Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Use pdf-creator-node to render an HTML string or Handlebars template through Puppeteer and Chromium, then write a PDF file, buffer, or stream. The core call is pdf.create(document, options). Your document supplies html, data, and (for file output) a path; options control paper size, orientation, margins, print backgrounds, page ranges, and headers or footers.

The package listing currently shows version 4.0.1, but npm versions change. Check the npm package page before pinning a dependency. At the time documented there, Node.js 18 or newer was required.

What pdf-creator-node does

pdf-creator-node is a Node.js wrapper for converting HTML and Handlebars templates to PDF with Puppeteer and headless Chromium. Chromium lays out the page much like a browser, so CSS, web fonts, images, tables and print rules can be used instead of drawing every PDF object manually. The trade-off is a larger installation and a browser process at runtime: Puppeteer normally downloads a compatible Chromium build during installation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The project documentation is at hajareshyam.github.io/pdf-creator-node. Wrapper option names and behavior can vary between releases, so verify them against the version installed in your application.

Prerequisites and installation

Install Node.js and the package

Use Node.js 18 or newer for the package requirement documented on npm. In a new project:

mkdir html-pdf-demo
cd html-pdf-demo
npm init -y
npm install pdf-creator-node

Expect the install to be larger than a pure JavaScript PDF library because Puppeteer downloads Chromium by default. In a container or serverless build, ensure the install step is allowed to download the browser and that the runtime can launch it.

Choose an output mode

  • File: provide path and let the package write a PDF.
  • Buffer: use the documented buffer type when you need to send the PDF through an HTTP response, object storage client or queue.
  • Stream: use the documented stream type when your surrounding API expects a readable stream.

Do not omit data; pass an object even when the HTML has no variables. Missing or empty HTML, missing data, a missing path for file output and template compilation errors are documented validation failures.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Minimal HTML-to-PDF conversion

Create template.html:

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Monthly report</title>
  <style>
    body { font-family: Arial, sans-serif; color: #222; }
    h1 { color: #123b66; }
  </style>
</head>
<body>
  <h1>{{title}}</h1>
  <p>Generated for {{customer}}.</p>
</body>
</html>

Then create convert.js:

const pdf = require("pdf-creator-node");
const fs = require("node:fs");

const html = fs.readFileSync("template.html", "utf8");
const document = {
  html,
  data: {
    title: "Monthly report",
    customer: "Example Company",
  },
  path: "./output.pdf",
};
const options = {
  format: "A4",
  orientation: "portrait",
  border: "10mm",
};

pdf.create(document, options)
  .then((result) => console.log(result))
  .catch((error) => {
    console.error("PDF generation failed:", error);
    process.exitCode = 1;
  });

Run it with node convert.js. A successful run creates output.pdf. The same pdf.create(document, options) flow works with an HTML string assembled in code or rendered from a Handlebars template.

Using Handlebars data safely

Put the values your template needs in document.data. Keep presentation in the template and data preparation in JavaScript:

const document = {
  html: fs.readFileSync("invoice.html", "utf8"),
  data: {
    invoiceNumber: "INV-1042",
    customer: { name: "Ada Lovelace", address: "1 Example Street" },
    items: [
      { description: "Consulting", quantity: 2, amount: "$400.00" },
      { description: "Support", quantity: 1, amount: "$100.00" },
    ],
  },
  path: "./invoice.pdf",
};

In the template, iterate over arrays with the Handlebars syntax supported by your installed package version. Escape untrusted text rather than injecting raw HTML. If a value is intentionally trusted markup, isolate and validate that input before passing it to the template.

Paper size, orientation and margins

The wrapper exposes common paper settings such as A3, A4, orientation, dimensions and borders. For v4, these settings are mapped to Puppeteer/Chromium; old PhantomJS-era options should not be assumed to work.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Need Typical setting What to verify
Standard report format: "A4" Content width and page breaks
Large drawing or poster format: "A3" or explicit width/height Printer or viewer support
Wide table orientation: "landscape" Headers, totals and overflow
Safe printable area border: "10mm" or margin options Whether the target printer clips edges

For detailed controls, Puppeteer documents PDF options for paper format, width, height, landscape orientation, margins, scale, page ranges, print backgrounds and header/footer templates in its PDFOptions reference. The wrapper’s direct options take precedence over matching pdfChrome values in the v4 documentation, so avoid setting contradictory values in both places.

Headers, footers and repeating content

pdf-creator-node examples include header and footer content, and the v4 documentation describes pdfChrome for Chromium layout and repeating headers or footers. Header and footer snippets are rendered separately from the main page. They do not automatically inherit the document’s styles.

  • Include needed CSS directly in the header or footer markup.
  • Repeat font declarations or references if the header uses a custom font.
  • Reserve enough top or bottom margin so content does not overlap the repeated area.
  • Inspect multiple pages; a one-page sample can hide overlap on later pages.

If you need page numbers or other Chromium header/footer tokens, confirm the syntax supported by the installed version and Puppeteer PDF options.

Print CSS changes the result

Puppeteer states that Page.pdf() “Generates a PDF of the page with the print CSS media type.” That means a screen screenshot is not a reliable preview of the PDF. A navigation bar hidden for print may disappear, while a print-only title may appear.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Add print rules deliberately:

@media print {
  .screen-only { display: none !important; }
  .avoid-break { break-inside: avoid; }
  a { color: #000; text-decoration: none; }
}

@page {
  size: A4 portrait;
  margin: 12mm;
}

Chromium waits for fonts by default during PDF generation. Print colors may also be adjusted unless CSS requests exact color rendering. If brand colors matter, test the actual PDF and consider:

@media print {
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}

Background graphics, tables split across pages, fixed-position elements, flex or grid layouts and very large images all deserve inspection in the generated file. The official guides are Puppeteer PDF generation and the Page.pdf() API reference.

Local images, fonts and relative URLs

Relative asset URLs need a base directory so Chromium can resolve them. Set the base directory as described by the package documentation, or use correctly formed absolute URLs where your deployment permits network access. Check file permissions and URL casing on Linux, where paths are case-sensitive.

  • Use a stable absolute path for local assets in production.
  • Wait for fonts and images to load before capture when your wrapper configuration exposes those waits.
  • Keep credentials out of asset URLs; use controlled headers or packaged local files instead.
  • Test inside the deployment container, not only on a developer laptop.

Buffer and stream responses

When an HTTP endpoint should return bytes instead of creating a permanent file, use the package’s documented buffer output type. For a download endpoint, set the response headers yourself and send the returned buffer. For pipelines that consume readable data, use the documented stream type. The exact type names and result shape are version-sensitive; confirm them in the project documentation for your installed release.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

File output remains simplest for scheduled jobs

For reports generated by a worker, writing to a temporary path makes retries and inspection straightforward. Use a unique filename, verify that the file exists and has non-zero size, then upload or move it. Remove temporary files after a successful upload and retain failed artifacts only when your debugging policy permits.

Production deployment and performance

Chromium rendering uses more resources than a drawing-only PDF library, and the browser download increases installation footprint. The package documentation discusses containers and serverless constraints; treat those as deployment considerations, not as universal memory or speed benchmarks.

Plan concurrency around your workload

  • Limit simultaneous conversions so several Chromium pages do not exhaust memory.
  • Queue large batches and apply request timeouts at the worker boundary.
  • Reuse a controlled browser process only if your integration supports it safely; otherwise favor isolated jobs for simpler failure handling.
  • Keep templates, fonts and static images local when possible to reduce network variability.
  • Measure your own document sizes, page counts and concurrency in the target container before choosing limits.

Container checklist

  • Install the Chromium dependencies required by the Puppeteer build.
  • Allow the browser binary to be downloaded during the image build, or provide the supported executable configuration for your environment.
  • Run as a user with appropriate sandbox permissions; do not disable security controls without understanding the risk.
  • Allocate writable temporary storage for browser and PDF files.
  • Log the template name, page count when available, duration and error class, while excluding document secrets.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting common failures

“HTML is required” or an empty document error

Cause: the html property is missing, empty or the file read returned no content. Fix: check the file path, encoding and string length before calling pdf.create().

Missing data or Handlebars compilation errors

Cause: data was omitted, a variable has an invalid value, or template syntax is malformed. Fix: always pass an object, render a minimal template first, then add expressions and loops one at a time.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Path-related validation failure

Cause: file output was selected without a writable path. Fix: use an absolute or known-writable directory, create it before conversion and switch to buffer or stream output when a persistent file is unnecessary.

Chromium fails to launch in CI or a container

Cause: the browser download was skipped, required OS libraries are absent, or the runtime user cannot launch Chromium. Fix: inspect the Puppeteer install log, include the supported system dependencies, verify the executable exists in the image and test a one-page conversion inside the same runtime.

Images or fonts are missing

Cause: relative URLs cannot be resolved, files are inaccessible, or the page is captured before resources finish loading. Fix: configure the package’s base directory, use valid paths, check permissions and add the appropriate wait strategy.

PDF looks different from the browser

Cause: print media CSS, print margins, background-color adjustment or page breaking changes the layout. Fix: inspect @media print and @page, enable exact color adjustment where needed and test the generated PDF rather than relying on a screen preview.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Header or footer has no styling

Cause: Chromium renders the snippet separately. Fix: embed the required styles and font references in the header/footer markup and increase the corresponding margin.

Or skip the browser setup

If your requirement is simply “give me a clean PDF or screenshot of a URL,” ScreenshotNeo provides a website screenshot API and MCP server. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the page verdict and billing status in X-Page-Verdict and X-Billed headers.

For a PDF-oriented workflow, configure the PDF options documented at ScreenshotNeo’s documentation. A one-call request looks like this:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

ScreenshotNeo also offers an MCP server for AI agents, with take_screenshot, get_page_info and capture_pdf tools. Every plan includes features such as full-page capture with lazy images loaded, CSS-selector element capture, dark mode, device presets, custom viewport and retina scale, PDF paper and margin controls, custom CSS or JavaScript, click and wait actions, request blocking, headers and cookies, timezone and geolocation, transparent backgrounds, resizing, chosen-TTL caching, signed links, asynchronous jobs, webhooks, bulk capture of up to 100 URLs per call, a usage API and an OpenAPI specification.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; yearly billing provides two months free. Sign up for the free ScreenshotNeo plan and start without adding a card.

When to choose this package

Choose pdf-creator-node when your source is already HTML or a Handlebars view and browser-compatible CSS is important. It gives you Chromium’s layout engine and familiar web tooling, at the cost of a heavier install and browser-runtime operations. Choose a drawing-oriented library only when you need direct PDF primitives rather than HTML rendering; the package documentation names PDFKit and pdf-lib as alternatives, but the sources here do not establish a complete feature or performance comparison.

FAQ

Does pdf-creator-node support Node.js 18?

Yes. Node.js 18 or newer was the requirement stated on the npm package page accessed in 2026. Recheck the package listing for later releases.

Why does my PDF omit CSS backgrounds?

PDF generation uses print media and print-color behavior. Add print rules, request exact color adjustment where appropriate and verify the generated file.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Can I generate a PDF without writing a file?

Yes. The package documents buffer and stream output modes; use those when an HTTP response or pipeline is the destination.

Is Puppeteer included?

The package uses Puppeteer and headless Chromium. Puppeteer normally downloads a compatible browser during installation, which increases the install footprint.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.