pdg XML → PDF

Guide

Node.js

The pdg npm package — render an XML document to a PDF from Node, async or sync, or throw with the engine's diagnostics.

The pdg npm package renders a pdg XML document to PDF bytes in Node. The engine is packed into the package (one package bundles a prebuilt binary for every platform), so there's no toolchain to install and nothing to compile.

import { render } from "pdg";
import { writeFile } from "node:fs/promises";

const pdf = await render(xml, { base: "invoices" });
await writeFile("invoice.pdf", pdf);

The XML you pass is the document format documented throughout these guides — see Document structure and the element reference.

ESM, Node ≥ 18, with bundled TypeScript types.

Installation

npm install pdg

Rendering

The document is a string (or Uint8Array); base is the asset directory (see Assets). Each async function has a synchronous *Sync counterpart.

import {
  render,
  renderWithMeta,
  renderFile,
  renderSync,
} from "pdg";

// PDF bytes (a Buffer). Rejects on failure.
const pdf = await render(xml, { base: "." });

// Bytes plus metadata.
const result = await renderWithMeta(xml);
result.pages;     // 3
result.bytes;     // 48213 (result.pdf.length)
result.objects;   // 412
result.timings;   // { parseMs, layoutMs, pdfMs }
result.warnings;  // [Diagnostic, ...]
result.pdf;       // Buffer

// Straight to a file (resolves to the Result).
await renderFile(xml, "report.pdf", { base: "assets" });

// Synchronous variants block the event loop — use the async forms in servers.
const pdfSync = renderSync(xml);

Assets

Relative paths inside the document — <font-face src>, <image src>, <pdf src> — resolve against base (default: the current working directory). http(s) URLs and <google-font> faces are fetched by the engine regardless.

await render(xml, { base: new URL("./pdf-assets", import.meta.url).pathname });

Errors and diagnostics

Every error extends PdgError.

  • RenderError — the engine withheld a PDF (a strict-mode block or a fatal parse/layout error); carries .diagnostics and the raw .meta.
  • BinaryError — the engine couldn't run (an installation/environment problem).
import { RenderError } from "pdg";

try {
  await render(xml);
} catch (err) {
  if (err instanceof RenderError) {
    for (const d of err.diagnostics) {
      d.severity;  // "warning" | "error"
      d.code;      // "unknown-tag", "content-dropped", …
      d.message;
      d.line;
      d.col;
      d.trace;     // enclosing tags, innermost first
    }
  }
}

Warnings don't throw — a recoverable render resolves to a Result; read result.warnings.

Browser

This package spawns a subprocess and is Node-only. To render in the browser, use the Browser guide and the pdg-browser package, which runs the engine as WebAssembly.

How it works

The package drives the packed engine over stdio (XML on stdin, PDF on stdout, one JSON meta object on stderr) behind a single module, so the same engine that powers the CLI and this playground produces your PDFs. Set the PDG_BINARY environment variable to override the bundled binary.