Gotenberg alternatives in 2026: what to use when self-hosting stops being fun
The best Gotenberg alternative depends on which half of Gotenberg you actually use. For its Chromium half (HTML and URLs to PDF), the realistic options are a managed API like Transformy or running Puppeteer or Playwright yourself; for its LibreOffice half (Office documents to PDF), the honest replacement is LibreOffice in headless mode, which is what Gotenberg runs under the hood anyway.
Let's be clear up front: Gotenberg is good software, actively maintained and free. Teams search for alternatives because the operational side stopped being fun, not because the project failed them.
$ docker stats gotenberg --no-stream
NAME MEM USAGE / LIMIT MEM %
gotenberg 1.87 GiB / 2 GiB 93.5%
$ kubectl get pod gotenberg-7d4b9
NAME READY STATUS RESTARTS
gotenberg-7d4b9 1/1 Running 14 (2h ago)
$ kubectl describe pod gotenberg-7d4b9 | grep -i reason
Last State: Terminated, Reason: OOMKilled
$
KEY TAKEAWAYS
- Gotenberg is two converters in one container. Chromium renders HTML and URLs; LibreOffice converts Office documents. Your alternative depends on which routes you call.
- The pain is operational, not functional. Memory growth, scaling, upgrade testing, and queueing are what push teams off self-hosted Gotenberg, not missing features.
- Managed rendering removes the container, not the API shape. An HTTP API like Transformy keeps the same integration pattern (POST HTML or a URL, get a PDF) while browser operations move to the vendor.
- For Office documents, go to the source. LibreOffice in headless mode is the engine Gotenberg wraps; calling it directly is the leanest self-hosted replacement for that half.
- JavaScript-free documents don't need a browser. WeasyPrint renders template-driven PDFs from Python with no Chromium anywhere in the stack.
Why teams look for Gotenberg alternatives
Gotenberg's pitch is genuinely attractive: a single Docker container that exposes document conversion as an HTTP API, wrapping Chromium for web content and LibreOffice for Office formats. For a team that wants API ergonomics without a SaaS dependency, it is the obvious first stop, and for many teams it stays the right one.
The friction shows up in production, and it is the same friction every self-hosted browser workload has:
Browsers are heavy tenants. Chromium's memory use grows with page complexity and concurrency, and a busy container eventually meets the OOM killer. The standard fixes (restart policies, per-container request limits, more replicas) work, but now you are doing capacity planning for a browser farm.
Scaling is a project, not a flag. One container handles a modest concurrent load; past that you are running multiple replicas behind a load balancer, deciding how many renders per instance are safe, and building a queue in front of the whole thing for bursty traffic like end-of-month invoice runs.
Upgrades carry rendering risk. New Gotenberg releases bring new Chromium and LibreOffice versions. That is exactly what you want for security, and it also means output can shift subtly between versions, so document-heavy teams need a regression pass per upgrade.
The second engine is a second surface. If you use the LibreOffice routes, you inherit LibreOffice's quirks (fidelity depends on fonts installed in the container, and Word layouts with heavy formatting can drift) on top of Chromium's.
None of this is a knock on Gotenberg; it is the cost of running rendering infrastructure anywhere. The question is whether that cost belongs in your team.
Tip
If Gotenberg is working and your volume is stable, keep it. The alternatives below earn their place when the ops line items above start appearing in your sprint planning.
First, decide which Gotenberg you use
Gotenberg's API groups into two families, and they migrate to different places:
HTML, Markdown, and URL conversion
This is browser rendering.
Migrates to: a managed rendering API, Puppeteer/Playwright, or the Chrome CLI
.docx, .xlsx, .pptx, and friends
This is Office conversion.
Migrates to: LibreOffice headless, or a slim Gotenberg kept just for this
Teams that use both halves usually split the migration: move HTML rendering to whichever option fits, and keep Office conversion on a dedicated, smaller footprint. A converter that does everything is convenient right up until you have to scale the whole thing to serve its busiest route.
The shortlist at a glance
| TOOL | TYPE | REPLACES WHICH HALF | PRICING | BEST FOR |
|---|---|---|---|---|
| Transformy | Managed API | Chromium (HTML/URL) | Free 100 docs/mo, then $99/mo for 10,000 | Keeping the HTTP-API shape without running browsers |
| Puppeteer / Playwright | Library (Node.js and more) | Chromium (HTML/URL) | Free (your infra) | Teams that prefer a library in-process over a service |
| Headless Chrome CLI | Command-line tool | Chromium (HTML/URL) | Free | Scripts and cron jobs, not services |
| LibreOffice headless | Command-line tool | LibreOffice (Office docs) | Free | Direct Office-to-PDF conversion, same engine Gotenberg uses |
| WeasyPrint | Library (Python) | Either, for JS-free documents | Free | Template-driven PDFs with no browser in the stack |
The managed option: Transformy
If what you like about Gotenberg is the shape (an HTTP API your services call, instead of a library each service embeds), a managed rendering API keeps that shape and removes the container. Transformy is an HTML-to-PDF API built on headless Chromium: send a URL or raw HTML in one authenticated POST and get a PDF back. Scaling, Chromium upgrades, memory management, and concurrency stop being your cluster's problem.
The integration is close enough to Gotenberg's Chromium routes that migrations are mostly parameter renaming (cheat sheet below). Beyond parity, you get the production plumbing that self-hosted setups usually hand-build: async jobs with signed webhooks, delivery straight to your own S3/GCS/Azure/R2 bucket, idempotency keys for safe retries, and a test mode that renders real documents free with a watermark. Engine upgrades are pinned and regression-tested on the vendor side, which converts your per-upgrade test pass into someone else's job.
curl -X POST https://api.transformy.io/v1/pdf/chrome \
-H "Authorization: Bearer tfy_live_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/invoice/1042",
"page_size": "a4",
"margin": "2cm",
"webhook_url": "https://api.yourapp.com/hooks/pdf-ready"
}' \
--output invoice.pdf
Pricing starts free (100 documents a month, no credit card), and the Pro plan is $99/month for 10,000 documents, then $0.01 per additional document. Two honest limits. First, Transformy renders HTML and URLs only: there is no Office conversion, so the LibreOffice half of your Gotenberg usage needs one of the options below. Second, if your compliance posture requires rendering to stay inside your network boundary, a managed API is off the table by definition, and Puppeteer or a slimmed-down Gotenberg is the right call.
Run it yourself: the open-source routes
Puppeteer and Playwright
If you would rather trade Gotenberg's service model for a library, Puppeteer and Playwright drive headless Chrome in-process, and page.pdf() produces the same Chromium output Gotenberg's routes do. The trade is architectural: no separate conversion service to deploy, but every consuming app now embeds a browser, with the memory, packaging, and upgrade weight that implies. That trade makes sense when exactly one service generates PDFs; it gets worse the more places need rendering, which is precisely the situation Gotenberg's API shape solves. Our guides to Puppeteer PDF generation and Playwright HTML to PDF cover working setups.
Operationally, know that you are not escaping the browser problems that pushed you off Gotenberg; you are relocating them. Memory recycling, crash recovery, and concurrency limits all come along. What you gain is control and zero licensing cost; what you keep is all of the ops. (Our Puppeteer alternatives comparison covers this trade-off from the other direction.)
Headless Chrome from the command line
For the narrow case where Gotenberg was serving a script or a scheduled job rather than live traffic, Chrome itself converts pages from the command line:
chrome --headless --no-pdf-header-footer --print-to-pdf=report.pdf https://example.com/report
One process, one PDF, no service to keep warm. The flags run out quickly (no per-request headers and footers with page numbers, coarse wait control), but for a nightly report emailed to finance, it may be all the infrastructure you need.
LibreOffice headless
Here is the alternative most Gotenberg comparisons skip: for the Office routes, Gotenberg is a convenience wrapper around LibreOffice. If Word-to-PDF is the half you actually use, you can call the engine directly:
soffice --headless --convert-to pdf --outdir ./out contract.docx
Same engine, same fidelity, same font caveats (install the fonts your documents use, or substitution will quietly change layouts), minus the HTTP layer. Wrap it in a small worker with a queue and you have replaced that half of Gotenberg with fewer moving parts. If you want to keep the HTTP interface, the leanest move is often the opposite of migration: keep a small Gotenberg deployment that only serves LibreOffice routes, and move the heavier Chromium traffic elsewhere.
WeasyPrint
If the documents you render are your own templates (invoices, statements, reports) and they never needed JavaScript, there is a case for skipping the browser entirely. WeasyPrint is a Python library with its own CSS paged-media engine: @page rules, running headers, and page numbering in pure CSS, with no Chromium or LibreOffice in the stack. Output is deterministic, the install is one pip command, and there is no container to feed. It also produces PDF/A and PDF/UA variants when compliance asks. The limits: no JavaScript at all, Python-only, and large documents render slower than Chrome. Our WeasyPrint guide covers setup and the common font pitfalls, and our WeasyPrint alternatives comparison maps where its limits sit.
Migrating: mapping Gotenberg's Chromium routes to Transformy
The concepts transfer directly; most of the work is renaming form fields to JSON parameters. The mapping for the options that appear in almost every Gotenberg integration:
- POST /forms/chromium/convert/url (multipart, field "url")
+ POST /v1/pdf/chrome (JSON, "url")
- POST /forms/chromium/convert/html (multipart, index.html file)
+ POST /v1/pdf/chrome (JSON, "html" string)
- paperWidth=8.27 paperHeight=11.7
+ "page_size": "a4" # or "page_width"/"page_height" with explicit units
- landscape=true
+ "orientation": "landscape"
- marginTop=0.79
+ "margin": {"top": "2cm"}
- printBackground=true
+ "print_background": true # already the default
- nativePageRanges=1-5
+ "page_ranges": "1-5"
- waitDelay=2s / waitForExpression=...
# usually unnecessary; JavaScript runs and settles before capture
- header.html / footer.html files
+ "header"/"footer": {"html": "… {{page}} of {{pages}} …"}
- webhook feature + basic auth on your instance
+ "webhook_url" (signed, retried) + Bearer API key
Differences worth a test pass: Gotenberg measures paper size in inches by default while Transformy takes explicit units as strings ("210mm", "8.5in"), and file-based inputs (a multipart index.html upload) become a JSON string field. If you use Gotenberg's Markdown route, convert Markdown to HTML in your app first; that step was always a preprocessor anyway.
For the LibreOffice routes there is no Transformy equivalent; use the LibreOffice section above.
Frequently asked questions
Is Gotenberg still maintained?+
Yes, actively. This page exists because self-hosting browser workloads has real operational cost, not because Gotenberg is at risk. If you have the ops capacity and your volume is steady, staying on Gotenberg is a defensible choice.
What is the main difference between Gotenberg and a managed API like Transformy?+
Who runs the browsers. Gotenberg gives you the HTTP-API shape and leaves scaling, memory, upgrades, and queueing to you; a managed API keeps the shape and takes over the operations. The integration pattern (POST HTML or a URL, receive a PDF) is nearly identical.
Can Transformy convert Word or Excel documents like Gotenberg does?+
No. Transformy renders HTML and URLs with headless Chromium only. For Office formats, use LibreOffice headless directly, or keep a small Gotenberg deployment dedicated to those routes.
What is the best free Gotenberg alternative?+
For HTML rendering: Puppeteer or Playwright if a library fits your architecture, or the headless Chrome CLI for scripts. For Office conversion: LibreOffice headless. For JavaScript-free templates in Python: WeasyPrint. All are free and actively maintained; all keep the ops on your side.
Gotenberg keeps getting OOM-killed. Is that fixable?+
Usually, yes: cap concurrent renders per instance, add replicas behind a load balancer, and recycle containers on a schedule. That work is exactly the trade this page is about; it is fixable, and it is also the moment to ask whether the fixing should be your team's job.
The bottom line
Match the alternative to the half of Gotenberg you actually use. If it is the Chromium half and you like the API shape, the closest like-for-like move is a managed rendering API: Transformy keeps the one-POST integration and takes the browser operations with it, and the free tier (100 documents a month, no credit card) is enough to test your real documents against the migration table above. If it is the LibreOffice half, call LibreOffice directly or keep a slim Gotenberg for exactly that. If a library suits your architecture, Puppeteer and Playwright are excellent; if your documents never needed a browser, WeasyPrint removes the problem at the root. And if you are also carrying legacy wkhtmltopdf workloads, our wkhtmltopdf alternatives comparison covers that migration in the same spirit.
Gotenberg earned its place by making document conversion feel like calling an API. The alternatives above are for the day the container behind that API starts feeling like a second job.