@qrcommunication/gigapdf-lib — SDK API reference - v0.110.3
    Preparing search index...

    @qrcommunication/gigapdf-lib — SDK API reference - v0.110.3

    @qrcommunication/gigapdf-lib

    TypeScript SDK for gigapdf-lib — a zero-dependency Rust→WASM PDF engine. Read, edit, render, search, sign (self-signed · PKCS#12 · PAdES-B-T timestamped · PAdES-LTV), encrypt, fill & build forms, annotate, redact, and convert PDFs ↔ Office/HTML/RTF/Markdown/CSV — plus a native HTML/CSS→PDF renderer with a built-in JavaScript engine, and a unified editable model that lowers/raises every format. The engine .wasm is self-contained: no third-party runtime dependencies. (OCR is a separate host-side native crate, gigapdf-ocr-rten.)

    pnpm add @qrcommunication/gigapdf-lib
    # or: npm i @qrcommunication/gigapdf-lib
    import { GigaPdfEngine } from "@qrcommunication/gigapdf-lib";

    // Node: loads the bundled gigapdf.wasm from the package.
    const giga = await GigaPdfEngine.loadDefault();

    // Browser / explicit control: pass a URL, Response, or bytes.
    // const giga = await GigaPdfEngine.load("/gigapdf.wasm");

    const doc = giga.open(pdfBytes); // Uint8Array

    // Read
    const lines = doc.structuredText(1); // [{ text, x, y, w, h }]
    const hits = doc.search("invoice"); // [{ page, text, x, y, w, h }]
    const text = doc.toText(); // whole-document plain text (exact, no OCR)

    // Edit (operates on the real content stream — no cosmetic overlay)
    doc.replaceText(1, 0, "New value");
    doc.redact(1, 72, 700, 180, 14); // physically remove content in a region
    doc.addHighlight(1, 72, 690, 252, 704, 0xffff00);

    // Convert
    const docx = doc.toDocx(); // also: toPptx/toOdp/toOdt/toXlsx/toOds/toHtml/toText/toRtf/toPdfA
    const png = doc.renderPage(1, 2); // rasterize a page

    // Save
    const out = doc.save(); // or doc.saveCompressed()
    doc.close();
    const fromDocx = giga.officeToPdf(officeBytes); // docx/xlsx/pptx/odt/ods/odp auto-detected
    const fromHtml = giga.htmlToPdf("<h1>Hello</h1>");
    const fromRtf = giga.rtfToPdf(rtfString);
    // Coordinates are PDF user space (origin bottom-left): [x0, y0, x1, y1].
    doc.addTextField(1, "fullname", [50, 700, 300, 720], "", { maxLen: 60 });
    doc.addCheckbox(1, "subscribe", [50, 670, 64, 684], true, { export: "Yes" });
    doc.addRadioGroup(1, "plan", [
    { export: "Basic", rect: [50, 640, 64, 654] },
    { export: "Pro", rect: [80, 640, 94, 654] },
    ], { selected: "Pro" });
    doc.addComboBox(1, "country", [50, 610, 200, 626], ["FR", "US", "DE"], { selected: "FR" });
    doc.addListBox(1, "langs", [50, 540, 200, 600], ["en", "fr", "de"], { multi: true });

    // Optional per-field styling.
    doc.addTextField(1, "vat", [50, 510, 200, 528], "", {
    style: { fontSize: 11, color: 0x102030, border: 0x888888, background: 0xf5f5f5 },
    });

    const filled = doc.fields(); // read them straight back: kind + value + options
    // 1. Base-14 standard fonts — no embedding, no network.
    doc.addStandardText(1, 72, 720, 24, "Heading", "Helvetica-Bold", 0x111111);
    doc.addStandardText(1, 72, 690, 12, "body in Times", "Times-Roman");

    // 2. Any family / Google Font — the host fetches, the engine embeds. embedFont
    // accepts any outline file: glyf .ttf OR OpenType-CFF .otf (auto-detected).
    const url = giga.fontRequestUrl("Roboto", 400); // Google Fonts CSS2 URL
    const css = await (await fetch(url, { headers: { "User-Agent": "Mozilla/4.0" } })).text();
    const ttf = new Uint8Array(await (await fetch(giga.parseCssFontUrl(css))).arrayBuffer());
    const fontObj = doc.embedFont("Roboto", ttf);
    doc.addText(1, 72, 660, 18, "Selectable embedded text", fontObj, 0x111111);
    // Font-aware editing: replace the run's text — re-encoded through Roboto's cmap.
    doc.replaceText(1, doc.textRuns(1).length - 1, "Edited in the same font");

    // 3. Reuse a face the PDF already embeds: list → extract → re-embed → draw.
    const face = doc.embeddedFonts().find((f) => f.format === "truetype");
    if (face) {
    const prog = doc.extractFont(face.baseFont)!; // { format, bytes }
    const reused = doc.embedFont("Reused", prog.bytes);
    doc.addText(1, 72, 630, 14, "drawn in the document's own font", reused);
    }

    Task-oriented snippets using the high-level classes. Each assumes const giga = await GigaPdfEngine.loadDefault() (Node) or GigaPdfEngine.load(url) (browser), Uint8Array in/out, and a final close().

    const merged = giga.mergePdfs([first, second, third]); // one PDF, pages in order
    

    Or, for finer control, append page-by-page yourself:

    const doc = giga.open(first);                 // the base document
    for (const extra of [second, third]) doc.appendPages(extra); // append every page
    const merged = doc.saveCompressed();
    doc.close();
    const pdf = giga.imageToPdf(imageBytes); // PNG/JPEG/GIF/WebP/AVIF → one A4 page
    // (image centred, shrink-to-fit, never upscaled; empty array if not an image)
    const doc = giga.open(pdfBytes);
    const partA = doc.extractPages([1, 2, 3]); // a NEW, self-contained PDF…
    const partB = doc.extractPages([4, 5, 6]); // …links / fields / dests to dropped pages pruned
    doc.close();
    // `fileId` is the document /ID (any stable string). AES-256 auto-generates the
    // 32-byte key via Web Crypto; pass `opts.keySeed` to supply your own.
    const locked = doc.saveEncrypted("user-pw", "doc-001", {
    ownerPassword: "owner-pw",
    algorithm: "aes256", // "rc4" | "aes128" | "aes256" (default)
    // permissions: -44, // PDF permission bitmask (optional)
    });
    doc.close();

    const reopened = giga.openEncrypted(locked, "user-pw"); // null on a wrong password
    reopened?.close();
    // Inspect without opening:
    const info = giga.encryptionInfo(locked); // { encrypted, permissions, version, revision }
    // (a) Self-signed — an ephemeral digital ID. `random` ≥ 256 host-entropy bytes.
    // fields = "name\treason\tdate\tnotBefore\tnotAfter" (PDF date strings).
    const fields = "Jane Doe\tApproved\tD:20260618120000Z\t260618000000Z\t360618000000Z";
    const random = crypto.getRandomValues(new Uint8Array(256));
    const signed = doc.sign(fields, random);

    // (b) PKCS#12 — your CA / eIDAS certificate + RSA key (.p12/.pfx), imported
    // natively. Throws on a wrong password / malformed file.
    const signed2 = doc.signP12(p12Bytes, "p12-password", {
    name: "Jane Doe",
    reason: "I approve this document",
    date: "D:20260618120000Z",
    location: "Paris",
    });

    // (c) PAdES-B-T — add an RFC 3161 trusted timestamp (async: one TSA round trip).
    // Identity is the p12 above, or a self-signed id (random + notBefore/notAfter).
    const timestamped = await doc.signTimestamped({
    p12: p12Bytes, password: "p12-password", name: "Jane Doe",
    tsaUrl: "https://freetsa.org/tsr",
    // tsaFetch: custom fetch (auth / proxy / SSRF allow-list — recommended in prod)
    });

    // (d) PAdES-LTV — B-T plus a /DSS (chain + OCSP/CRL the host fetches), so the
    // signature validates long-term. archiveTimestamp adds a B-LTA doc timestamp.
    const ltv = await doc.signLtv({
    p12: p12Bytes, password: "p12-password",
    tsaUrl: "https://freetsa.org/tsr", archiveTimestamp: true,
    // revocationFetch / crlFetch: override the OCSP/CRL HTTP (SSRF allow-list)
    });
    doc.close();

    Timestamping and LTV need network the WASM core can't perform, so the engine emits the request bytes and the SDK does the HTTP. The OCSP/CRL/TSA URLs are host-supplied (LTV URLs come from the certificates) — in production pass tsaFetch / revocationFetch / crlFetch to apply your own SSRF allow-list.

    doc.addHighlight(1, 72, 690, 252, 704, 0xffff00);
    doc.addTextNote(1, 300, 700, 0xff0000, { contents: "Check this clause", author: "Reviewer" });
    doc.addSquare(1, 60, 680, 264, 712, 0xff0000, null); // stroke red, no fill
    const all = doc.annotations(1); // read back, with full metadata
    doc.flattenAnnotations(1); // bake into page content (non-interactive)
    const out = doc.save();
    doc.close();
    import type { HtmlFontRequest, HtmlFont } from "@qrcommunication/gigapdf-lib";

    // Phase 1: ask the engine which fonts the HTML needs; the HOST fetches them
    // (the wasm has no network). Phase 2: render with those fonts embedded.
    async function fetchFonts(reqs: HtmlFontRequest[]): Promise<HtmlFont[]> {
    return Promise.all(reqs.map(async (r) => {
    const css = await (await fetch(r.url, {
    headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0)" }, // → TTF, not WOFF2
    })).text();
    const ttf = new Uint8Array(await (await fetch(giga.parseCssFontUrl(css))).arrayBuffer());
    return { family: r.family, weight: r.weight, italic: r.italic, ttf };
    }));
    }

    const html = `<body style="font-family: Roboto"><h1>Invoice</h1><p>Net 30.</p></body>`;
    const fonts = await fetchFonts(giga.htmlNeededFonts(html));
    const pdf = giga.htmlRender(html, fonts, 595, 842, 36); // A4 in points, 36pt margin
    // Named sizes, per-side margins and a header/footer with {{page}}/{{pages}} tokens:
    // giga.htmlRenderWith(html, fonts, { pageSize: "A4", header, footer });

    OCR itself runs host-side — it lives in the separate native crate gigapdf-ocr-rten (PaddleOCR PP-OCR on a pure-Rust runtime), whose model weights are far heavier than the lean WASM core. This SDK provides the text-layer side: addTextLayer stamps recognized words back onto the page so the scan becomes selectable & searchable. (For PDFs that already carry text, use toText/structuredText/search — exact, no OCR needed.)

    const doc = giga.open(scannedPdf);
    const scale = 2; // rasterise at 2× = 144 dpi for OCR
    for (let page = 1; page <= doc.pageCount(); page++) {
    const { height } = doc.pageInfo(page);
    const png = doc.renderPage(page, scale); // raster the page for your OCR service…
    const words = await ocrService(png); // … your host OCR → [{ x, y, w, h, text }]
    // boxes in raster pixels (top-left)
    // Map each word box back to PDF user space (bottom-left, Y up) and stamp an
    // invisible (render-mode 3) text layer — selectable & searchable, pixel-aligned.
    doc.addTextLayer(page, words.map((w) => ({
    x: w.x / scale,
    y: height - (w.y + w.h) / scale,
    size: w.h / scale,
    text: w.text,
    })));
    }
    const searchable = doc.save();
    doc.close();
    doc.setMetadata("Title", "Quarterly report");
    doc.setMetadata("Author", "Finance");
    doc.setOutline([
    { title: "Summary", level: 0, page: 1 },
    { title: "Details", level: 0, page: 2 },
    { title: "Appendix", level: 1, page: 5 },
    ]);
    const out = doc.save();
    doc.close();

    loadDefault() reads gigapdf.wasm from the package directory. In standalone output, add it to the route's outputFileTracingIncludes so it is copied into the bundle:

    // next.config.ts
    outputFileTracingIncludes: {
    "/api/pdf/*": ["./node_modules/@qrcommunication/gigapdf-lib/gigapdf.wasm"],
    }

    Or call GigaPdfEngine.load(bytes) with bytes you read yourself.

    Full, per-method reference: docs/SDK.md documents every method (parameters, return, notes) grouped by domain. Exact signatures and defaults also ship in the bundled .d.ts.

    • GigaPdfEngineload/loadDefault, open/openEncrypted, txtToPdf/htmlToPdf/rtfToPdf/officeToPdf/imageToPdf (PNG/JPEG/GIF/WebP/AVIF → A4 page), mergePdfs (concatenate many PDFs), fontCatalog/fontRequestUrl/parseCssFontUrl.
    • GigaPdfDoc — text intelligence (textRuns, structuredText, pageBlocks, search, toText, elements, elementAt, documentLanguage), editing (replaceText, setTextRunStyle (per-character restyle), removeElement, moveElement, transformElement (full affine — move + resize
      • rotate in place), reorderElement (native z-order — bring to front / send to back), setPathStyle (in-place vector restyle: fill/stroke/width/dash + real opacity), setElementOpacity (constant opacity on any element — text/image/shape), duplicateElement, redact, redactPii (irreversible — erases image pixels)), vector drawing (addRectangle, drawLine, addEllipse, addPolygon, addPath (SVG path), addImage (PNG/JPEG, alpha + opacity), addImageWatermark (stamp an image across pages), addSvg (native vector)), pages (rotatePage, deletePage, movePage, appendPages, extractPages, resizePage, addPage, copyPage, pageInfo), renderPage (and renderPageNoText — a text-free background for editors that overlay real editable text; vectors/gradients/images/annotations still rendered — plus renderPageExcluding — a background omitting specific elements for live-overlay editing), fonts (base-14 addStandardText, embed any TrueType/OpenType via embedFont/addText, font-aware editing replaceText, the document's own faces embeddedFonts/extractFont, neededFonts), conversions (toText/Html/Docx/Pptx/Odp/Odt/Xlsx/Ods/Rtf/PdfA, toModel for the unified editable model, plus engine-level gridsToXlsx/gridsToOds to emit Office output from a host-built table grid), security (saveEncrypted (AES-256 R6) + permissionsToP/getPermissions; digital signatures: self-signed sign, PKCS#12 signP12, PAdES-B-T timestamped signTimestamped (RFC 3161 TSA), PAdES-LTV signLtv (DSS + OCSP/CRL, B-LT/B-LTA)), metadata (getMetadata, setMetadata), embedded files (attachments — extract every /EmbeddedFiles entry with its decoded bytes), annotations (addSquare, addHighlight, addLineAnnotation, addFreeText, addUnderline, addStrikeOut, addInk, addStamp, annotations, removeAnnotation, flattenAnnotations), links (links, addUriLink, addGotoLink, named destinations addNamedDest/namedDests/addGotoLinkNamed), outline (outline, setOutline), forms — read/fill (fields, setTextField, setCheckbox, setRadio, setChoice) and create (addTextField, addCheckbox, addRadioGroup, addComboBox, addListBox, each with an optional FieldStyle) plus flattenForm / flattenFormXObjects, margins & running header/footer (pageMargins/setPageMargins, setHeader/setFooter/headerFooter), and optional-content layers (layers, addLayer, setLayerVisibility, setLayerLocked, removeLayer).
    • HTML rendering engine (on GigaPdfEngine) — htmlNeededFonts(html) returns the Google fonts to download (phase 1); htmlRender(html, fonts, pageW?, pageH?, margin?) renders HTML + CSS to PDF with those fonts embedded (phase 2). No headless browser. Block / inline / table / flex (flex-direction, justify-content, flex-grow) / grid (grid-template-columns) layout, selector cascade, pagination, and forced page breaks via CSS page-break-before|after: always / break-*: page or a <pagebreak> tag. See the exhaustive list of supported HTML elements, CSS properties, units, colours and selectors in docs/HTML-CSS.md.
    • JavaScript — a document's inline <script>s run before layout through a built-in zero-dependency JS engine (no Chromium/Playwright), so script-driven content is rendered. It covers classes + super, closures, destructuring, RegExp, Map/Set, Symbol, eval/Function, and DOM bindings (document.getElementById, querySelector(All) with >/+/~/[attr], textContent, innerHTML, createElement/appendChild, classList, style). function*/async bodies compile to a suspendable bytecode VM, so generators are truly lazy (infinite generators, bidirectional .next(v), yield*) and await yields with spec microtask ordering. This happens automatically inside htmlRender/htmlNeededFonts — no extra call needed.

    Every method is fully typed. Always close() a document when done to free the WASM handle.

    PolyForm Noncommercial License 1.0.0 © Rony Licha / QR Communication. Free for noncommercial use; a commercial license is required otherwise. See LICENSE.