A real browser drawn inside a terminal pane. Not a screenshot, not a text dump — the actual page, rendered next to your shell, and scriptable from it. You open it with a command, you close it with a command, and it stays where you put it.
There are three ways to get it. Pick one:
— copy one block into your coding agent.Let your agent do it— build, install, run. Nothing else involved.Just the browser— adds a browser pane type and Ctrl+clickable links.With herdr
Paste this into Claude Code, Cursor, Codex or whatever you use. It is written for the agent, not for you, and it stops rather than guessing when something is missing.
Set up terminal-browser on this machine, from source.
Repo: https://github.com/yoelgal/terminal-browser — branch `upstream-proposal`.
This fork publishes no release binaries, so building from source is the only path. There is no
install one-liner for it. Do not look for one.
1. Check the prerequisites and report which are missing. Do not install system packages on your
own. Ask me before running any package manager, brew, apt, or sudo command.
- Platform: macOS arm64, or Linux x64/arm64. Anything else is unsupported — stop there.
- Node 22, pnpm, and a stable Rust toolchain.
- macOS: Xcode command line tools (`xcode-select --install`) — a Swift helper is compiled.
- Linux: libnss3, libgtk-3-0, libasound2t64, libgbm1.
- jq. Only the herdr plugin needs it, but check now so I hear about it once.
2. Build and install the browser:
git clone https://github.com/yoelgal/terminal-browser
cd terminal-browser
git checkout upstream-proposal
pnpm install
pnpm dist
`pnpm dist` builds and installs. App lands in ~/.local/share/terminal-browser/app, shim at
~/.local/bin/terminal-browser.
3. Verify, do not assume: `terminal-browser --version` must print `local-<short sha>`. If it says
command not found, ~/.local/bin is missing from PATH — tell me. Do not edit my shell profile.
4. Then check for herdr with `herdr --version`. If there is no herdr, you are done: go to step 6.
If there is, take the version and strip any `-preview.<date>-<sha>` suffix, then compare the
remaining X.Y.Z against 0.8.2. Anything lower: STOP. Tell me my herdr is too old and that the
plugin install would be refused. Do not run `herdr update`, brew, or any other upgrade —
upgrading my herdr is my decision, not yours.
5. Only when that base version is 0.8.2 or newer:
herdr plugin install yoelgal/terminal-browser/herdr-plugin --ref upstream-proposal -y
Step 2 must already be done. The plugin's build step runs UPSTREAM's `curl | bash` installer
when it finds no terminal-browser, which would install upstream's build over this fork. With the
fork's binary already on PATH that build step does nothing, which is what we want.
Verify with `herdr plugin list`: `zenbu-labs.terminal-browser` must be listed.
6. Report back: versions you found, anything missing, whether the plugin went in, anything you
skipped and why.
Throughout: do not open a browser window, do not run `terminal-browser open`, `new-tab`, or any
plugin action, and do not touch my panes, tabs, or focus. Nothing that opens a window or steals
focus. Commit nothing and open no pull request. If a step fails, stop and show me the exact output.
macOS arm64, or Linux x64/arm64. The installer refuses anything else.Node 22,** pnpm**, and a** stable Rust toolchain**— the render engine is a Rust native module.** macOS:**Xcode command line tools,xcode-select --install
. A small Swift scroll helper gets compiled.Linux:libnss3 libgtk-3-0 libasound2t64 libgbm1
. The installer runsldd
on the bundled Electron and names anything missing.
A patched Electron is downloaded from the public zenbu-labs/electron-releases
mirror during
pnpm install
, and its SHA256 is checked.
This fork ships no release artifacts, so you build it yourself:
git clone https://github.com/yoelgal/terminal-browser
cd terminal-browser
git checkout upstream-proposal
pnpm install
pnpm dist
pnpm dist
builds a release tarball and then hands it to the same installer a published release would use, so you end up in the normal place:
-
app at
~/.local/share/terminal-browser/app -
shim at
~/.local/bin/terminal-browser
terminal-browser --version # -> local-66ffc59
terminal-browser open example.com
The version is local-
plus the short commit you built, so yours changes as the branch moves.
If your terminal is a VS Code-family editor, run terminal-browser setup
once. Those ship with terminal images switched off, and this turns them on.
That is the whole browser install. If you do not use herdr, skip the next section — nothing below it depends on it.
The plugin puts the browser under herdr's own controls, so a browser pane behaves like any other pane and links become clickable into it.
herdr plugin install yoelgal/terminal-browser/herdr-plugin --ref upstream-proposal
Add -y
to skip the confirmation prompt. It is required anyway when stdin is not a terminal.
Check it landed:
herdr plugin list # -> zenbu-labs.terminal-browser (Terminal Browser) enabled
Do the Just the browser build before this. The plugin has one build step, and it exists so the plugin is never installed onto a machine with no browser to drive:
It does nothing whenterminal-browser
is already on your PATH, orTERMINAL_BROWSER_BIN
points at something runnable. Your own build is left alone.Otherwise it runs upstream's, which gives you a stock terminal-browser rather than this fork.curl | bash
installer
So the ordering is the whole trick: build the fork, then install the plugin, and the plugin drives the fork.
This is checked and it is a refusal, not a warning. On anything older the install stops before it starts — nothing is checked out, no build step runs:
plugin requires Herdr 0.8.2 or newer; current Herdr is 0.8.0
Only the X.Y.Z
part of your version counts. A preview build like
0.8.0-preview.2026-08-17-1147e60bc0a4
compares as plain 0.8.0 and is refused however recently
it was built. Get to 0.8.2 with herdr update
, or brew update && brew upgrade herdr
on a Homebrew install, then install the plugin.
| Pane type | browser , "Terminal Browser" — opens as a split |
Action open-split |
Splits the focused pane and opens a browser to the right |
Action open-url |
Opens a URL, reusing an existing browser when there is one |
| Link handler | ^https?:// routes to open-url |
From a shell inside a herdr pane — the split needs a pane to split:
herdr plugin action list --plugin zenbu-labs.terminal-browser
herdr plugin action invoke open-split --plugin zenbu-labs.terminal-browser
Two things will otherwise surprise you:
A plain click still opens your system browser. Only Ctrl+click reaches a plugin link handler.Other plugins win ties. When more than one enabled plugin claims the same URL pattern, herdr sorts enabled plugins by id and takes the first match.zenbu-labs.terminal-browser
sorts near the end of the alphabet, so it yields to most other plugins that want^https?://
. If your Ctrl+clicks land somewhere else, that is why — disable the other handler.
A clicked link reuses a browser already open in the same herdr tab first, then one elsewhere in the
same workspace. It never reaches into another workspace. With nothing to reuse it splits a new
browser pane. This reuse is a jq
query, so without jq
installed every click splits a fresh browser.
If you are working on terminal-browser itself, you do not have to install over the copy on PATH. Set
TERMINAL_BROWSER_BIN
and every plugin script — pane, split, link reuse — agrees on that binary:
export TERMINAL_BROWSER_BIN=/path/to/checkout/bin/terminal-browser
Plugin commands inherit the herdr server's environment, so export it somewhere the server will see it and restart the server:
herdr server stop && herdr
A value that does not resolve to something runnable is refused by name:
TERMINAL_BROWSER_BIN is set to '…', which is not runnable — fix or unset it
It does not quietly fall back to PATH. Fix it or unset it.
Opening and moving around:
terminal-browser open localhost:3000
terminal-browser open ./report.html --split right --size 0.4
terminal-browser new-tab github.com
terminal-browser ls # running browsers, their profiles, their tab ids
terminal-browser shutdown # all browsers share one process; this stops it
Driving the open page from a script or an agent — everything after --
is an agent-browser command:
terminal-browser action -- snapshot
terminal-browser action -- click @e14
terminal-browser action -- eval "document.title"
Signing in as yourself. This reads cookies out of a Chromium-family profile on this machine — Chrome, Brave, Edge, Arc, Vivaldi and friends; not Firefox or Safari — and copies them into a browser you already have open. It is macOS only and refuses to run elsewhere, because the values are decrypted with a key from your login keychain. Cookies only: no history, no bookmarks, no passwords. In a terminal it shows what it found and asks first.
terminal-browser import-cookies
terminal-browser import-cookies --domain github.com --from brave
Profiles are separate boxes of cookies and storage, so you can be signed into one site twice:
terminal-browser profile list
terminal-browser profile create Work
terminal-browser open github.com --profile work
terminal-browser: command not found
after a clean build.~/.local/bin
is not on your PATH:
export PATH="$HOME/.local/bin:$PATH"
The page draws as garbage, or not at all, in a VS Code-family terminal.
Terminal images are off by default there. terminal-browser setup
turns them on.
Linux: warning: missing system libraries. The installer checked the bundled Electron and found gaps. Install what it names:
sudo apt-get install libnss3 libgtk-3-0 libasound2t64 libgbm1
Every Ctrl+click opens a brand-new browser instead of reusing the one on screen.
jq
is missing. brew install jq
, or apt-get install jq
.
** plugin requires Herdr 0.8.2 or newer.** Update herdr. A
-preview
suffix counts for nothing toward the number.** TERMINAL_BROWSER_BIN is set to '…', which is not runnable.** A stale override — you moved or rebuilt what it pointed at. Repoint it, or
unset TERMINAL_BROWSER_BIN
to go back to PATH. The herdr server keeps the old value until you
restart it.No prebuilt binaries for this fork. Every install is a build, on every machine.Do not run It installs the latest release from the channel your install records, which is upstream's — so it replaces your fork build with upstream's. To move the fork forward, pull the branch and runterminal-browser upgrade
on a source build.pnpm dist
again.macOS arm64 and Linux x64/arm64 only. No Intel macs, no Windows.Cookie import is macOS only. On Linux it refuses.