The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →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 html-pdf-node‘s generatePdfs(files, options) method. Pass an array containing HTML content strings or public url values, await the returned promise, then write each returned PDF buffer to a filename you control. One shared options object sets paper size, margins, CSS page sizing, page ranges, orientation, backgrounds and Chromium flags for the whole batch.
Install html-pdf-node and prepare the output directory
Install the package in a Node.js project:
npm install html-pdf-node
The package wraps a Chromium-based renderer. Your deployment therefore needs a compatible browser installation and permission to launch it. If you convert URLs, the renderer also needs network access to those pages. The package README documents version 1.0.8 on npm’s 2026 page; package metadata and download counts can change, so verify them before locking a production dependency.
mkdir -p out
Use stable names in your input records. The name property is an application-level identifier that lets you match each returned buffer to its source; it is not a promise that the library will write the file for you.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallGenerate a batch from HTML strings and URLs
This complete CommonJS example creates two invoices from inline HTML and one report from a public URL. It passes one options object to every document, checks that the result count matches the input count, and writes each buffer independently.
#1 Best Overall
const htmlToPdf = require('html-pdf-node');
const fs = require('node:fs/promises');
const files = [
{
content: `<!doctype html>
<html><head><meta charset="utf-8">
<style>body{font-family:Arial,sans-serif} h1{color:#174a7e}</style>
</head><body><h1>Invoice 1001</h1><p>Alice</p></body></html>`,
name: 'invoice-1001.pdf'
},
{
content: '<h1>Invoice 1002</h1><p>Bob</p>',
name: 'invoice-1002.pdf'
},
{
url: 'https://example.com/report',
name: 'report.pdf'
}
];
const options = {
format: 'A4',
printBackground: true,
margin: { top: '12mm', right: '12mm', bottom: '12mm', left: '12mm' },
path: false
};
async function run() {
await fs.mkdir('./out', { recursive: true });
const results = await htmlToPdf.generatePdfs(files, options);
if (results.length !== files.length) {
throw new Error(`Expected ${files.length} PDFs, received ${results.length}`);
}
await Promise.all(results.map(async ({ name, buffer }, index) => {
if (!Buffer.isBuffer(buffer)) {
throw new TypeError(`Result ${index} did not contain a PDF buffer`);
}
const safeName = files[index].name || name;
await fs.writeFile(`./out/${safeName}`, buffer);
}));
console.log(`Wrote ${results.length} PDFs to ./out`);
}
run().catch(error => {
console.error(error);
process.exitCode = 1;
});
The repository documents generatePdfs(files, options) as a promise that resolves to an array of objects containing PDF buffers. In practice, keep the input order and your own IDs so a result can never be assigned to the wrong customer or report. See the html-pdf-node README for the documented API.
Understand the input and returned output
HTML content entries
Use { content: '<h1>…</h1>', name: 'file.pdf' } when your application already rendered a document. Include a complete HTML document when you need a <head>, embedded fonts, print styles or page rules. Inline assets avoid a second network dependency; external assets must be reachable by Chromium.
URL entries
Use { url: 'https://your-site.example/report', name: 'report.pdf' } for a publicly reachable page. Authentication, robots rules, slow APIs and client-side rendering can affect the result. The README documents URL input but does not publish a wait strategy or timeout contract, so make the page deterministic before calling the batch API and test slow pages in your own environment.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Buffer persistence
Each returned object includes a PDF buffer. Save it with fs.writeFile, stream it to object storage, or send it in an HTTP response. The explicit buffer workflow gives you per-file validation and naming. The path option is documented as the file-path setting, but returned buffers are the clearer choice when every input needs a distinct destination and error handling.
Set paper size, margins and page selection
All documents in a call share the options object. The main controls are:
Rank #2
| Option | Use | Important behavior |
|---|---|---|
format |
Named paper such as 'A4' |
The README says the default is Letter. Set A4 explicitly when that is your required standard. |
width, height |
Custom paper dimensions | Supply units such as 210mm or 8.5in. A set format takes priority over these dimensions. |
margin |
Printable whitespace | Set top, right, bottom and left, each with a unit. |
pageRanges |
Select pages | Examples include 1-5, 8, 11-13. An empty value means all pages. |
preferCSSPageSize |
Honor CSS page rules | When true, CSS @page size takes priority over width, height or format. |
printBackground |
Include background graphics | The documented default is false; set true for colored panels, backgrounds and many charts. |
landscape |
Rotate orientation | The documented default is false (portrait). |
A4 with CSS-controlled page size
const options = {
format: 'A4',
preferCSSPageSize: true,
printBackground: true,
margin: { top: '15mm', right: '15mm', bottom: '15mm', left: '15mm' }
};
With preferCSSPageSize enabled, put rules such as @page { size: A4 landscape; margin: 12mm; } in the document’s stylesheet. Without it, the JavaScript paper settings control the page.
Custom dimensions and page ranges
const options = {
width: '210mm',
height: '297mm',
pageRanges: '1-5, 8, 11-13',
printBackground: true
};
Do not set a conflicting format when custom dimensions must win; the documented precedence gives format priority. Page ranges are applied to each generated PDF, not to the batch as a whole.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Control Chromium arguments safely
The args option passes additional Chromium flags. The README shows --no-sandbox and --disable-setuid-sandbox as defaults:
const options = {
format: 'A4',
args: ['--no-sandbox', '--disable-setuid-sandbox']
};
Changing sandbox flags changes the browser’s security posture. Review the container, operating-system user and deployment policy before removing or adding flags. A local success does not prove that a locked-down production container can launch Chromium.
Build a reliable batch pipeline
- Render each source. Produce deterministic HTML or verify that every URL is reachable from the worker.
- Assign a stable name. Keep a database ID separate from the filename and sanitize names before writing to disk.
- Use shared options. Put paper, margin and browser settings in one object so every output follows the same print policy.
- Await the promise. Do not read a buffer before
generatePdfsresolves. - Validate cardinality and type. Confirm one result per input and that every result has a buffer.
- Persist with isolation. Write each file to a controlled directory or object-storage key; record failures with the input ID.
The package publishes no throughput or concurrency benchmark. Measure rendering time, memory use, browser startup cost and failure rate with your real templates. For large workloads, queue jobs, cap concurrent batches according to available CPU and memory, and retry only transient URL or infrastructure failures. Retrying malformed HTML or an inaccessible page will not fix the cause.
Rank #3
Troubleshoot common failures
“Cannot find module ‘html-pdf-node’”
Run npm install html-pdf-node in the project that executes the script, then check that the same Node.js environment runs it. A global install does not satisfy a local dependency reliably.
Free tools Windows power users keep installed
One-click scans. No signup required.
Chromium fails to launch in a container
Confirm that the package’s browser dependency is installed and executable by the service user. Review the documented sandbox arguments and your container security policy; do not blindly disable protections in a multi-tenant environment.
The PDF is blank or missing styles
For inline content, include a valid HTML document and embed or expose required assets. Set printBackground: true for backgrounds. For URLs, test the page from the same network, wait until server-rendered content is available, and avoid relying on an undocumented readiness timeout.
Remote images or fonts do not appear
Check HTTPS access, DNS, certificate validity and cross-origin restrictions from the renderer. Prefer absolute URLs or inline assets, and ensure the URL is not protected by an interactive login.
Output names are wrong or files are overwritten
Do not use a shared literal filename. Give every input a unique name, map results by index or an external ID, sanitize path separators, and write to a directory created for the job.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesRank #4
Only selected pages are present
Inspect pageRanges. An empty value means all pages; a range such as 1-5, 8, 11-13 intentionally omits other pages.
A custom size is ignored
Remove format when using width and height, or set preferCSSPageSize: true if the CSS @page rule should control the size.
Or skip the browser setup
ScreenshotNeo provides a website screenshot and PDF API when your input is a URL rather than locally generated HTML. One GET request returns a PNG, JPEG, WebP or PDF. Before capture it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups and chat widgets; bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients.
Read the complete parameter list in the ScreenshotNeo API documentation. The one-call example below targets a PDF-producing endpoint; change the URL to your page and use the returned file as needed:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
For applications that need explicit PDF output, request the documented PDF option for your endpoint configuration. The service also supports full-page capture with lazy images loaded, CSS-selector element capture, dark mode, device presets and arbitrary viewports, retina scale, custom CSS and JavaScript, clicks, selector or network-idle waits, request blocking, headers, cookies, user agents, authorization, timezone and geolocation, transparent backgrounds, resizing, chosen-TTL caching, signed links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API and an OpenAPI specification. Parameter names used by other screenshot APIs are accepted to ease migration.
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`ScreenshotNeo HTTP ${res.status}`);
const bytes = Buffer.from(await res.arrayBuffer());
ScreenshotNeo’s Free plan includes 1,000 screenshots per month without a card. Paid plans start at $5 for 3,000 shots; every feature is on every plan, and yearly billing gives two months free. Create a free ScreenshotNeo account to try the URL workflow.
FAQ
Does generatePdfs write files automatically?
It resolves with objects containing PDF buffers. Your application decides filenames and storage; writing the buffers explicitly is the predictable batch pattern.
Can one batch mix HTML and URLs?
Yes. Each array entry can provide either a public url or an HTML content string, so the example can combine both sources.
Is there an official throughput limit?
The package documentation publishes no throughput or concurrency benchmark. Establish capacity with representative documents and your own browser-hosting environment.
Frequently Asked Questions
Does generatePdfs write files automatically?
It resolves with objects containing PDF buffers. Your application decides filenames and storage; writing the buffers explicitly is the predictable batch pattern.
Can one batch mix HTML and URLs?
Yes. Each array entry can provide either a public url or an HTML content string, so a batch can combine both sources.
Is there an official throughput limit?
The package documentation publishes no throughput or concurrency benchmark; measure capacity with representative documents in your own environment.
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.

