Documentation

Pages

A Document holds one or more Pages. Each page sets its own size, orientation and margins, and when its content is taller than the page, jasy flows it onto as many pages as it needs, on its own.

Page({ size: "A4", orientation: "portrait", margin: 56 }, [Text("One page.")]);
PropTypeWhat it does
sizePageSize or a name like "A4", "letter"the page format (default A4)
orientation"portrait" | "landscape"rotates the format (default portrait)
marginInsetsthe content box inset (default 56pt all sides)
headeran elementdrawn at the top, repeated on every page
footeran elementdrawn at the bottom, repeated on every page

A Page also takes the Column options (gap, justify, align), since its children are stacked in a column.

Many pages

Hand Document a list of pages. Each can differ, mixing sizes and orientations freely.

Document([
  Page({ size: "A4" }, [Text("Cover")]),
  Page({ size: "A5", orientation: "landscape" }, [Text("A landscape insert")]),
]);

Headers, footers and pagination

A header and footer are laid out once and reprinted on every page the content spills onto, so a long table or a long stack of paragraphs keeps its letterhead and page furniture throughout. You write the content once; jasy paginates.

import { writeFileSync } from "node:fs";
import { Document, Page, Column, Row, Text, renderToBytes } from "@jasy/pdf";

const header = Row({ justify: "between" }, [
  Text("Acme Inc.", { bold: true, color: "#1450aa" }),
  Text("Report"),
]);
const footer = Row({ justify: "between" }, [
  Text("Confidential", { size: 9, color: "gray" }),
  Text("2026", { size: 9, color: "gray" }),
]);

async function build() {
  const body = Array.from({ length: 60 }, (_, i) =>
    Text(`Paragraph ${i + 1} - long body text that flows across pages.`, { size: 12 }),
  );

  const doc = Document([
    Page({ size: "A4", margin: 56, header, footer }, [Column({ gap: 6 }, body)]),
  ]);

  writeFileSync("report.pdf", await renderToBytes(doc));
}

build();

The 60 paragraphs are taller than one page, so the result is several pages, each carrying the same header and footer.

jasypdf

Declarative PDFs in pure TypeScript. ZUGFeRD & XRechnung compliant, with no headless browser and no Java.

Resources

© 2026 Florian Heuberger · MIT License

Built with Nuxt · self-hosted fonts · no trackers