March 26, 2026

HTML to PDF API Comparison 2026: With Code Examples

PDF APIcomparisonwkhtmltopdfChromiumPuppeteer

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

Powered by FUNBREW PDF