Chromium setup
Viewing, authoring, and live-presenting a deck need only a normal browser. A few build-time features render slides headlessly, and those need a real Chromium binary. Chromium is optional: if you never use those features, you never need it.
What needs Chromium
Section titled “What needs Chromium”| Feature | Command / API | Without Chromium |
|---|---|---|
| Slide thumbnails (overview grid) | liebstoeckel build, liebstoeckel live, buildDeck() | Skips the capture and keeps building. The deck works; the overview grid falls back to a live render. |
| Regenerate thumbnails | liebstoeckel thumbs | Fails with an error. |
| Export to PNG or PDF | liebstoeckel export | Fails with an error. |
The split is deliberate. build and live treat thumbnails as a best-effort enhancement, so a missing browser never blocks a build. thumbs and export exist only to produce that output, so they fail loudly instead of writing nothing.
Check what you have
Section titled “Check what you have”liebstoeckel doctor reports your build environment (Bun version, whether a Chromium was found, and where its path is recorded):
liebstoeckel doctor # human summary; --json for the machine-readable formIf a Chrome or Chromium is already on the machine, liebstoeckel usually finds it on its own (see Resolution order), you may not need to do anything.
Provide a Chromium
Section titled “Provide a Chromium”If doctor reports none, any of these works.
Let liebstoeckel install and remember Playwright’s Chromium for you:
liebstoeckel doctor --install-chromium # installs, then records the path in your configOr install it yourself (liebstoeckel ships playwright-core, which has no browser of its own):
bunx playwright install chromiumOr point LIEBSTOECKEL_CHROMIUM at a Chrome or Chromium you already have:
export LIEBSTOECKEL_CHROMIUM=/usr/bin/chromium # or a full path to Chromeliebstoeckel build my-talkResolution order
Section titled “Resolution order”When a feature needs a browser, liebstoeckel looks in this order and uses the first binary that exists on disk:
- An explicit
executablePathpassed to the thumbnails/export API. - The
LIEBSTOECKEL_CHROMIUMenvironment variable — including the pathdoctorrecords in your config (~/.config/liebstoeckel/config.json), which the CLI loads into this variable when you haven’t set it yourself. Surrounding quotes and whitespace are stripped (a common artifact ofset VAR="C:\..."on Windows), and a configured path that doesn’t exist prints a warning before falling back to auto-detection. - A system Chrome/Chromium:
PUPPETEER_EXECUTABLE_PATH/CHROME_PATH, Puppeteer’s install cache,google-chrome/chromium/chromium-browser/chromeonPATH, the standard macOS and Windows install locations (including per-user installs and 32-bit/64-bitProgram Filesvariants), and on Windows the registry’s App Paths entry, which finds Chrome wherever the installer put it. - On Windows, Microsoft Edge as a last resort — it is preinstalled everywhere and uses the same engine, so capture output is identical.
- The Chromium installed by Playwright.
The existence check matters: Playwright reports a computed path even when nothing is installed, so liebstoeckel verifies the file is really there before trusting it. This keeps the “no Chromium” path honest in CI. When nothing is found, liebstoeckel doctor lists every location it probed.
Launch flags
Section titled “Launch flags”On Linux and macOS the browser launches headless with container-friendly flags
(--no-sandbox --disable-gpu --disable-dev-shm-usage --renderer-process-limit=1), chosen so capture works in sandboxes and CI
without a GPU or user namespaces; Windows uses the stock process model. The GPU
thread deliberately stays in its own process: on machines where software GL
cannot initialize, an in-browser GPU thread would crash the browser, while a
separate GPU process falls back to software compositing. If a
Chrome update or an unusual environment makes those defaults crash, the
LIEBSTOECKEL_CHROMIUM_ARGS environment variable replaces the whole list
(whitespace-separated), so you can also remove a default flag, not just add:
export LIEBSTOECKEL_CHROMIUM_ARGS="--no-sandbox --disable-gpu --disable-dev-shm-usage"Containers and CI
Section titled “Containers and CI”Capture launches Chromium with container-friendly flags so it runs without a GPU or user namespace (see Launch flags above for the list and the LIEBSTOECKEL_CHROMIUM_ARGS override).
In a container image, either run bunx playwright install chromium during the build, or install your distro’s Chromium package and set LIEBSTOECKEL_CHROMIUM to it.
Windows
Section titled “Windows”On Windows, liebstoeckel drives the browser over the Chrome DevTools Protocol directly (it launches Chrome with a DevTools port and connects with a native WebSocket) instead of Playwright’s usual transports, which do not work under Bun on Windows. This is automatic and produces identical output. Setting LIEBSTOECKEL_CDP_DRIVER=1 forces the same transport on any platform, useful when debugging capture issues.
When no Chromium is found
Section titled “When no Chromium is found”The “no Chromium found” message is expected if you never installed one. What follows depends on the command:
liebstoeckel buildandliebstoeckel livelog a note that thumbnails were skipped and finish normally. Runliebstoeckel doctor --install-chromium(or provide a browser as above) to get the overview thumbnails back.liebstoeckel thumbsandliebstoeckel exportstop with an error that names the fixes (liebstoeckel doctor --install-chromium, or setLIEBSTOECKEL_CHROMIUM).
Skip thumbnails on purpose
Section titled “Skip thumbnails on purpose”To build without thumbnails even when a browser is present, set LIEBSTOECKEL_NO_THUMBS:
LIEBSTOECKEL_NO_THUMBS=1 liebstoeckel build my-talkCode-first presentations your agent can author. One file out, no server.
Comments