Picking a PDF generation API comes down to three variables: how much infrastructure you want to manage, which rendering engine you need, and what your budget is. This guide compares five options that developers actually use in 2026, with code examples and a feature table for each.
The short answer
If you want a hosted API with zero infrastructure and a visual template editor, use PDF4.dev or PDFMonkey. If you want self-hosted and open-source, use Gotenberg. If you're still running wkhtmltopdf, migrate — it is no longer maintained and its rendering engine is outdated.
The rest of this article explains the trade-offs in detail.
PDF generation API comparison table
| PDF4.dev | PDFMonkey | DocRaptor | Gotenberg | wkhtmltopdf | |
|---|---|---|---|---|---|
| Type | SaaS API | SaaS API | SaaS API | Self-hosted Docker | CLI / library |
| Rendering engine | Chromium (Playwright) | Chromium | Prince XML | Chromium + LibreOffice | QtWebKit |
| CSS Grid / Flexbox | ✅ Full | ✅ Full | ✅ Full (Prince) | ✅ Full | ❌ Partial |
| Templating | Handlebars | Liquid | HTML interpolation | No (raw HTML) | No |
| Visual template editor | ✅ Yes | ✅ Yes | ❌ No | ❌ No | ❌ No |
| Free tier | ✅ Yes | Trial only | Trial only | Free (self-host) | Free (OSS) |
| Serverless-friendly | ✅ HTTP only | ✅ HTTP only | ✅ HTTP only | ⚠️ Docker required | ❌ Binary required |
| Actively maintained | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes | ❌ Archived |
| Open source | ❌ No | ❌ No | ❌ No | ✅ Yes (Apache 2.0) | ✅ Yes (LGPL) |
| MCP / AI agent support | ✅ Yes | ❌ No | ❌ No | ❌ No | ❌ No |
Rendering fidelity depends on document complexity. CSS Grid and Flexbox results above reflect standard web compatibility. Prince XML (DocRaptor) uses CSS Paged Media extensions that differ from Chromium-based rendering.
PDF4.dev
PDF4.dev is a REST API for HTML-to-PDF generation powered by Playwright and headless Chromium. You create templates with Handlebars syntax, preview them live in a browser-based editor, then call the API with JSON data to render PDFs at runtime.
How it works:
- Create a template in the dashboard (HTML + CSS + Handlebars variables)
- Call
POST /v1/renderwith{ templateId, data }and your API key - Receive the PDF as a binary response or base64
const response = await fetch('https://pdf4.dev/api/v1/render', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PDF4_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
templateId: 'your-template-id',
data: {
customerName: 'Acme Corp',
invoiceNumber: 'INV-2026-001',
total: '$1,200.00',
},
}),
});
const pdf = await response.arrayBuffer();
// Save or stream the PDFStrengths:
- Visual template editor with live preview
- Handlebars templating with helpers, loops, and conditionals
- MCP server for AI agent integration (Claude, Cursor, ChatGPT)
- Renders in under 300ms with a warm browser pool
- Free tier, no credit card required
- Serverless-compatible (pure HTTP)
Limitations:
- Closed-source SaaS
- No Office document conversion (only HTML)
Best for: teams that want a fast setup with a visual editor, startups building invoice or document generation features, and developers using AI coding assistants.
PDFMonkey
PDFMonkey is a SaaS PDF generation API that also uses Chromium under the hood. It uses Liquid templating (similar to Shopify's template language) and has a visual editor for designing templates.
How it works:
You create templates in PDFMonkey's dashboard using Liquid syntax, then call the API with JSON data to generate PDFs asynchronously. PDFMonkey generates the PDF in the background and returns a document ID; you poll for completion or receive a webhook.
// PDFMonkey: async generation pattern
const createResponse = await fetch('https://api.pdfmonkey.io/api/v1/documents', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PDFMONKEY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
document: {
document_template_id: 'your-template-id',
payload: JSON.stringify({ name: 'Acme Corp', total: 1200 }),
},
}),
});
const { document } = await createResponse.json();
// Poll or receive webhook with document.download_urlStrengths:
- Large library of pre-built templates
- Liquid templating is familiar for developers from Shopify backgrounds
- Good webhook support for async generation
Limitations:
- Asynchronous-first API (adds latency for synchronous use cases)
- Pricing based on monthly document credits
- No AI/MCP integration
Best for: teams with design-heavy documents, Shopify developers, or workflows where async generation is acceptable.
DocRaptor
DocRaptor is a SaaS API that uses Prince XML, a commercial CSS Paged Media rendering engine. Prince XML has strong support for CSS Paged Media spec (page counters, running headers, widow/orphan control), which makes it popular for publishing workflows, academic papers, and legal documents.
const response = await fetch('https://docraptor.com/docs', {
method: 'POST',
headers: {
'Authorization': `Basic ${Buffer.from('YOUR_API_KEY_HERE').toString('base64')}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'pdf',
document_content: '<html><body><h1>Hello PDF</h1></body></html>',
prince_options: { media: 'print' },
}),
});Strengths:
- Prince XML handles complex print layouts well (running headers, footnotes, multi-column)
- Good support for CSS Paged Media spec
- Long-established API with stability track record
Limitations:
- Prince XML is not a standard web browser: CSS compatibility differs from Chrome
- Higher price point ($15/month minimum for 125 documents)
- No visual template editor
- No Handlebars or Liquid: you interpolate HTML strings manually
Best for: publishing, legal, and compliance teams that need CSS Paged Media features. Not ideal for web developers who expect Chromium-compatible CSS.
Gotenberg
Gotenberg is an open-source Docker microservice that wraps Chromium (for HTML/URL) and LibreOffice (for Office documents). You POST multipart form requests and receive PDFs. It has no hosted SaaS option — you run it yourself.
const form = new FormData();
form.append('files', new Blob(['<html><body><h1>Hello</h1></body></html>'], {
type: 'text/html',
}), 'index.html');
const response = await fetch('http://localhost:3000/forms/chromium/convert/html', {
method: 'POST',
body: form,
});
const pdf = await response.arrayBuffer();Strengths:
- Free and open-source (Apache 2.0)
- Supports HTML, URL, Office, and Markdown conversion
- No vendor lock-in
- Good documentation
Limitations:
- Requires Docker in production (adds ~500MB to your image)
- No templating: you build HTML strings yourself
- No visual editor
- You manage concurrency, scaling, and updates
Best for: teams with Docker infrastructure already in place, cost-sensitive projects, or use cases requiring Office document conversion alongside HTML.
wkhtmltopdf
wkhtmltopdf is a command-line tool that converts HTML to PDF using QtWebKit. It was widely used between 2010 and 2020 but is now effectively abandoned — the last release was 0.12.6 in 2020, and the project is no longer actively maintained.
Why developers still use it:
- Many legacy Rails and PHP applications integrated wkhtmltopdf years ago
- wicked_pdf (Rails gem) and laravel-snappy (PHP) built abstraction layers on top of it
- Migration has a cost
Why you should migrate:
- QtWebKit is the engine from Safari circa 2013. It does not support CSS Grid, CSS custom properties, modern flexbox, or web fonts reliably
- No active security patches
- Unicode and complex layouts frequently break
- Container images require system-level dependencies that create reproducibility problems
If you're on wkhtmltopdf, the migration path depends on your stack. For a detailed comparison, see the Playwright vs Puppeteer guide for self-hosted options, or the benchmark comparing HTML-to-PDF approaches for a full performance analysis.
Which PDF API should you choose?
| Use case | Best choice | Why |
|---|---|---|
| Invoice generation for SaaS | PDF4.dev | Visual editor, Handlebars, fast API, free tier |
| Design-heavy documents | PDFMonkey | Template library, Liquid templating |
| CSS Paged Media / publishing | DocRaptor | Prince XML for complex print layouts |
| Self-hosted, open-source | Gotenberg | Free, Docker, HTML + Office support |
| Serverless (Lambda, Vercel) | PDF4.dev or PDFMonkey | No binary dependency |
| AI agent workflows | PDF4.dev | MCP server support |
| Migrating from wkhtmltopdf | PDF4.dev or Gotenberg | Modern Chromium engine |
| Low budget, control over infra | Gotenberg | Free to run on your own server |
The infrastructure trade-off
The real decision is not "which engine renders better" — Chromium-based APIs all render the same HTML the same way. The decision is: who manages the browser?
Self-hosted Playwright, Puppeteer, or Gotenberg give you full control. You also absorb the complexity: Chromium binary updates, concurrency management, crash recovery, serverless incompatibility, and ~700MB Docker images.
Managed APIs (PDF4.dev, PDFMonkey, DocRaptor) remove that complexity. You pay per render. You get an SLA. When a browser security update ships, the API provider handles it.
Most teams reach for a managed API once they hit production issues with self-hosted Chromium — Docker image bloat, Lambda size limits, browser crashes under load. Starting with a managed API avoids those issues entirely.
Code comparison: DIY vs API
Here is the same invoice generation task implemented with self-hosted Playwright versus PDF4.dev's API:
import { chromium } from 'playwright';
import Handlebars from 'handlebars';
import fs from 'fs';
// You manage: browser lifecycle, concurrency, crashes
const browser = await chromium.launch();
const context = await browser.newContext();
const page = await context.newPage();
const template = Handlebars.compile(fs.readFileSync('invoice.html', 'utf8'));
const html = template({
customerName: 'Acme Corp',
invoiceNumber: 'INV-2026-001',
total: '$1,200.00',
items: [
{ description: 'Design services', amount: '$800.00' },
{ description: 'Development', amount: '$400.00' },
],
});
await page.setContent(html, { waitUntil: 'networkidle' });
const pdf = await page.pdf({
format: 'A4',
printBackground: true,
margin: { top: '20mm', bottom: '20mm', left: '15mm', right: '15mm' },
});
await browser.close();
// ~40 lines, plus Dockerfile, plus concurrency poolThe rendering output is the same Chromium engine. The difference is 40 lines versus 15 lines, and no Docker image weight, no crash handling, no concurrency pool to maintain.
Pricing comparison
| PDF4.dev | PDFMonkey | DocRaptor | Gotenberg | |
|---|---|---|---|---|
| Free tier | Yes | Trial | Trial | Free (self-host) |
| Paid entry | Pay-per-render | Monthly credits | $15/month (125 docs) | Server cost only |
| Volume pricing | Yes | Yes | Yes | Server scaling |
| Per-render cost | Low | Medium | High per doc | ~$0 (your server) |
Pricing as of Q1 2026. Check each provider's current pricing page before committing.
Summary
The PDF generation API landscape in 2026 has two clear segments: managed SaaS APIs (PDF4.dev, PDFMonkey, DocRaptor) and self-hosted tools (Gotenberg, wkhtmltopdf).
For most web developers building document generation into a product, a managed API is the practical choice. The operational complexity of running a production-grade browser service — concurrency, crashes, Docker image size, serverless incompatibility — is rarely a good use of engineering time.
For open-source enthusiasts or cost-sensitive infrastructure teams, Gotenberg is the best self-hosted option. It uses modern Chromium, supports Office documents, and is actively maintained.
wkhtmltopdf should not be used for new projects. If you're running it in production, plan a migration to avoid CSS compatibility and security problems.
Ready to try PDF4.dev? Generate your first PDF free — no credit card required. For a step-by-step integration guide, see generating PDFs from HTML in Node.js or the complete HTML-to-PDF benchmark for 2026.
Free tools mentioned:
Start generating PDFs
Build PDF templates with a visual editor. Render them via API from any language in ~300ms.