DEV Community

Custodia-Admin
Custodia-Admin

Posted on • Originally published at pagebolt.dev

How to Generate PDFs from HTML in Node.js (No Puppeteer)

How to Generate PDFs from HTML in Node.js (No Puppeteer)

If you've ever tried generating PDFs from HTML in Node.js, you know the pain: Puppeteer requires installing Chrome, managing processes, handling memory leaks, and dealing with infrastructure overhead. There's a simpler way.

In this tutorial, I'll show you how to generate production-ready PDFs in just 3 lines of code using the PageBolt API — no browser installation, no DevOps headaches.

The Problem: Puppeteer Complexity

Here's what a basic Puppeteer PDF generation looks like:

const puppeteer = require('puppeteer');

async function generatePDF(htmlContent, filename) {
  const browser = await puppeteer.launch({
    args: ['--no-sandbox', '--disable-setuid-sandbox']
  });

  const page = await browser.newPage();
  await page.setContent(htmlContent);

  // Set PDF options
  await page.pdf({
    path: filename,
    format: 'A4',
    margin: {
      top: '10mm',
      right: '10mm',
      bottom: '10mm',
      left: '10mm'
    }
  });

  await browser.close();
}
Enter fullscreen mode Exit fullscreen mode

That's 20 lines for a basic PDF. Now add error handling, retry logic, timeout management, and memory cleanup — you're looking at 50+ lines of boilerplate code. And you still need to manage Chrome process lifecycle, handle OOM errors, and maintain your own infrastructure.

The Solution: PageBolt's PDF API

Here's the equivalent using PageBolt:

const response = await fetch('https://api.pagebolt.dev/v1/pdf', {
  method: 'POST',
  headers: { 'Authorization': `Bearer YOUR_API_KEY` },
  body: JSON.stringify({
    html: htmlContent,
    format: 'A4',
    margin: { top: 10, right: 10, bottom: 10, left: 10 }
  })
});

const pdfBuffer = await response.arrayBuffer();
Enter fullscreen mode Exit fullscreen mode

That's it. 3 lines. No browser installation. No process management. No memory leaks.

Real-World Example: Invoice Generation

Let's say you're building an invoicing system. Here's how to generate a PDF invoice from an HTML template:

async function generateInvoice(invoiceData) {
  const htmlTemplate = `
    <html>
      <head>
        <style>
          body { font-family: Arial, sans-serif; margin: 40px; }
          .header { font-size: 24px; font-weight: bold; margin-bottom: 20px; }
          .item { display: flex; justify-content: space-between; padding: 10px 0; }
          .total { font-weight: bold; border-top: 1px solid #000; margin-top: 20px; padding-top: 10px; }
        </style>
      </head>
      <body>
        <div class="header">Invoice #${invoiceData.invoiceId}</div>
        <div>Date: ${invoiceData.date}</div>
        <div>Customer: ${invoiceData.customer}</div>

        <div style="margin-top: 30px;">
          ${invoiceData.items.map(item => `
            <div class="item">
              <span>${item.description}</span>
              <span>$${item.amount.toFixed(2)}</span>
            </div>
          `).join('')}
        </div>

        <div class="total">Total: $${invoiceData.total.toFixed(2)}</div>
      </body>
    </html>
  `;

  const response = await fetch('https://api.pagebolt.dev/v1/pdf', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer YOUR_API_KEY`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      html: htmlTemplate,
      format: 'A4'
    })
  });

  if (!response.ok) throw new Error(`PDF generation failed: ${response.statusText}`);

  return Buffer.from(await response.arrayBuffer());
}

// Usage
const pdfBuffer = await generateInvoice({
  invoiceId: 'INV-001',
  date: new Date().toLocaleDateString(),
  customer: 'Acme Corp',
  items: [
    { description: 'Web Development', amount: 5000 },
    { description: 'UI Design', amount: 2000 }
  ],
  total: 7000
});

// Save to file
const fs = require('fs');
fs.writeFileSync('invoice.pdf', pdfBuffer);
Enter fullscreen mode Exit fullscreen mode

Batch PDF Generation

Need to generate 1,000 invoices? PageBolt handles concurrent requests without breaking a sweat:

async function generateBatchInvoices(invoices) {
  const promises = invoices.map(invoice => generateInvoice(invoice));
  const results = await Promise.allSettled(promises);

  return results.map((result, idx) => ({
    invoiceId: invoices[idx].invoiceId,
    status: result.status,
    pdf: result.value,
    error: result.reason?.message
  }));
}
Enter fullscreen mode Exit fullscreen mode

Cost Comparison

Puppeteer (self-hosted):

  • AWS EC2 t3.medium instance: ~$30/month
  • Chrome memory overhead: ~200MB per process
  • Managing 5 concurrent processes: ~$150/month
  • Total: $150-300/month for modest scale

PageBolt:

  • Starter plan: $29/month for 5,000 PDFs
  • Growth plan: $79/month for 25,000 PDFs
  • Scale plan: $199/month for 100,000 PDFs
  • No infrastructure to manage

For most applications, PageBolt Starter ($29/month) handles your entire PDF generation needs.

Getting Started

  1. Sign up for free at pagebolt.dev/pricing — 100 PDFs/month, no credit card required
  2. Get your API key from the dashboard
  3. Make your first PDF request:
const response = await fetch('https://api.pagebolt.dev/v1/pdf', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer YOUR_API_KEY`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    html: '<h1>Hello World</h1>',
    format: 'A4'
  })
});

const pdf = await response.arrayBuffer();
Enter fullscreen mode Exit fullscreen mode

That's your first PDF, generated in milliseconds. No Puppeteer, no infrastructure, no complexity.

When to Use PageBolt vs. Puppeteer

Use PageBolt if you:

  • Generate PDFs on-demand (invoices, reports, certificates)
  • Want zero infrastructure overhead
  • Need reliable uptime guarantees
  • Prefer managed services over DIY

Use Puppeteer if you:

  • Need full browser automation (screenshots, testing)
  • Generate PDFs so rarely it doesn't justify a service subscription
  • Have strict data residency requirements

For pure PDF generation, PageBolt wins on simplicity, cost, and reliability every time.

Start free today — pagebolt.dev/pricing. 100 PDFs/month, no credit card required.

Top comments (0)