Comparison

PDFSend vs DIY Puppeteer

Every developer thinks “I'll just use Puppeteer directly”. Then they spend weeks building template management, a preview system, auth, error handling, and an editor UI. PDFSend ships all of this out of the box — plus a visual editor your business team can use without writing a single line of code.

The real cost of “I'll build it myself”

Puppeteer's page.pdf() is just the rendering step. Everything around it — the template system, the API, the editor, the preview — is where the real work lives.

What you need to buildDIY effortPDFSend
Browser setup & management4-8hBuilt-in
Template storage & CRUD8-16hBuilt-in
Variable injection system2-4hBuilt-in
PDF format/margin config2-4hBuilt-in
REST API with auth8-16hBuilt-in
Template editor UI16-40hBuilt-in
Live preview8-16hBuilt-in
Generation logs & analytics8-16hBuilt-in
API documentation4-8hBuilt-in
Error handling & edge cases4-8hBuilt-in
Total64-136 hours~5 minutes

At a $100/hour developer rate, that's $6400-$13600 of engineering time. Plus ongoing maintenance.

Before and after

DIY Puppeteer
// DIY Puppeteer — the "simple" version
const puppeteer = require('puppeteer');

async function generatePdf(html, data, options) {
  // Launch browser (cold start: 2-5 seconds)
  const browser = await puppeteer.launch({
    headless: true,
    args: ['--no-sandbox', '--disable-setuid-sandbox',
           '--disable-dev-shm-usage']
  });

  try {
    const page = await browser.newPage();

    // Manually replace variables
    let rendered = html;
    for (const [key, value] of Object.entries(data)) {
      rendered = rendered.replaceAll(`{{${key}}}`, value);
    }

    await page.setContent(rendered, {
      waitUntil: 'networkidle0' // or 'networkidle2'?
    });

    const pdf = await page.pdf({
      format: options.format || 'A4',
      margin: options.margin || { top: '20mm', bottom: '20mm' },
      printBackground: true,
    });

    return pdf;
  } finally {
    await browser.close(); // Don't forget this!
  }
}

// Now you need: API route, auth, template storage,
// editor UI, preview, logs, error handling...
// That's another 60-120 hours of work.
With PDFSend
// PDFSend — one API call
const res = await fetch('https://pdfsend.up.railway.app/api/v1/render', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer ps_live_xxxxx',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    template_id: 'invoice',
    data: { company: 'Acme Corp', amount: '$1,500' },
  }),
});

const pdf = await res.blob(); // Done.

What you get out of the box

With raw Puppeteer, you get page.pdf(). That's it. Everything else — template storage, variable injection, format presets, browser lifecycle management, auth, API routes — is on you.

PDFSend wraps all of this into a production-ready system:

  • Monaco editor with Handlebars autocompletion and custom dark theme
  • Visual editor — your business team can update templates without touching code or asking a developer
  • Live preview with accurate page dimensions and margin simulation
  • Singleton browser instance — no cold starts, reuses Chromium across requests
  • 6 PDF format presets with configurable margins, fonts, and background colors
  • REST API compatible with any language (TypeScript, Python, Go, Rust, PHP, cURL...) — Bearer auth and structured error responses
  • Interactive API docs powered by Scalar (OpenAPI 3.1)
  • Generation logs with duration tracking, file sizes, and cursor pagination
  • 5 starter templates (Invoice, Payslip, Certificate, Receipt, Letter)

When DIY Puppeteer makes sense

To be fair, there are cases where raw Puppeteer is the right choice:

  • You need to render PDFs from existing web pages (not templates)
  • You need screenshot capture, not just PDF generation
  • You're building a scraping pipeline that happens to output PDFs
  • You need very specific browser automation beyond PDF rendering

But if your use case is “I have HTML templates, I need to inject data and generate PDFs via API” — that's exactly what PDFSend was built for.

Stop rebuilding the wheel

Deploy PDFSend and start generating PDFs in 5 minutes instead of 5 weeks.