Why invoices are a good fit for HTML
An invoice is a table, a total, and a logo. That is exactly what HTML and CSS are good at, and it means your designers can iterate on the layout without a developer rebuilding a coordinate-based PDF template every time the branding changes.
- Line items that reflow naturally across pages, with the header repeated on each
- Tax and discount rows that appear only when they apply, using ordinary template conditionals
- Locale-aware currency and date formatting handled in your app, not the PDF layer
- Right-to-left layouts and non-Latin scripts via normal CSS and web fonts
Surviving end of month
Billing traffic is not smooth. It is flat for twenty-nine days and then everything happens at once. Requests are queued rather than dropped when volume spikes, transient failures are retried automatically, and workers scale with the queue depth — so the first invoice of the run and the ten-thousandth take the same time.
import fs from "node:fs";
const res = await fetch("https://api.filecook.com/render/pdf", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.FILECOOK_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
html: "<h1>Invoice #1042</h1>",
options: { format: "A4", margin: "12mm" }
})
});
if (!res.ok) throw new Error(`Render failed: ${res.status}`);
fs.writeFileSync("invoice.pdf", Buffer.from(await res.arrayBuffer()));
Attaching to the email that follows
The response is the raw PDF, so the common pattern is a single function: render, attach, send. There is no intermediate upload step and no signed URL to expire, which also means the invoice never sits at rest on someone else’s infrastructure.
