Every one of these has a real use case. None of them is the right answer for everything, and the fastest way to waste a week is picking one because it topped a search result rather than because it fits what you are building.
**jsPDF** runs entirely in the browser, no server round trip. That is its whole appeal: forms, receipts, simple reports, anything where the layout is simple enough to describe in code. The tradeoff shows up the moment you need a non-Latin script or a complex multi-column layout. Embedding a custom font means fetching a TrueType file and calling addFont yourself, and if that font happens to be OTF or WOFF instead of a real TTF, jsPDF fails silently rather than throwing, so the text just does not appear and nothing in your console tells you why. We know this one specifically because we hit it building our own text-to-PDF tool.
**Puppeteer** drives a real headless Chrome instance and prints whatever you point it at, which means it renders CSS, web fonts and JavaScript-heavy pages exactly as a browser would, because it is a browser. The cost is real too: a Chrome install is 200MB or more, cold starts on serverless platforms are slow enough to matter, and running it at any volume means managing a browser process, not calling a library.
**wkhtmltopdf** converts HTML using an older WebKit build and has not seen meaningful maintenance in years. It still works for basic HTML, and a lot of legacy systems still depend on it, but it does not support modern CSS well and the project's own documentation now points people elsewhere. If you are starting something new, this is a tool to migrate away from, not toward.
**pdf-lib** is not a generator so much as a PDF editor: add pages, embed fonts, draw shapes, merge and split existing documents, all in JavaScript, in Node or the browser. If your job is manipulating PDFs that already exist rather than producing new ones from scratch, this is closer to the right layer than a generator like jsPDF.
**ReportLab** is the standard answer in Python for anything involving tables, charts or precise layout control. The commercial version adds more, but the open-source core covers most real reporting needs. If your stack is already Python, this is usually the first thing worth trying before reaching for a headless browser.
**LaTeX** produces the best typeset output of anything on this list, full stop, which is why academic and scientific publishing still runs on it decades later. The cost is a genuinely steep learning curve and an error message style that can turn a missing brace into twenty lines of cryptic output. Worth it for a thesis. Rarely worth it for an invoice.
**Pandoc** converts between an enormous number of document formats from the command line, including Markdown to PDF by routing through LaTeX under the hood. If you are already writing in Markdown and want a PDF out the other end without hand-rolling a pipeline, this is usually the fastest path.
**Apache PDFBox** is the Java equivalent of pdf-lib: text extraction, splitting, merging, generation from scratch, inside the JVM. If your system is already Java, adding a second-language dependency just for PDFs is rarely worth the operational cost.
**Gotenberg** wraps Chrome and LibreOffice behind a Docker API, so it can convert HTML, Office documents and Markdown to PDF without you managing the underlying engines yourself. Good middle ground if you want Puppeteer-quality rendering without owning the browser process directly, at the cost of running another container.
## Where our own tool actually fits
We built [PDFly's API](/docs) because most of the above assumes either a server you control or a language-specific runtime, and we wanted something callable over plain HTTP with no install. It renders Latin, Devanagari and Arabic script text with the matching font embedded automatically, has 15 templates and 11 page sizes, and a free tier of 100 documents a month with no card required. It does not do pixel-perfect arbitrary web page rendering the way Puppeteer does, and it is not a general document editor the way pdf-lib is. It is one option among the ten above, chosen for a specific job: generating documents from data without standing up your own rendering infrastructure.