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.

For HTML that needs browser-accurate CSS layout, use a headless browser from Node.js: load the page, generate a PDF with its PDF API, and close the browser. Puppeteer and Playwright both use print CSS media by default; both can be switched to screen media before generating the PDF. Choose PDFKit instead when you want to construct PDF content programmatically, not render an existing HTML page.

Choose the right Node.js approach

The key distinction is whether your input is a web page or a document you want to build from drawing and text operations. A headless browser renders HTML and CSS using browser layout, making it the natural fit for existing pages, templates, and browser-dependent styling. Puppeteer and Playwright both expose a page-level PDF method.

Approach Best fit What the documented workflow establishes
Puppeteer Rendering a URL or page in a browser and saving its PDF. Launch a browser, create a page, navigate, call page.pdf(), then close the browser. PDF generation uses print CSS media by default.
Playwright Browser rendering where you want Playwright’s page API and PDF buffer workflow. page.pdf() returns a PDF buffer and uses print CSS media by default. Paper formats such as Letter and A4, or width and height in px, in, cm, or mm, are documented.
PDFKit Building a PDF programmatically rather than rendering a web page. The official guide describes creating a PDFDocument and piping it to a writable Node stream; that guide does not establish HTML rendering.

The browser libraries require a browser runtime as well as Node.js. The cited documentation does not establish one universal deployment recipe or infrastructure requirement: verify browser installation and runtime compatibility for the specific environment where you deploy.

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.

Convert a URL to PDF with Puppeteer

Install Puppeteer in your project using its package manager, then create a file such as url-to-pdf.js. The basic flow below follows Puppeteer’s documented pattern: navigate to a URL, write the PDF to a path, and close the browser.

#1 Best Overall
Epson EcoTank ET-2800 Wireless Color All-in-One Supertank Printer - Black
  • INNOVATIVE CARTRIDGE-FREE PRINTING — No more dealing with lots of tiny ink cartridges; With this wireless document and photo printer each ink bottle set is equivalent to about 90 individual cartridges²
  • LESS FREQUENT INK REPLACEMENT — Replacement ink bottles don't have to be changed nearly as often as ink cartridges¹; When you choose this combination printer, scanner and copier you can print up to 4,500 pages black/7,500 color³
  • COLOR PRINTING — Up to 2 years of ink in the box4 (and with every replacement ink set) for fewer out-of-ink frustrations
  • ZERO CARTRIDGE WASTE — By using an Epson EcoTank printer you can help reduce the amount of cartridge waste ending up in landfills
  • HOME PRINTER DESIGNED FOR RELIABILITY — The Epson EcoTank ET-2800 All-in-One Supertank Color Printer creates vivid, detailed prints and documents thanks to Micro Piezo Heat-Free Technology; Fire off 10 ISO pages per minute1 to easily finish large jobs
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();

  try {
    const page = await browser.newPage();
    await page.goto('https://example.com');
    await page.pdf({ path: 'page.pdf' });
  } finally {
    await browser.close();
  }
})();

Run it with node url-to-pdf.js. If navigation and PDF generation complete, the resulting file is page.pdf in the current working directory. Replace the example URL with the page you need to capture and choose a destination path appropriate for your application.

The finally block ensures the browser is closed even if navigation or PDF generation throws an error. This matters for scripts that run repeatedly or inside a service: leaving browser processes open can consume resources and interfere with later jobs.

Render screen media instead of print media

Puppeteer documents that page.pdf() renders using print CSS media by default. If the page’s screen stylesheet is the desired output, set the media type before creating the PDF:

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.
await page.emulateMediaType('screen');
await page.pdf({ path: 'page.pdf' });

Put these calls after the page has loaded and before page.pdf(). This changes which media styles apply; it does not mean a PDF is a screenshot of the browser window. Decide whether the document should follow print rules or screen rules, then test the resulting layout with the actual page.

Preserve print colors when needed

Puppeteer’s documentation says PDF output adjusts colors for printing by default. If exact CSS colors matter, it documents the CSS property -webkit-print-color-adjust for retaining them. Apply it in the page’s print styles, for example:

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

Use this only when the print color adjustment is not wanted; color fidelity can affect readability and ink use. Confirm the result in the generated PDF rather than assuming the browser’s on-screen appearance will be identical.

Rank #2
Sale
Epson EcoTank Photo ET-8550 Wireless Wide-Format All-in-One Tank Printer
  • CARTRIDGE-FREE PRINTING — Print lab-quality photos, graphics and creative projects; Get vibrant colors and sharp text with Epson's high-accuracy printhead and Claria ET Premium 6-color inks
  • INK BOTTLES — Save on photos1 and creative projects with affordable in-house printing; All-in-one printer allows you to print 4" x 6" photos for about 4 cents each vs. 40 cents with traditional ink cartridges1
  • LESS FREQUENT INK REPLACEMENT — Replacement ink bottles don't have to be changed nearly as often as ink cartridges¹; Printer, scanner and copier lets you print up to 6,200 color pages³
  • PRINT FOR LONGER — Up to 2 years of ink in the box² (and with every replacement ink set) for fewer out-of-ink frustrations with this wireless printer
  • ZERO CARTRIDGE WASTE — Epson EcoTank printer helps reduce the amount of cartridge waste ending up in landfills; Cartridge-free printer uses high-yield ink bottles; Each replacement ink bottle set is equivalent to about 100 individual ink cartridges⁴

Use Playwright when its API fits better

Playwright’s page.pdf() returns a PDF buffer. That is useful when the application needs to handle the bytes itself rather than having the PDF API write directly to a named path. This runnable CommonJS example writes the buffer to a file using Node’s filesystem API:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const { chromium } = require('playwright');
const fs = require('node:fs/promises');

(async () => {
  const browser = await chromium.launch();

  try {
    const page = await browser.newPage();
    await page.goto('https://example.com');
    const pdf = await page.pdf({ format: 'A4' });
    await fs.writeFile('page.pdf', pdf);
  } finally {
    await browser.close();
  }
})();

Playwright documents Letter and A4 paper formats, and dimensions can be specified in px, in, cm, or mm. The example selects A4; change the format or set dimensions when your document needs another page size. Playwright also uses print CSS media by default. To render screen media, call page.emulateMedia({ media: 'screen' }) before generating the PDF:

await page.emulateMedia({ media: 'screen' });
const pdf = await page.pdf({ format: 'A4' });

Use the same browser-lifecycle discipline as in the Puppeteer example: close the browser after the PDF is generated, including when a step fails. Choose between Puppeteer and Playwright based on the browser automation API already used by your project and the way you want to handle PDF output; the documented facts here do not establish that one is universally faster or easier to deploy.

Render HTML you already have

If the source is an HTML string rather than a URL, put that content into a browser page before calling its PDF method. The following Puppeteer example uses a small self-contained document:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();

  try {
    const page = await browser.newPage();
    await page.setContent(`
      <!doctype html>
      <html>
        <head>
          <meta charset="utf-8">
          <title>Report</title>
          <style>
            body { font: 16px Arial, sans-serif; margin: 2rem; }
            h1 { color: #17365d; }
            @media print {
              html { -webkit-print-color-adjust: exact; }
            }
          </style>
        </head>
        <body>
          <h1>Monthly report</h1>
          <p>This content is rendered by a browser before PDF creation.</p>
        </body>
      </html>
    `);

    await page.pdf({ path: 'report.pdf' });
  } finally {
    await browser.close();
  }
})();

For a real application, make sure the page content includes the styles and assets it needs. When HTML refers to external images, stylesheets, or fonts, the browser must be able to load them for the rendered document to include them. Puppeteer’s guide says page.pdf() waits for fonts by default; that does not guarantee every other external dependency has loaded successfully.

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

Choose print layout, page size, and output behavior

Print CSS versus screen CSS

  • Use print media when the page has print-specific rules or should follow its print layout. This is the default for both libraries’ documented PDF methods.
  • Use screen media when the screen stylesheet is the intended design. Set the media type before calling the PDF method.
  • Check color-sensitive pages because Puppeteer documents print-oriented color adjustment by default and a CSS control for retaining exact colors.

Paper format and dimensions

Playwright’s documentation explicitly describes paper formats including Letter and A4, and custom width and height in px, inches, centimeters, or millimeters. Select the format based on the intended reader and use case; do not assume a page designed for a wide screen will fit a portrait sheet without layout changes. For Puppeteer, consult the API documentation for the exact PDF options supported by the version installed in your project; the basic example above intentionally uses only the documented path workflow.

Rank #3
HP Smart Tank 5000 Wireless All-in-One Ink Tank Printer, Scanner, Copier with 2 Years of Ink Included, Best-for-Home, Cartridge-Free, Refillable and AI-Enabled. (5D1B6A)
  • SET IT UP ONCE AND PRINT WITH CONFIDENCE. No complicated maintenance. Just easy, reliable printing you can count on.
  • INK FOR YEARS. NOT MONTHS. Up to 2 years of ink included. Get thousands of pages of cartridge-free printing. More pages, less hassle
  • KEEPS PRINTING WELL AFTER COMPETITORS HAVE QUIT. No complex maintenance. Sharper text, richer colors.[2] Only with HP Smart Tank
  • PREMIUM SUPPORT - Strong technical expertise to solve issues faster
  • THE LAST PRINTER YOU'LL EVER NEED. Enjoy years of refillable, cartridge-free printing.

Saving to disk or handling bytes

Puppeteer’s basic documented example passes a path to page.pdf(). Playwright returns a PDF buffer, which can be written to a file, streamed onward by application code, or otherwise handled as bytes. Choose the output flow that suits the rest of your Node.js application instead of creating an unnecessary intermediate file.

Where PDFKit fits

PDFKit is a PDF-generation library, but the cited official guide establishes a different workflow from browser rendering: create a PDFDocument and pipe it to a writable stream. That is a good conceptual fit when your application constructs the PDF from programmatic content and does not need a browser to interpret HTML and CSS. Do not treat it as a drop-in HTML-to-PDF renderer based on that guide alone.

Or skip the browser setup

If your input is a public webpage and you do not want to manage browser automation in your Node service, ScreenshotNeo offers a website screenshot API that can also return PDFs. Its API and PDF options are documented at ScreenshotNeo docs. The supplied one-request example saves a screenshot image; consult the docs for the PDF response format and request options rather than assuming an undocumented parameter.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo accepts cookie or consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies page verdict and billing status in headers. An MCP server exposes screenshot and PDF tools to AI agents. The free plan includes 1,000 shots per month with no card, and paid plans start at $5 for 3,000. Sign up for 1,000 free screenshots a month, with no card.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting common failures

The PDF uses unexpected styling

Check whether the page’s print stylesheet differs from its screen stylesheet. Both browser PDF methods use print media by default; explicitly emulate screen media before generating if that is the intended output. Also inspect print-specific CSS that hides or rearranges elements.

Colors differ from the browser view

Puppeteer documents that PDF output adjusts colors for printing by default. If exact colors are required, apply -webkit-print-color-adjust: exact in the relevant CSS and inspect the generated PDF. This adjustment is specific to the print rendering behavior documented by Puppeteer.

Fonts or images are missing

Confirm that the assets are available to the browser and that URLs resolve from the machine running the script. Puppeteer says its PDF method waits for fonts by default, but that is not a general guarantee that remote resources load. Check the source page or HTML, network access, and the generated document for missing dependencies.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
NDYIN Portable Printers Wireless for Travel, N80 Bluetooth Thermal Printer
  • Wireless Bluetooth Printer: Portable thermal printer compatible with iPhone, Android phones, iPad and tablet computers via Bluetooth. For smartphones, please download the "Nada Print" App. You can also connect to laptops and computers for printing using a USB-C cable. (Note: Laptops and computers can only be connected via USB and require the installation of a driver first. Bluetooth connection is not supported.)
  • No-ink printing: Only supports US Letter and A4 size thermal paper.(Doesn't support regular paper) The no-ink portable thermal printer uses direct thermal technology, requiring no ink, toner or ribbons, making it environmentally friendly, cost-effective and time-saving. The thermal printer package comes with a roll of US Letter thermal printing paper. Note: When installing the paper, remember to switch the paper size switch on APP
  • Clear Print: NDYIN N80 portable thermal printer adopts high-definition printing technology, with a 203DPI resolution to provide you with clear printing results. This mobile printer is compatible with roll paper, folded paper and tattoo transfer paper, supporting printing from your mobile phone PDF, Word, pictures and web pages anytime and anywhere. It is recommended to use our NDYIN thermal paper to achieve good printing quality
  • Portable wireless printer for travel: The thermal printer is equipped with a built-in 1500mAh rechargeable battery, which can print 160 sheets of 8.5" x 11" thermal paper after being fully charged. It weighs only 1.5 pounds and is compact in size. This ink-free portable printer can be easily carried in a backpack or briefcase! It is perfect for business travel, cars, small offices, construction sites, schools and homes. You can print documents, contracts, invoices and boarding passes anytime and anywhere
  • The N80 thermal printer has a wide range of uses. The package includes the N80 printer, a roll of US Letter paper(7m/roll), a user manual, a guide card, a type-C soft cable and a type C adapter. Note: The charging adapter is not included. Special thermal paper is required for use; ordinary paper cannot be used. This ink-free portable thermal printer is suitable for various scenarios such as home, school, travel, office, and outdoor, meeting the printing needs of different groups of people. This tattoo template printer is also compatible with tattoo transfer paper, making it an ideal choice for tattoo art

The process hangs or consumes resources over repeated jobs

Ensure browser closure runs on both success and error paths. The examples use try/finally for that reason. If navigation itself does not complete in your environment, investigate the page and runtime rather than assuming the PDF method is responsible; the cited documentation does not establish a universal timeout or deployment configuration.

The script cannot launch a browser in production

A headless-browser solution requires both Node.js and a usable browser runtime. Check the chosen library’s official installation instructions and your deployment environment’s browser compatibility. The documentation summarized here does not specify a provider, resource size, or security configuration that applies to every deployment.

Performance, reliability, and cost considerations

Browser rendering is appropriate when layout fidelity to HTML/CSS is more important than avoiding a browser dependency. The cost is operational: the application must launch or manage a browser and ensure the runtime is available where code executes. Reuse patterns, concurrency limits, memory needs, and exact performance depend on the application and environment; the cited documentation does not provide benchmarks, service-level guarantees, or a universal resource estimate.

For reliable jobs, treat navigation, resource availability, PDF generation, output persistence, and browser cleanup as separate failure points. Log the failing stage and retain enough context to identify the URL or input document. Do not report a successful conversion until the PDF bytes have been written or handed to the next stage successfully.

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

Frequently Asked Questions

Does Puppeteer create a PDF using print CSS or screen CSS?

Print CSS by default. Call page.emulateMediaType('screen') before page.pdf() to use screen media.

Does Playwright write a PDF file directly?

Its page.pdf() method returns a PDF buffer. The example writes that buffer with Node’s filesystem API.

Is PDFKit an HTML-to-PDF library?

The cited PDFKit guide establishes programmatic PDF creation and stream output, not HTML rendering.

Quick Recap

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.

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