HTML to PDF API Comparison 2026: With Code Examples
HTML to PDF conversion is a common requirement in web applications — from invoices and reports to certificates and contracts. Rendering browser content as pixel-perfect PDFs requires the right tool, and choosing poorly can mean months of maintenance headaches.
This guide compares the major options available in 2026, with real code examples, so you can make an informed decision for your project.
Major HTML to PDF Solutions
1. wkhtmltopdf (OSS)
A command-line tool based on the QtWebKit rendering engine. It was the go-to solution for years but was archived in 2023, with no further maintenance.
Pros:
- Free and open source
- Lightweight and fast (lower resource usage than Chromium-based tools)
- Simple CLI interface
Cons:
- Maintenance has stalled (archived)
- Incomplete CSS Grid/Flexbox support
- Cannot keep up with modern web standards
Code Example (CLI)
# Basic conversion
wkhtmltopdf https://example.com output.pdf
# With options (margins, page size)
wkhtmltopdf \
--encoding utf-8 \
--page-size A4 \
--margin-top 20mm \
--margin-bottom 20mm \
invoice.html invoice.pdf
wkhtmltopdf is not recommended for new projects. If you're migrating from it, see our wkhtmltopdf vs Chromium engine guide for alternatives.
2. Puppeteer / Playwright (OSS)
Node.js libraries that control headless Chrome. PDF generation is available as one of many browser automation features, with full support for modern web standards.
Pros:
- Full support for modern CSS/JS (CSS Grid, Flexbox, Web Fonts)
- Can also capture screenshots
- Large community and ecosystem
Cons:
- Chrome installation and version management required
- High memory consumption (200–500MB per process)
- Not purpose-built for PDF generation
- Concurrency handling must be implemented manually
Code Example (Node.js / Puppeteer)
const puppeteer = require('puppeteer');
async function generatePdf() {
const browser = await puppeteer.launch();
const page = await browser.newPage();
// Set HTML content directly
await page.setContent(`
<html>
<style>
body { font-family: Arial, sans-serif; }
.invoice-header { display: flex; justify-content: space-between; }
</style>
<body>
<div class="invoice-header">
<h1>Invoice</h1>
<p>March 2026</p>
</div>
<table>
<tr><td>Service Fee</td><td>$100.00</td></tr>
</table>
</body>
</html>
`);
await page.pdf({
path: 'invoice.pdf',
format: 'A4',
margin: { top: '20mm', bottom: '20mm', left: '15mm', right: '15mm' },
printBackground: true,
});
await browser.close();
}
generatePdf();
For a deeper look at migrating from Puppeteer, see our Puppeteer to API migration guide.
3. Gotenberg (OSS)
A Docker-based PDF generation API that uses Chromium and LibreOffice internally. It exposes a RESTful API for PDF conversion.
Pros:
- One-command Docker setup
- Language-agnostic REST API
- Full Chromium rendering capabilities
- Also supports Word/Excel to PDF conversion
Cons:
- Docker required (difficult in serverless environments)
- Self-managed scaling
- Limited error handling
- CJK font setup requires additional configuration
Code Example (cURL)
# Convert an HTML file to PDF
curl \
--request POST http://localhost:3000/forms/chromium/convert/html \
--form files=@index.html \
--form marginTop=20 \
--form marginBottom=20 \
-o output.pdf
# Convert a URL to PDF
curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--form url=https://example.com \
--form paperWidth=8.27 \
--form paperHeight=11.7 \
-o output.pdf
4. FUNBREW PDF (SaaS)
A managed REST API for generating PDFs from HTML, URLs, and templates. No infrastructure to manage — just an API key to get started.
Pros:
- Zero infrastructure management, start with just an API key
- Dual engine (Fast/Quality) for different use cases
- Built-in template engine, webhooks, and email delivery
- Full CJK font support (Noto Sans JP and others pre-installed)
- Auto-scaling for concurrent requests
Cons:
- Monthly generation limits (plan-dependent)
- External service dependency
Code Example (cURL)
curl -X POST https://api.pdf.funbrew.cloud/v1/pdf/from-html \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"html": "<h1>Invoice</h1><p>Total: $100.00</p>",
"engine": "quality",
"format": "A4",
"margin": {
"top": "20mm",
"bottom": "20mm"
}
}' \
-o invoice.pdf
Code Example (Node.js)
const response = await fetch('https://api.pdf.funbrew.cloud/v1/pdf/from-html', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
html: '<h1>Invoice</h1><p>Total: $100.00</p>',
engine: 'quality',
format: 'A4',
}),
});
const pdf = await response.arrayBuffer();
fs.writeFileSync('invoice.pdf', Buffer.from(pdf));
Code Example (Python)
import requests
response = requests.post(
'https://api.pdf.funbrew.cloud/v1/pdf/from-html',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
json={
'html': '<h1>Invoice</h1><p>Total: $100.00</p>',
'engine': 'quality',
'format': 'A4',
},
)
with open('invoice.pdf', 'wb') as f:
f.write(response.content)
Code Example (PHP)
<?php
$apiKey = getenv('FUNBREW_PDF_API_KEY');
$ch = curl_init('https://api.pdf.funbrew.cloud/v1/pdf/from-html');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'html' => '<h1>Invoice</h1><p>Total: $100.00</p>',
'engine' => 'quality',
'format' => 'A4',
'margin' => ['top' => '20mm', 'bottom' => '20mm'],
]),
CURLOPT_TIMEOUT => 30,
]);
$pdf = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200) {
file_put_contents('invoice.pdf', $pdf);
echo "PDF generated.\n";
}
Code Example (Gotenberg + Node.js)
const FormData = require('form-data');
const fs = require('fs');
const axios = require('axios');
async function generateWithGotenberg() {
const form = new FormData();
form.append('files', fs.createReadStream('invoice.html'), 'index.html');
form.append('marginTop', '20');
form.append('marginBottom', '20');
const response = await axios.post(
'http://localhost:3000/forms/chromium/convert/html',
form,
{ headers: form.getHeaders(), responseType: 'arraybuffer' }
);
fs.writeFileSync('output.pdf', response.data);
}
generateWithGotenberg();
Explore more in the documentation or try it live in the Playground. See the invoice automation guide for a real-world example.
Comparison Table
| Feature | wkhtmltopdf | Puppeteer | Gotenberg | FUNBREW PDF |
|---|---|---|---|---|
| CSS Grid/Flexbox | Partial | Full | Full | Full |
| CJK Fonts | Limited, manual | Manual install | Manual config | Pre-installed |
| REST API | No | No | Yes | Yes |
| Templates | No | No | No | Yes |
| Webhooks | No | No | No | Yes |
| Email Delivery | No | No | No | Yes |
| Infrastructure | Self-hosted | Self-hosted | Docker | Managed |
| Scaling | Manual | Manual | Manual | Automatic |
| Free Tier | OSS | OSS | OSS | 30/month |
| Maintenance | Archived | Active | Active | Active |
Recommendations by Use Case
Side Projects & Prototypes
For low-volume PDF generation, Puppeteer is a quick way to get started. However, consider FUNBREW PDF's free tier (30/month) to avoid infrastructure setup entirely.
Startups & Mid-size Teams
If development speed matters, a managed API like FUNBREW PDF is ideal. Skip Chromium version management and scaling headaches — focus on your core product instead.
Enterprise & High Volume
For tens of thousands of PDFs per month, either self-host Gotenberg with proper scaling, or use FUNBREW PDF's enterprise plan. For strict security requirements, see our PDF API security guide.
Migration Tips
If you're currently using wkhtmltopdf, our wkhtmltopdf vs Chromium engine guide covers your migration options. For those moving from Puppeteer or Playwright, a managed API eliminates the operational overhead of browser management and scaling.
Conclusion
The landscape in 2026 is clear:
- wkhtmltopdf — archived, not recommended for new projects
- Puppeteer/Playwright — flexible but operationally heavy
- Gotenberg — strong with Docker, but scaling is on you
- FUNBREW PDF — zero infrastructure, production-ready out of the box
Start free and see for yourself. Try the Playground to generate PDFs right from your browser.
Related
- wkhtmltopdf vs Chromium: Engine Selection Guide — Deep dive into engine differences
- Puppeteer to PDF API Migration Guide — Step-by-step migration from Puppeteer
- PDF API Quickstart — Get started in Node.js, Python, or PHP
- PDF API Pricing Comparison 2026 — Cost breakdown across services
- PDF Template Engine Guide — Dynamic PDF generation with templates
- PDF API Error Handling Guide — Essential error handling for production
- PDF API Production Checklist — End-to-end production readiness
- Automate Invoice PDF Generation — Practical API automation example
- FUNBREW PDF Documentation — API reference and quickstart
- Playground — Try PDF generation in your browser