PDFPipe

Comparison

HTML templates instead of pdf-lib coordinate drawing

pdf-lib is a powerful JavaScript library for creating and modifying PDF files at the binary level. You position text with x/y coordinates, embed fonts explicitly, and handle page geometry manually. This is the right tool when you need to programmatically manipulate existing PDFs. When the goal is generating a new document from structured data (an invoice, a report, a certificate) PDFPipe lets you write HTML and CSS, including the Tailwind or Bootstrap your team already uses for every other layout task, and renders it to a PDF for you.

pdf-lib versus PDFPipe

PDFPipepdf-lib
Layout languageHTML + CSSx/y coordinates in code
Font handlingWeb fonts, system fonts automaticManual embed from bytes
Tables and listsNative HTML elementsManual rows, column math
Page breaksCSS print rulesManual newPage() calls
Template iteration speedEdit HTML/CSS and re-renderRewrite coordinate code
PDF modificationNot the primary use caseExcellent: merge, split, annotate
Runs on serverYes (API call)Yes (library)
AI agentsFirst-class MCP serverRequires custom tooling

The coordinate approach scales poorly

A pdf-lib invoice implementation typically starts with placing a header atdrawText("Invoice", { x: 50, y: 750 }). When the line-item table grows by one row, every element below it needs its y-coordinate manually decremented. When a customer name is longer than expected, it clips or overlaps. When the design changes, the entire coordinate grid needs recalculating.

HTML and CSS handle all of this with flow layout: elements push each other down, text wraps, tables grow to fit content. Designers can iterate on the template without touching JavaScript. PDFPipe renders that template with a full browser engine, so the output matches what you see in a browser at A4 print size.

When pdf-lib is still the right choice

pdf-lib is the right tool when you need to programmatically manipulate existing PDFs: merging documents, filling form fields in an existing template, adding digital signatures, splitting pages, or annotating PDFs. For those tasks it has no close peer in JavaScript. PDFPipe is the better choice when you are generating new documents from data.

Using PDFPipe from Node.js

Node.js (TypeScript)
const html = `
  <style>
    body { font-family: system-ui; padding: 40px; }
    table { width: 100%; border-collapse: collapse; }
    td { padding: 8px; border-bottom: 1px solid #eee; }
  </style>
  <h1>Invoice #${orderId}</h1>
  <table>
    ${lineItems.map(i => `<tr><td>${i.name}</td><td>${i.amount}</td></tr>`).join("")}
  </table>
`;

const res = await fetch("https://api.pdfpipe.xyz/v1/pdf", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.PDFPIPE_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ html, options: { format: "A4" } }),
});

const buffer = Buffer.from(await res.arrayBuffer());