Generating PDFs on the server is harder than it looks.
PDF generation has a complexity wall: HTML-to-PDF conversion, custom fonts, page breaks, and server rendering all have gotchas. The approaches that work in development fail in production serverless environments. Getting PDF generation production-ready requires choosing the right library for the use case.
PDF generation that works in development but fails in production, generates incorrectly formatted output, or is too slow for the use case
PDF generation approaches and their trade-offs:
Puppeteer (headless Chrome): Spins up a headless Chrome browser, renders the HTML, and prints to PDF. Produces pixel-perfect PDFs that match your HTML exactly. Problems: large binary (~200MB), high memory usage, fails in many serverless environments (Lambda has a 50MB deployment package limit). Works on Fly.io, Railway, and EC2 where binary size and memory aren't constrained.
React-PDF (pdf-lib based): Generates PDFs programmatically via a React-like component API. No browser required — runs anywhere including serverless. Trade-off: you define the PDF layout in React-PDF's component system, not in standard HTML/CSS.
@react-pdf/renderer: Similar to React-PDF — React components that render to PDF. Works in Node.js. PDF layout defined in their component system.
PDFKit: Low-level Node.js PDF library. Maximum control over the output; more verbose to use. Works everywhere.
Browserless.io / Playwright Cloud: Remote headless browser services. Send the HTML, receive the PDF. Removes the binary size and serverless constraints. Additional cost per render.
The right choice by use case:
Complex invoices that need to match your existing HTML/CSS design → Puppeteer on a traditional server or Browserless.io
Simple structured reports (tables, lists) → React-PDF or @react-pdf/renderer (works serverless)
Complex documents with precise layout control → PDFKit
Production-ready PDF generation that works in serverless environments, renders correctly, and delivers PDFs at acceptable speed
React-PDF
for serverless-compatible PDF generation
Puppeteer
on Fly.io/Railway for complex HTML-to-PDF conversion
PDF templates
for invoices, reports, and contracts
Download endpoint
serving generated PDFs as file downloads
Background generation
for large PDFs that take > 2 seconds
One honest number to start.
Fixed-scope, fixed-price. The number below is the starting point — final scope is built from your brief.
Production-ready PDF generation that works in serverless environments, renders correctly, and delivers PDFs at acceptable speed
Three steps, every time.
The same repeatable engagement on every project. No surprises, no mystery, no billable ambiguity.
Brief & discovery.
We send you questions, then get on a call. Output: a written scope with every step, feature, and integration listed.
Build & ship.
Fixed schedule, weekly reviews. No scope creep unless you change the scope — and if you do, we reprice it transparently.
Warranty & retainer.
30-day warranty on every launch. Most clients stay on a monthly retainer for ongoing features and maintenance.
Why Fixed-Price Matters Here
PDF generation scope is defined by the document types and the deployment environment.
Questions, answered.
Puppeteer's Chromium binary exceeds Vercel's 50MB serverless function limit. Solution: React-PDF for Vercel compatibility, or Puppeteer on a separate server.
With Puppeteer: render any URL to PDF. With React-PDF: redesign the layout in their component system. Puppeteer is easier for converting existing HTML; React-PDF requires rebuilding the layout.
Tell Ryel about your project.
Describe what you’re building and what outcome you need. You’ll have a written, fixed-price scope within the week.