Forem

Custodia-Admin
Custodia-Admin

Posted on • Originally published at pagebolt.dev

html-pdf Alternative: Generate PDFs from HTML Without the Phantom/wkhtmltopdf Headaches

html-pdf Alternative: Generate PDFs from HTML Without the Phantom/wkhtmltopdf Headaches

If you're still using the html-pdf npm package, you've probably hit the wall. 4,000+ stars, zero updates since 2019, and CSS rendering that feels stuck in 2010. Or you're maintaining mPDF, dompdf, or wkhtmltopdf in production — debugging native dependency hell every time you deploy.

There's a better way.

The Problem: Why html-pdf and Friends Break

The html-pdf package (unmaintained since 2019) relies on PhantomJS, a headless browser that's been abandoned for years. It doesn't support modern CSS:

  • CSS Grid? Nope.
  • Flexbox? Partial at best.
  • CSS variables? Forget it.
  • Media queries? Good luck.

PHP developers face the same problem with mPDF and dompdf — they're JavaScript-based rendering engines that struggle with anything beyond basic styling.

Then there's wkhtmltopdf. Yes, it renders CSS better. But it requires:

  • A native binary installed on your server
  • Qt library dependencies (300MB+)
  • System-level configuration for headless operation
  • Docker images bloated to 700MB+ just to avoid dependency hell

Every deployment, every scaling event, every new server — you're managing native dependencies instead of writing code.

The Before/After: Code Complexity Comparison

Before — html-pdf (struggling with CSS):

const pdf = require('html-pdf');
const fs = require('fs');

const html = `
  <html>
    <head>
      <style>
        body { font-family: Arial; }
        .grid { display: grid; grid-template-columns: 1fr 1fr; }
        h1 { color: #333; font-size: 24px; }
      </style>
    </head>
    <body>
      <h1>Invoice</h1>
      <div class="grid">
        <div>Item 1</div>
        <div>$50</div>
      </div>
    </body>
  </html>
`;

const options = {
  format: 'A4',
  orientation: 'portrait',
  border: {
    top: '10mm',
    right: '10mm',
    bottom: '10mm',
    left: '10mm'
  },
  // PhantomJS rendering — CSS Grid won't work properly
};

pdf.create(html, options).toFile('invoice.pdf', (err, res) => {
  if (err) return console.log(err);
  console.log(res.filename);
  // Grid layout rendered incorrectly; flexbox issues; media queries ignored
});
Enter fullscreen mode Exit fullscreen mode

Result: Your CSS Grid layout collapses. Flexbox breaks. Colors look wrong. You're fighting the browser engine, not building.

After — PageBolt API (modern Chromium rendering):

const html = `
  <html>
    <head>
      <style>
        body { font-family: Arial; }
        .grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
        h1 { color: #333; font-size: 24px; }
      </style>
    </head>
    <body>
      <h1>Invoice</h1>
      <div class="grid">
        <div>Item 1</div>
        <div>$50</div>
      </div>
    </body>
  </html>
`;

const response = await fetch('https://api.pagebolt.dev/generate_pdf', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ html, format: 'A4' })
});

const { pdfUrl } = await response.json();
console.log(pdfUrl); // PDF with perfect CSS Grid, flexbox, modern styling
Enter fullscreen mode Exit fullscreen mode

Difference: 5 lines vs. 30. Modern CSS support. No native dependencies. No Docker bloat.

Feature Comparison: What Actually Works

Feature html-pdf wkhtmltopdf mPDF/dompdf PageBolt
CSS Grid ⚠️ Partial ✅ Full
Flexbox ⚠️ Partial ⚠️ Partial ✅ Full
CSS Variables
Media Queries
Web Fonts (@import) ⚠️ Limited
SVG/Canvas ⚠️ Limited ⚠️ Limited ✅ Full
Native Dependencies ✅ PhantomJS (abandoned) ❌ Qt library required ✅ None ✅ None
Maintenance Status 🚨 Abandoned (2019) ⚠️ Limited ⚠️ Community-driven ✅ Active
CSS Rendering 2010s 2015s 2015s 2024+

PageBolt runs on real Chromium — the same browser rendering engine used by 60% of the web. Your CSS works.

Real-World Cost Analysis

Scenario: Generate 10,000 invoices/month in production

Option 1: Self-Hosted wkhtmltopdf

  • Server: $100/month (t3.medium EC2)
  • Maintenance: 5 hrs/month managing dependencies, debugging rendering issues, handling deployment failures
  • Labor: $500/month (50 hrs × $100/hr contractor rate)
  • Total: $600/month

Option 2: PageBolt API

  • API cost: 10,000 PDFs × $0.01 = $100/month
  • Management: Zero — no servers, no dependencies
  • Total: $100/month

Savings: $500/month. Plus 5 hours of engineering time freed.

For enterprises generating 1M+ PDFs/month, PageBolt's cost scales predictably. Self-hosted solutions require scaling infrastructure, managing more servers, debugging more edge cases.

Migration Path: Drop-In Replacement

  1. Test with PageBolt first (100 free requests/month):
   const response = await fetch('https://api.pagebolt.dev/generate_pdf', {
     method: 'POST',
     headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' },
     body: JSON.stringify({ html, format: 'A4', margin: '10mm' })
   });
Enter fullscreen mode Exit fullscreen mode
  1. Wrap in an abstraction so you can switch back if needed:
   async function generatePDF(html) {
     return fetch('https://api.pagebolt.dev/generate_pdf', { /* ... */ });
   }
Enter fullscreen mode Exit fullscreen mode
  1. Migrate gradually — new features use PageBolt, old code continues with html-pdf until you're ready to switch.

  2. No vendor lock-in — if needed, export your templates and switch at any time.

When to Use What

Use PageBolt if:

  • You need modern CSS support (Grid, Flexbox, variables)
  • You want zero infrastructure management
  • You value reliability and maintenance
  • You generate 100+ PDFs/month
  • You need consistent output across deployments

Use html-pdf if:

  • You're in a legacy codebase with unmaintained code you won't touch
  • You generate <10 PDFs/month and can tolerate rendering bugs
  • You need 100% local control for compliance reasons

(Spoiler: PageBolt wins for every real production scenario.)

Next Steps

  • Try PageBolt free — 100 requests/month, no credit card. Test with your actual HTML templates.
  • Check the docs — CSS support matrix, all rendering options, pricing tiers.
  • Migrate one feature — replace your invoice or report generation first. Measure the difference.

Your CSS Grid layouts are waiting. Stop fighting PhantomJS. Start generating PDFs that actually look right.


PageBolt makes PDF generation simple, modern, and cost-effective. Get started free →

Top comments (0)