HTML to PDF in Bun
One POST, a PDF back. No headless browser to install, no Chromium to keep patched, no fonts to install on the box — the render happens on a warm browser that is already running.
Render HTML to a PDF
const response = await fetch('https://api.pdfcraft.dev/v1/render', {
method: 'POST',
headers: {
authorization: `Bearer ${Bun.env.PDFCRAFT_API_KEY}`,
'content-type': 'application/json',
},
body: JSON.stringify({ html: '<h1>Invoice 1042</h1>' }),
});
await Bun.write('invoice.pdf', await response.arrayBuffer());Read a PDF back as JSON
The same key works for extraction. Send a PDF, name the fields you want by the label printed on the page, and get them back with the raw text, a coerced value, a confidence and a bounding box.
const pdf = await Bun.file('statement.pdf').arrayBuffer();
const response = await fetch('https://api.pdfcraft.dev/v1/extract', {
method: 'POST',
headers: {
authorization: `Bearer ${Bun.env.PDFCRAFT_API_KEY}`,
'content-type': 'application/json',
},
body: JSON.stringify({
file: Buffer.from(pdf).toString('base64'),
schema: { closing_balance: 'currency' },
}),
});
const { fields, tables } = await response.json();What bites in Bun
- `Bun.write` takes an ArrayBuffer directly, so there is no Buffer round-trip for the render path.
- Bun implements Node’s Buffer, which is still the shortest way to base64 a file for the extract path.
- The SDK installs and runs unchanged under Bun — it has no dependencies and no native code.
Errors are one shape
Every failure is {"error":{"code","message","docs_url"}} with a stable code, so you can switch on error.code rather than parsing prose. The two worth handling explicitly are rate_limited — honour Retry-After — and render_failed, which means your HTML broke rather than ours did.
The same thing in another language
- HTML to PDF in Node.js
- HTML to PDF in Python
- HTML to PDF in Go
- HTML to PDF in PHP
- HTML to PDF in Ruby
- HTML to PDF in Java
- HTML to PDF in C#
- HTML to PDF in Rust
- HTML to PDF in curl
- HTML to PDF in Deno
- HTML to PDF in TypeScript
Or try it with no code at all in the playground. A free key is 100 renders a month.