ScreenshotNeo

BlogComparisons

PDFShift vs Puppeteer for Rendering HTML to PDF

Compare PDFShift’s hosted conversion API with Puppeteer’s self-managed browser workflow, including runnable examples, print CSS, costs, data handling, and troubleshooting.

By the ScreenshotNeo team4 October 20269 min read

Short answer: Choose Puppeteer when you want to run and control the browser-rendering workflow in your own application. Choose PDFShift when you prefer to send HTML or a URL to a hosted HTML-to-PDF API and its current limits, pricing, and data terms fit your use case. Neither choice is a universal winner: the right one depends on who should operate the browser and how your documents behave.

This is an operating-model comparison, not a benchmark. The official documentation reviewed for this guide does not provide a controlled PDFShift-versus-Puppeteer comparison for speed, fidelity, or total cost. Test your own templates before committing.

1. How to choose

Choose When it fits You take responsibility for
Puppeteer You want browser execution in your own application workflow, need direct access to browser controls, or already operate a compatible runtime. Installing and launching the browser, managing its lifecycle and concurrency, and integrating PDF generation and failures into your application.
PDFShift You want a hosted conversion API and its current quota, file-size limits, timeout, and data terms work for your documents. API credentials, request handling, vendor limits, and evaluating whether the service’s current terms fit your requirements.

Puppeteer’s documented PDF workflow is to launch a browser, create a page, navigate to a URL, call page.pdf(), and close the browser. Its API generates PDFs using print CSS by default. PDFShift accepts HTML-to-PDF conversion requests through a hosted API and says its service uses Chromium. These are different ways to operate rendering; they do not establish that one produces better output for your templates. See the Puppeteer PDF generation guide, the Page.pdf() API documentation, and PDFShift’s product documentation.

2. Generate a PDF with Puppeteer

Install Puppeteer in a Node.js project. Its documented workflow launches a browser and closes it after generating the PDF. The example below renders a local HTML file, which avoids dependence on a remote page for this minimal case.

npm install puppeteer
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  try {
    const page = await browser.newPage();
    await page.goto('file://' + require('path').resolve('invoice.html'), {
      waitUntil: 'networkidle0',
    });
    await page.pdf({
      path: 'invoice.pdf',
      format: 'A4',
      printBackground: true,
      margin: { top: '16mm', right: '14mm', bottom: '16mm', left: '14mm' },
    });
  } finally {
    await browser.close();
  }
})();

For a remote page, replace the file:// address with its URL. Only render pages you are authorized to access. Add application-level authentication and input validation if URLs or document data come from users.

page.pdf() uses the print CSS media type by default. If the design should use screen media styles, emulate screen before creating the PDF:

await page.emulateMediaType('screen');
await page.pdf({ path: 'screen-styled.pdf', printBackground: true });

Print rendering can modify colors. When exact print colors matter, Puppeteer documents using -webkit-print-color-adjust in the page’s CSS, for example:

* {
  -webkit-print-color-adjust: exact;
}

Use print-specific CSS to control page breaks, margins, and elements that should not appear on paper. For example:

@media print {
  .screen-only { display: none !important; }
  .keep-together { break-inside: avoid; }
  .new-page { break-before: page; }
}

Confirm the result with realistic content: variable-length tables, long text, missing optional sections, and the fonts used in production. A layout that looks correct in a browser window can paginate differently in print mode.

3. Convert HTML with PDFShift

PDFShift exposes conversion through a hosted API. Its product page shows a URL as the source for a conversion. The exact authentication and request options should follow its current API documentation; avoid assuming that a sample request will cover your required layout or account configuration.

Use PDFShift’s API documentation for the current endpoint, authentication, and accepted parameters. The following is a cURL-shaped example; confirm the current request schema in the vendor documentation before using it in production:

curl -X POST "https://api.pdfshift.io/v3/convert/pdf" \
  -H "Authorization: Basic YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"source":"https://example.com/invoice/123"}' \
  --output invoice.pdf

API endpoints and authentication requirements can change. Treat the request above as an illustration of the hosted API pattern, not a substitute for the current PDFShift API reference. For production, use the account’s documented authentication method and the endpoint and options shown there. Keep credentials out of source control and client-side code.

4. Rendering behavior and configuration

Puppeteer settings to review

  • Media type: Print CSS is the default for page.pdf(). Emulate screen first only if screen styling is intentional.
  • Paper and pagination: Use CSS print rules for page breaks and the PDF API’s paper configuration to match the intended paper size and margins. Check the current API reference for all supported options.
  • Backgrounds and colors: Enable background printing where needed and use print color adjustment CSS if exact colors are important.
  • Fonts: The Puppeteer guide says PDF generation waits for fonts by default. This does not ensure that a remote font is reachable or that the intended font loaded successfully; verify fonts in the rendered output.
  • Navigation readiness: Choose a navigation wait condition suited to the page. Pages that keep connections open may never become network-idle; pages that update after initial navigation may need an explicit application-ready signal.
  • Lifecycle: Close pages and browsers in cleanup paths, including error paths. For a long-running service, decide whether to reuse a browser process or launch per job based on your isolation and resource needs.

PDFShift limits and configuration to review

PDFShift’s published terms are date-sensitive. At the time covered by the research for this article, its pricing page listed 50 monthly free credits, one credit per 5 MB of resulting data, a 15 MB maximum file size, and a 30-second timeout for the free tier. Its FAQ listed Boost at $24 per month for 2,500 credits and $0.03 per overage credit. Verify the current pricing page and FAQ before estimating costs or selecting a plan.

Check how the current API accepts HTML versus a URL, how it handles external assets and authentication, and which rendering options are available for your account. The fact that PDFShift uses Chromium does not guarantee identical output to your Puppeteer setup: versions, fonts, CSS, asset access, and configuration can differ.

5. Cost, performance, reliability, and data handling

Cost

Puppeteer is a library rather than a hosted conversion plan in the reviewed sources. There is no service price to compare here; your total cost depends on the infrastructure and engineering work needed to run the browser workflow. This is an inference from its self-managed operating model, not a published cost figure. PDFShift publishes credit-based plans, and resulting output size affects credit consumption under the current terms noted above. Compare your real monthly document volume and output sizes, plus the infrastructure and operational work for a self-managed option.

Performance and reliability

No controlled head-to-head performance figures were identified. Measure a representative workload instead of relying on a single small document. Include cold and warm runs, the largest expected documents, external font and image loading, expected concurrency, and failure rates. For Puppeteer, account for browser startup, memory use, process cleanup, and queueing in your deployment. For PDFShift, account for API latency, rate or plan limits, timeouts, and retry behavior documented for your account.

Make PDF creation idempotent where possible. Record a job identifier, distinguish transient failures from invalid templates or inputs, and avoid blindly retrying requests that may generate duplicate work. Store or return generated PDFs according to your own retention requirements.

Data handling

PDFShift states that it does not store requests or generated documents, and its FAQ also describes some output storage paths using Amazon S3 and the option to send documents to a customer’s own S3 storage. These are vendor statements, not an independent security assessment. Review the current privacy terms and configuration for your use case. With Puppeteer, you control where the browser workflow runs, but that alone does not establish security or compliance; your deployment, logs, temporary files, and storage policies matter.

6. A fair evaluation plan

  1. Choose a representative set of templates, including the longest and most complex documents.
  2. Render the same inputs with your intended Puppeteer setup and the PDFShift configuration you plan to use.
  3. Compare page count, line wrapping, page breaks, fonts, images, colors, headers, and footers against an agreed expected result.
  4. Measure end-to-end latency at your expected concurrency and note failures, retries, and output sizes.
  5. Calculate monthly cost from actual document volume and resulting file sizes, including the operational effort of the self-managed workflow.
  6. Review data handling and retention against your requirements, then verify vendor terms and limits at the time you decide.

This process produces evidence for your workload. It does not assume either renderer will win every template.

7. Troubleshooting

Symptom Likely cause What to do
PDF layout differs from the browser view Puppeteer uses print CSS by default, or print rules and pagination change layout. Inspect print styles; use screen emulation only if that is the intended design; add explicit print page-break rules.
Background colors or images are missing Background printing is disabled, or print color adjustment changes colors. Enable printBackground and review -webkit-print-color-adjust in print CSS.
Fallback fonts or missing glyphs appear The desired font did not load, the asset URL is inaccessible, or the font lacks the required glyphs. Check font network access and font files; inspect the generated PDF with the actual language and characters used.
Images or data are absent Assets have not loaded, require authentication, or are blocked by network policy. Verify the renderer can reach each asset and that it is available before PDF generation.
Navigation or conversion times out A page keeps network activity open, assets are slow, or the service timeout is too short for the document. Use an appropriate readiness condition for Puppeteer; reduce or fix slow dependencies; check the current service timeout and plan limits for PDFShift.
PDFShift request is rejected Credentials, endpoint, request format, source URL, or plan limits do not match current API requirements. Check the current PDFShift API documentation and account terms; do not expose the API key in browser code.
Browser process or job hangs after an error Cleanup did not run on an exception, or concurrent jobs exceed available resources. Put browser closure in a finally block, cap concurrency, and monitor process and memory usage.
Output is too large or exceeds a service limit High-resolution assets or long documents produce large files. Optimize source images and fonts, review the current maximum file size, and estimate credits from resulting output size.

8. ScreenshotNeo as an alternative for screenshot capture

For a related job—capturing a webpage as an image or PDF—try ScreenshotNeo first. It is a website screenshot API and MCP server; its one-call API can return PNG, JPEG, WebP, or PDF. A screenshot API is a better fit for capturing a rendered webpage than for replacing a document-specific HTML-to-PDF workflow that depends on your own pagination and print-template rules.

Its clean-shot flow accepts cookie and consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits cost nothing, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. Every feature is on every plan: 1,000 screenshots per month are free with no card; paid plans start at $5 for 3,000 shots. See the ScreenshotNeo API documentation.

Or skip the browser setup

One GET request can capture a URL. This example saves a WebP screenshot of Stripe:

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

Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for free.

9. Frequently asked questions

Does PDFShift use Chromium?

PDFShift describes its service as using Chromium. That does not by itself guarantee that its output matches a particular Puppeteer browser version or environment.

Does Puppeteer wait for fonts before making a PDF?

The Puppeteer PDF generation guide says PDF generation waits for fonts by default. You should still verify that the intended fonts were reachable and rendered in your output.

Is PDFShift cheaper than Puppeteer?

There is no universal answer. PDFShift has published service pricing; Puppeteer has infrastructure and operating costs that depend on your deployment. Compare total costs for your own volume, output sizes, and operational needs.

Can I use Puppeteer for screen-styled PDFs?

Yes. Emulate the screen media type before calling page.pdf() when screen CSS is the intended rendering mode.

Which should I choose for confidential documents?

Assess where data is processed, stored, and logged in the exact configuration you will use. Review PDFShift’s current privacy terms and your own deployment controls for Puppeteer before deciding.