HTML to PDF in Ruby, with headless Chrome and WebDriver BiDi
bidi2pdf is an open-source Ruby gem and command-line tool that turns web pages and HTML into PDFs. It is built for developers, CI pipelines and AI coding agents that need PDF generation they can script: structured JSON results, predictable exit codes and rendering by a real browser.
What it does
- A web page or HTML file to PDF from the command line, with waits for page load or network idle, cookies, headers and basic auth.
- HTML in, PDF out:
--stdinand--output -pipe without an input or output file of your own. The PDF goes straight to stdout; the piped HTML is kept in a temporary file while Chrome loads it, then deleted. - Automation and agents: with
--json, stdout carries exactly one JSON document per call; failures come back in the same shape with a structured error and a stable exit code; the JSON Schema of every shape is built in. - Why does the PDF not look like the page?
bidi2pdf diagnosereports console errors, failed requests, font loading, print rules and Paged.js – without producing a PDF. - Pages that need steps before printing: declarative recipes, validated without launching a browser.
- Screen, dark and mobile views of a page as PDF (
--media,--color_scheme), and screenshots through the Ruby API, for review. - A shared remote Chrome for several processes – Puma workers, job workers – with pre-warmed sessions and a sweeper for leaked ones.
- Ruby and Rails: a programmatic API and DSL, bidi2pdf-rails for
render pdf:in controllers, and RSpec matchers for PDF specs.
Quick start
gem install bidi2pdf
bidi2pdf render --url https://example.com --output example.pdf
Requires Ruby 3.4 or later and Chrome or Chromium – or use the published Docker image.
Common tasks
- Generate PDFs in Ruby or Rails – reports, invoices and other HTML templates, rendered by headless Chrome: bidi2pdf-rails gives controllers
render pdf:; plain Ruby uses the gem's API. - Convert HTML to PDF in CI – one command, then read
okand the exit code instead of parsing logs:bidi2pdf render --html-file report.html --output report.pdf --json - Debug a PDF that looks wrong – missing fonts, failed requests, print CSS, JavaScript errors, without producing a PDF:
bidi2pdf diagnose --url https://example.com/invoice --json
When to use bidi2pdf
It fits when the PDF should look like the page does in a browser – modern CSS, web fonts, content a script renders, Paged.js print layouts – because Chrome itself renders it; when PDFs are made unattended, in CI, background jobs or by an agent, and a failure has to say what went wrong; and when the code around it is Ruby or Rails, or several processes share one remote Chrome.
Something else fits better when the PDF is drawn in code rather than from HTML – a PDF library does that without a browser – or where neither Chrome nor Docker can run.
For agents and CI
# check compatibility - no browser launched
bidi2pdf version --json
# discover the shape of every result
bidi2pdf schema render
# validate a recipe without a browser, then run it
bidi2pdf run recipe.yml --validate
bidi2pdf run recipe.yml --json
# render with a machine-readable result
bidi2pdf render --url https://example.com --output example.pdf --json
| Exit code | Meaning |
|---|---|
0 | success |
2 | CLI, configuration or recipe-validation error |
3 | browser or navigation error |
4 | page not as expected (a recipe action or assertion, or a diagnose selector, failed) |
6 | output or PDF generation failure |
70 | unexpected internal error |
Details: structured output, stdin/stdout and progress events, diagnose, recipes. A plain-text summary for language models: llms.txt.
Claude Code plugin
Six skills teach an agent to use bidi2pdf as intended: rendering, recipes, diagnosing a wrong PDF, a shared remote Chrome, review screenshots and PDF specs.
/plugin marketplace add dieter-medium/bidi2pdf
/plugin install bidi2pdf@bidi2pdf