Four ways to turn HTML code into a PDF
To generate a PDF from HTML code, pass the HTML to a rendering engine and ask it for a PDF. The engine is either a headless browser (Puppeteer, or Gotenberg which wraps Chromium), a dedicated HTML-to-PDF library (WeasyPrint) or a hosted API that runs one of these for you.
| Route | Language | Runs JavaScript in the page | What you install |
|---|---|---|---|
| Puppeteer | Node.js | Yes, it is Chrome | An npm package plus a Chrome download |
| WeasyPrint | Python or command line | Not a browser; choose it for static HTML and CSS | A pip package plus the Pango system library |
| Gotenberg | Any, over HTTP | Yes, it uses headless Chromium | A Docker container |
| Hosted API | Any, over HTTP | Depends on the service | Nothing |
If the HTML does not exist yet and you really want to fill a layout with data, a template route is the better starting point.
Puppeteer: the documented steps
Prerequisites. Node.js, and room for the Chrome for Testing build that Puppeteer downloads on install, which is roughly 170 to 282 MB depending on the operating system.
- Install:
npm i puppeteer - Launch the browser:
const browser = await puppeteer.launch(); - Open a page:
const page = await browser.newPage(); - Load your HTML string:
await page.setContent(html); - Create the PDF:
await page.pdf({ path: 'out.pdf', printBackground: true }); - Close:
await browser.close();
To convert a live URL instead of a string, the Puppeteer guide uses await page.goto(url, { waitUntil: 'networkidle2' }) in place of step 4. By default page.pdf() waits for fonts to load and times out after 30 seconds.
WeasyPrint and Gotenberg: the same job without Node.js
WeasyPrint is the shortest route in Python. Version 70.0 needs Python 3.10 or later and Pango 1.44 or later.
- Install:
pip install weasyprint - Import:
from weasyprint import HTML - Convert a string:
HTML(string=html).write_pdf("out.pdf") - Or convert a file:
HTML(filename="page.html").write_pdf("out.pdf")
There is also a command line form. The documentation's example is weasyprint https://weasyprint.org /tmp/weasyprint-website.pdf: input first, output second.
Gotenberg gives every language the browser route over HTTP.
- Start it:
docker run --rm -p "3000:3000" gotenberg/gotenberg:8 - Save your HTML as a file named
index.html. The name is required. - Convert:
curl --request POST http://localhost:3000/forms/chromium/convert/html --form files=@/path/to/index.html -o my.pdf
Hosted APIs: one request, nothing to install
If you cannot run Chrome or Docker, a hosted API accepts the same HTML in a POST request. Three with public documentation:
- DocRaptor: POST JSON to
https://api.docraptor.com/docswith"type": "pdf"and"document_content": "<html>...</html>". Adding"test": truemakes a free, watermarked document. - PDFShift: POST JSON to
https://api.pdfshift.io/v3/convert/pdfwithsourceset to your HTML or a URL, and the key in theX-API-Keyheader. - Api2Pdf: POST
{"html": "<h1>Hello World</h1>"}tohttps://v2.api2pdf.com/chrome/pdf/htmlwith the key in theAuthorizationheader.
Free allowances and entry prices for these are in the HTML to PDF API comparison. For a few hundred documents a month on a server you already run, the free routes above are enough.
Worked example: a two-page report with a header band
The HTML has a dark header band, a summary paragraph and a 60-row table. With Puppeteer, call page.pdf({ path: 'report.pdf', printBackground: true }). The format option defaults to letter, so a US audience needs no size setting, and the margin option sets page margins. Add displayHeaderFooter: true and a footerTemplate containing an element with the class pageNumber to print page numbers.
With WeasyPrint the same result comes from CSS alone: an @page rule sets size and margins, as in the documentation's @page { size: A3; margin: 1cm } example with your own values.
A mistake to avoid: expecting the PDF to match the screen
PDF renderers print; they do not screenshot. Puppeteer's documentation states that page.pdf() uses the print CSS media type, that printBackground is false by default, and that colors may be modified for printing. So the header band above disappears until you set printBackground: true, and any @media print rules in your stylesheet apply. Call page.emulateMediaType('screen') before page.pdf() if you want screen styles.
The second mistake is security. Both the WeasyPrint documentation and the wkhtmltopdf status page warn against rendering untrusted HTML. If users can supply markup, sanitize it and isolate the renderer.
The third is long tables splitting badly across pages; the page breaks guide covers the CSS. For template-driven versions of these steps, see the Node.js and Python guides.
Sources used for this page
The facts above come from the pages below, read on 3 October 2026. We have not used these products hands-on. Prices and terms change, so confirm them on the vendor's site before you buy.
- Installation | Puppeteer — Vendor documentation · pptr.dev · checked 2026-10-03
- PDF generation | Puppeteer — Vendor documentation · pptr.dev · checked 2026-10-03
- Page.setContent() method | Puppeteer — Vendor documentation · pptr.dev · checked 2026-10-03
- Page.pdf() method | Puppeteer — Vendor documentation · pptr.dev · checked 2026-10-03
- PDFOptions interface | Puppeteer — Vendor documentation · pptr.dev · checked 2026-10-03
- First Steps - WeasyPrint documentation — Vendor documentation · doc.courtbouillon.org · checked 2026-10-03
- Installation | Gotenberg — Vendor documentation · gotenberg.dev · checked 2026-10-03
- Convert HTML to PDF | Gotenberg — Vendor documentation · gotenberg.dev · checked 2026-10-03
- DocRaptor API documentation: overview and parameters — Vendor documentation · docraptor.com · checked 2026-10-03
- Convert to PDF - PDFShift API Documentation — Vendor documentation · docs.pdfshift.io · checked 2026-10-03
- Authentication - PDFShift API Documentation — Vendor documentation · docs.pdfshift.io · checked 2026-10-03
- API2PDF home page with starter requests — Vendor product page · api2pdf.com · checked 2026-10-03
- wkhtmltopdf project status — Vendor documentation · wkhtmltopdf.org · checked 2026-10-03