PDF generation from HTML without managing servers
Generate PDFs from HTML without wkhtmltopdf or managing infrastructure. REST API with headers/footers, fonts, custom styling.
Your app generates invoices. Estimates. Contracts. Shipping labels. Every document becomes a PDF.
Currently: You run wkhtmltopdf on your server. It works... until it doesn't.
Wednesday 3 PM: wkhtmltopdf process hangs on a malformed HTML file. All PDF generation freezes. Customers can't download invoices. Support tickets pile up. By 5 PM, you're SSH'ing into production servers, killing processes manually.
There's a better way. A REST API that generates PDFs from HTML. No server to manage. No hanging processes. No complexity.
The self-hosted PDF generation trap
Most developers start with wkhtmltopdf or similar CLI tools:
const { execSync } = require('child_process');
const fs = require('fs');
function generatePDF(html, filename) {
fs.writeFileSync('/tmp/input.html', html);
execSync(`wkhtmltopdf /tmp/input.html /tmp/${filename}.pdf`, {
timeout: 30000
});
const pdf = fs.readFileSync(`/tmp/${filename}.pdf`);
fs.unlinkSync('/tmp/input.html');
fs.unlinkSync(`/tmp/${filename}.pdf`);
return pdf;
}
Looks simple. In production: nightmare.
Hidden costs
Process management
- wkhtmltopdf hangs on malformed HTML → timeout → manual restart
- No error recovery → customers stuck waiting
- Requires
/tmpcleanup (disk space issues) - System resource limits (ulimits) need tuning
Reliability
- Font rendering differs by system setup
- Timeouts are silent failures
- Large files OOM the process
- No graceful degradation
Scaling
- Each PDF needs a new process spawn (~2 seconds)
- Can't run 100 PDFs/second without horizontal scaling
- Vertical scaling hits ceiling
Real cost: $50–100/month infrastructure + 3–5 hours DevOps = ~$700/month effective cost.
Solution: Hosted PDF API
Call an endpoint. Get a PDF back. That's it.
curl -X POST https://pagebolt.dev/api/v1/pdf \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"html": "<h1>Invoice #12345</h1><p>Total: $99.99</p>",
"format": "A4",
"margin": "1in"
}' \
--output invoice.pdf
No infrastructure. No process management. No timeouts.
Before and after
Self-hosted approach
const express = require('express');
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
app.post('/invoice/:invoiceId', (req, res) => {
try {
const html = req.body.html;
const filename = `invoice-${req.params.invoiceId}`;
const tmpInput = path.join('/tmp', `${filename}.html`);
const tmpOutput = path.join('/tmp', `${filename}.pdf`);
fs.writeFileSync(tmpInput, html);
// This can hang, timeout, or fail silently
execSync(`wkhtmltopdf --margin-top 10 --margin-bottom 10 ${tmpInput} ${tmpOutput}`, {
timeout: 30000,
stdio: 'pipe'
});
const pdf = fs.readFileSync(tmpOutput);
fs.unlinkSync(tmpInput);
fs.unlinkSync(tmpOutput);
res.set('Content-Type', 'application/pdf');
res.set('Content-Disposition', `attachment; filename="${filename}.pdf"`);
res.send(pdf);
} catch (error) {
console.error('PDF generation failed:', error);
res.status(500).send('PDF generation failed');
}
});
Cost: $50–100/month infrastructure + 3–5 hours DevOps = ~$700/month effective.
Hosted API approach
app.post('/invoice/:invoiceId', async (req, res) => {
try {
const response = await fetch('https://pagebolt.dev/api/v1/pdf', {
method: 'POST',
headers: {
'x-api-key': process.env.PAGEBOLT_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
html: req.body.html,
format: 'A4',
margin: '1in'
})
});
const pdf = Buffer.from(await response.arrayBuffer());
res.set('Content-Type', 'application/pdf');
res.set('Content-Disposition', `attachment; filename="invoice-${req.params.invoiceId}.pdf"`);
res.send(pdf);
} catch (error) {
res.status(500).send('PDF generation failed');
}
});
Cost: $29/month (Starter, 5,000 PDFs/month), $0 infrastructure, $0 DevOps = $29/month total.
Real example: Invoice generation + email
E-commerce platform: generate invoice PDF, email to customer, archive to S3.
const nodemailer = require('nodemailer');
const AWS = require('aws-sdk');
async function generateAndEmailInvoice(order) {
const html = `
<h1>Invoice</h1>
<p>Order ID: ${order.id}</p>
<table>
${order.items.map(item => `
<tr>
<td>${item.name}</td>
<td>$${item.price}</td>
</tr>
`).join('')}
</table>
<p>Total: $${order.total}</p>
`;
// Generate PDF
const res = await fetch('https://pagebolt.dev/api/v1/pdf', {
method: 'POST',
headers: {
'x-api-key': process.env.PAGEBOLT_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({ html, format: 'A4' })
});
const pdf = Buffer.from(await res.arrayBuffer());
// Email to customer
await nodemailer.createTransport({/* ... */}).sendMail({
from: 'noreply@mystore.com',
to: order.customer.email,
subject: `Invoice for Order #${order.id}`,
text: 'Your invoice is attached.',
attachments: [{ filename: `invoice-${order.id}.pdf`, content: pdf }]
});
// Archive to S3
await new AWS.S3().putObject({
Bucket: 'invoices-archive',
Key: `${order.id}.pdf`,
Body: pdf
}).promise();
return { success: true, invoiceId: order.id };
}
Simple, reliable, no process management.
Comparison: wkhtmltopdf vs hosted API
| Factor | wkhtmltopdf | Hosted API |
|---|---|---|
| Setup | 1–2 hours | 10 minutes |
| Infra cost | $50–100/month | $0 |
| DevOps time | 3–5 hours/month | 0 hours |
| Latency | 2–5 seconds | 1–2 seconds |
| Reliability | 99% (hangs, timeouts) | 99.9% SLA |
| Scaling | Capped at server | Unlimited |
| Font support | System-dependent | Consistent |
| Custom styling | Limited | Full CSS3 |
| Per-PDF cost | $0.05–0.10 (infra) | $0.02–0.05 (API) |
When to use hosted PDF API
✅ User-facing invoice/receipt generation
✅ Automated document pipelines
✅ Report generation at scale
✅ Limited DevOps resources
✅ Unpredictable volume
Keep wkhtmltopdf if:
- You process 10,000+ PDFs/day (break-even at scale)
- You have dedicated DevOps
- Documents require extreme customization not achievable via HTML/CSS
For most teams: hosted wins.
Getting started
- Sign up at pagebolt.dev (free: 100 requests/month)
- Get API key from your dashboard (1 minute)
- Make your first PDF (5 minutes)
- Evaluate: Does it solve your use case?
No more hanging processes. No more 3 AM PDF generation failures.
Replace wkhtmltopdf in 10 minutes
Free tier: 100 PDFs/month. No credit card. No servers to manage.