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
});
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
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
- 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' })
});
- Wrap in an abstraction so you can switch back if needed:
async function generatePDF(html) {
return fetch('https://api.pagebolt.dev/generate_pdf', { /* ... */ });
}
Migrate gradually — new features use PageBolt, old code continues with html-pdf until you're ready to switch.
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)