Compare Python PDF libraries¶
For HTML-to-PDF generation in Python, start with the source of the content. Playwright is useful when the document depends on JavaScript or a live browser page. Fullbleed and WeasyPrint accept static HTML/CSS for paginated documents such as invoices, statements, and reports. ReportLab offers Python drawing and document-layout APIs; pypdf works on existing PDFs.
This guide is maintained by Fullbleed. The choices below link to each project's documentation and to our retained comparison files, so you can evaluate the tradeoffs on your own documents.
Compare actual PDFs Run a Fullbleed invoice example
Choose by the job¶
| Your main task | Tools to evaluate | What to check |
|---|---|---|
| Generate invoices, statements, or reports from static HTML/CSS | Fullbleed, WeasyPrint | Page breaks, repeated table headings, fonts, and your actual CSS |
| Export a JavaScript application or a live web page | Playwright with Chromium | Page readiness, loaded fonts/images, and print styles |
| Build a document through Python drawing and layout primitives | ReportLab | Canvas/Platypus APIs and the layout code your team wants to own |
| Merge, split, crop, or extract text from existing PDFs | pypdf | The existing files' structures and the operations you need |
Playwright vs WeasyPrint for HTML to PDF¶
Playwright runs a browser. It can load an application, execute its JavaScript,
and print the resulting page through Chromium. Its page.pdf() API
uses print CSS by default; background graphics and preference for CSS page size
are explicit options. For an application-generated chart, arrange a readiness
signal for the completed chart and fonts before printing.
WeasyPrint lays out static documents. Its pagination engine is independent of a browser, and its documented scope excludes JavaScript. Generate the HTML and chart images before rendering. This is a useful model for server templates whose final content is already known.
Fullbleed also renders static documents, using a Rust print engine with Python bindings. It adds explicit asset registration, structured diagnostics, PNG previews, and compiled document workflows. It does not execute your page's JavaScript. Check its CSS coverage and your page breaks before moving an existing template.
What you deploy¶
| Renderer | Runtime to provision | First integration check |
|---|---|---|
| Fullbleed | Python and a published wheel, which bundles the engine and fonts | Confirm your Python/platform has a wheel; register your brand fonts and images |
| WeasyPrint | Python, its Python packages, and platform libraries including Pango | Follow the installation instructions for your host and verify font discovery |
| Playwright | Python package, the matching Chromium binary and system dependencies | Verify browser startup, asset loading, and PDF generation in the deployment image |
Using the same HTML in all three does not guarantee the same line or page breaks. Include a long table, an unusually long name, and the final record of your largest document in the first evaluation.
Inspect the same invoice in three renderers¶
These unmodified previews come from the retained October 5, 2026 comparison: Fullbleed 2.5.6, WeasyPrint 70.0, and Playwright 1.63.0 with Chromium 153.0.8010.12. Each received the same HTML/CSS, Inter font, and synthetic records. Select an image to open its actual one-page PDF.
The complete comparison includes a longer ledger and report, the input source, output checks, timings, memory samples, and all 414 generated PDFs. The ledger occupies three pages in Fullbleed and WeasyPrint, and four in Chromium. That difference is included in the results.
The timings describe those versions and fixtures on one host. The results favor different tools for different measurements; they do not establish a universal speed or quality ranking. These previews are historical evidence, not newly generated samples of the latest releases.
When Fullbleed is a useful fit¶
Fullbleed is useful when your application owns the document template, input data, and assets, and needs repeatable print output. Its Python package has no required third-party Python runtime dependencies. Its compiled fixed and reflowing binding APIs support repeated document families, such as monthly statements. The engine is MIT licensed.
Start with the integration closest to your application:
- Python invoice from structured data, with editable HTML/CSS.
- FastAPI, Flask, or Django PDF endpoint, with a downloadable project.
- Docker deployment or AWS Lambda, with explicit runtime requirements.
- Variable-data documents, for compiled fixed and reflowing workflows.
For the current CSS evidence, browse all 1,662 fixtures from the published Fullbleed 2.5.22 Linux wheel. The recorded results include 25 FAIL and 18 REFERENCE-DISPUTED cases; the unchanged upstream gate fails. Inspect the relevant cases and test your own templates. A CSS comparison does not establish PDF/A, PDF/UA, or PDF/X conformance.
Other projects' documented scope¶
- ReportLab exposes Python PDF generation and document-layout APIs. Evaluate it when you want to build the layout through Python rather than an HTML/CSS template.
- pypdf supports operations on existing PDFs, including transformations, merging, splitting, and text or metadata extraction. It can be a separate step after document generation.
The linked third-party descriptions were reviewed on October 14, 2026. Consult each project's current documentation and license before adopting it.
A practical migration check¶
- Define the output contract. Choose representative documents and expected record IDs, values, totals, page dimensions, and required metadata.
- Pin the inputs. Record engine versions and the exact font/image files. Match margins, headers, and footers before judging differences.
- Inspect the longest document. Compare page images and extracted content. Check that every record appears once, in order, and that the final row and closing notes are present.
- Validate required profiles. For accessible, archival, or print output, run the relevant validators on the final PDFs and retain the reports. Visual similarity alone is insufficient.
- Measure complete jobs. Include startup, font and asset setup, rendering, and file writes. Test a reused process separately from a fresh process and retain failures as well as successful outputs.
Use the shared-input comparison harness as a starting point for your own acceptance contract. For Fullbleed projects, the PDF regression starter provides a runnable CI example.


