203 lines
5.8 KiB
Markdown
203 lines
5.8 KiB
Markdown
---
|
|
title: "Stop Wrestling with Puppeteer: Generate PDFs with One API Call"
|
|
published: false
|
|
description: "How to generate invoices, reports, and documents as PDFs from HTML, Markdown, or JSON data — without managing headless browsers."
|
|
tags: webdev, api, node, tutorial
|
|
cover_image: # (add a cover image URL)
|
|
---
|
|
|
|
Every developer has the same PDF story. It starts innocently:
|
|
|
|
> "Can we add a 'Download as PDF' button?"
|
|
|
|
Three days later, you're debugging Chrome memory leaks in production, your Puppeteer instance is eating 2GB of RAM, and the PDFs look different on every server.
|
|
|
|
I got tired of this cycle, so I built [DocFast](https://docfast.dev) — a PDF API that takes HTML, Markdown, or structured data and returns a PDF. No headless browser setup, no dependencies.
|
|
|
|
Here's what I learned, and how you can generate PDFs in about 30 seconds.
|
|
|
|
## The Simple Version
|
|
|
|
```bash
|
|
curl -X POST https://docfast.dev/v1/convert/html \
|
|
-H "Authorization: Bearer YOUR_KEY" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"html": "<h1>Hello World</h1><p>This is a PDF.</p>"}' \
|
|
-o hello.pdf
|
|
```
|
|
|
|
That's it. JSON in, PDF out.
|
|
|
|
## Three Ways to Generate PDFs
|
|
|
|
DocFast has three conversion endpoints, each for a different use case:
|
|
|
|
### 1. HTML → PDF
|
|
|
|
You have full control. Pass any HTML with optional CSS:
|
|
|
|
```javascript
|
|
const response = await fetch('https://docfast.dev/v1/convert/html', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Authorization': 'Bearer YOUR_KEY',
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
html: `
|
|
<h1 style="color: navy;">Monthly Report</h1>
|
|
<p>Revenue: <strong>$12,345</strong></p>
|
|
<table>
|
|
<tr><td>Users</td><td>1,234</td></tr>
|
|
<tr><td>MRR</td><td>$5,670</td></tr>
|
|
</table>
|
|
`,
|
|
css: 'body { font-family: Georgia, serif; padding: 40px; }',
|
|
format: 'A4'
|
|
})
|
|
});
|
|
|
|
const pdf = await response.arrayBuffer();
|
|
fs.writeFileSync('report.pdf', Buffer.from(pdf));
|
|
```
|
|
|
|
### 2. Markdown → PDF
|
|
|
|
This is my favorite endpoint. Write Markdown, get a styled PDF with syntax highlighting:
|
|
|
|
```javascript
|
|
const markdown = `
|
|
# Project Proposal
|
|
|
|
## Overview
|
|
We propose building a **real-time dashboard** for monitoring API usage.
|
|
|
|
## Timeline
|
|
| Phase | Duration | Cost |
|
|
|-------|----------|------|
|
|
| Design | 2 weeks | $3,000 |
|
|
| Build | 4 weeks | $8,000 |
|
|
| Test | 1 week | $1,500 |
|
|
|
|
## Code Sample
|
|
\`\`\`javascript
|
|
const analytics = new Analytics({ key: 'abc123' });
|
|
analytics.track('pdf_generated', { format: 'A4' });
|
|
\`\`\`
|
|
`;
|
|
|
|
const response = await fetch('https://docfast.dev/v1/convert/markdown', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Authorization': 'Bearer YOUR_KEY',
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({ markdown })
|
|
});
|
|
```
|
|
|
|
Tables, code blocks, images — it all renders beautifully.
|
|
|
|
### 3. URL → PDF
|
|
|
|
Need to snapshot a webpage? Just pass the URL:
|
|
|
|
```bash
|
|
curl -X POST https://docfast.dev/v1/convert/url \
|
|
-H "Authorization: Bearer YOUR_KEY" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"url": "https://example.com", "waitUntil": "networkidle0"}' \
|
|
-o page.pdf
|
|
```
|
|
|
|
It handles JavaScript-rendered pages too (SPAs, dashboards, etc).
|
|
|
|
## The Killer Feature: Invoice Templates
|
|
|
|
This is what I wish existed years ago. Instead of building invoice HTML from scratch, you pass JSON data and get a professional invoice:
|
|
|
|
```javascript
|
|
const response = await fetch('https://docfast.dev/v1/templates/invoice/render', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Authorization': 'Bearer YOUR_KEY',
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
data: {
|
|
invoiceNumber: 'INV-2026-042',
|
|
date: '2026-02-14',
|
|
dueDate: '2026-03-14',
|
|
from: {
|
|
name: 'Your Company',
|
|
address: '123 Main St',
|
|
email: 'billing@yourco.com'
|
|
},
|
|
to: {
|
|
name: 'Client Corp',
|
|
address: '456 Oak Ave',
|
|
email: 'ap@client.com'
|
|
},
|
|
items: [
|
|
{ description: 'Web Development', quantity: 40, unitPrice: 95, taxRate: 20 },
|
|
{ description: 'Hosting', quantity: 1, unitPrice: 29 }
|
|
],
|
|
currency: '€',
|
|
notes: 'Payment due within 30 days.',
|
|
paymentDetails: 'IBAN: AT12 3456 7890 1234 5678'
|
|
}
|
|
})
|
|
});
|
|
```
|
|
|
|
No HTML. No CSS. Just data → PDF.
|
|
|
|
## Integrating Into Your App
|
|
|
|
Here's a minimal Express.js endpoint that generates and returns an invoice:
|
|
|
|
```javascript
|
|
app.get('/api/invoice/:id', async (req, res) => {
|
|
const invoice = await db.getInvoice(req.params.id);
|
|
|
|
const pdfResponse = await fetch('https://docfast.dev/v1/templates/invoice/render', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Authorization': `Bearer ${process.env.DOCFAST_KEY}`,
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({ data: invoice })
|
|
});
|
|
|
|
res.setHeader('Content-Type', 'application/pdf');
|
|
res.setHeader('Content-Disposition', `attachment; filename=invoice-${invoice.invoiceNumber}.pdf`);
|
|
pdfResponse.body.pipe(res);
|
|
});
|
|
```
|
|
|
|
12 lines. Your users can download invoices.
|
|
|
|
## Why Not Just Use Puppeteer?
|
|
|
|
You can! But here's what you're signing up for:
|
|
|
|
- **Memory:** Each Chrome instance uses 200-500MB RAM
|
|
- **Cold starts:** Launching a browser takes 1-3 seconds
|
|
- **Stability:** Chrome crashes, zombie processes, OOM kills
|
|
- **DevOps:** Managing Chrome versions, fonts, dependencies in Docker
|
|
- **Concurrency:** Need multiple PDFs at once? Now you're managing a browser pool
|
|
|
|
DocFast handles all of this. Persistent browser pool, sub-second generation, no infrastructure to manage.
|
|
|
|
## Pricing
|
|
|
|
- **Free:** 100 PDFs/month, all endpoints, all templates
|
|
- **Pro:** $9/month for 10,000 PDFs/month
|
|
|
|
No per-page fees. No credit card for the free tier. [Get your API key here](https://docfast.dev).
|
|
|
|
---
|
|
|
|
If you have questions about the API or want to see specific templates added, drop a comment. I'm actively building based on user feedback.
|
|
|
|
Happy PDF-ing! 📄
|