view-beads
v0.3.0
Published
Local web dashboard for beads (bd) issue trackers. Type view-beads in any folder and get a link to open in your browser.
Maintainers
Readme
view-beads
A local web dashboard for beads (bd)
issue trackers. Run view-beads in any folder, get a link, open it in your
browser.
Built with Next.js, shadcn/ui and Tailwind. All data comes from the bd CLI.

Install
# npm (Node >= 20.9)
npm install -g view-beads
# or run it without installing
npx view-beadsRequires bd from beads on your
PATH (or point BEADS_BIN at it). The npm package ships the built
standalone server, so it has no runtime npm dependencies.
Alternatively, from this flake (pulls in bd automatically):
nix run github:Prn-Ice/beads-viewer
# or add it to your home-manager packages
inputs.view-beads.packages.x86_64-linux.defaultUsage
cd ~/Projects/my-project
view-beads # starts the server and opens the browser
view-beads --no-open # only print the linkThe server keeps running in the background. Running view-beads again reuses
it and just re-opens the browser.
Use Copy as Markdown in an issue drawer to copy its loaded details for an agent handoff or PR discussion. Comments are excluded.
Which projects are shown?
Every beads project found on your machine, in this order:
- The project in your current folder (or any parent folder)
- Workspaces registered in
~/.beads/registry.json - Any folder containing
.beadsunder~/Projectsor~/Dotfiles(3 levels deep)
Override the search roots with BEADS_PROJECT_ROOTS=/path/a,/path/b.
Checkouts that are linked git worktrees (their .git is a file, not a
directory — e.g. the beads-viewer-worker-* worktrees from
docs/workers.md) are grouped under a separate Worktrees
sidebar section instead of cluttering the main project list. Projects whose
.beads exists but no longer works with the installed bd (e.g. a stale
pre-dolt database) land under Broken with a warning marker.
Live updates
By default the dashboard refreshes the open board every few seconds, re-running
bd list each time. With beads 1.3 or newer you can switch on the
events journal in a
project instead:
bd config set events-journal trueWhile that project's board is open, view-beads follows
bd events tail --follow and pushes each change to the browser as it happens.
The board stops polling and only reloads when something changed. Changes the
journal doesn't record (a bd dolt pull, bd sql writes, a defer date
passing) are caught by a server-side check every 15 seconds. The follower stops
a minute after you leave the board or hide the tab. The sidebar's project
counts still refresh every few seconds.
view-beads never turns the journal on itself: the setting lives in your
project's .beads/config.yaml and applies to every bd command there.
Projects whose database runs on a Dolt server (dolt_mode: server in
.beads/metadata.json) get more: while their board is open, view-beads starts
bd serve on a free loopback port and reads the board and project counts over
its HTTP API (milliseconds instead of a bd process per read), with or without
the journal. With the journal on, changes arrive through bd serve's event
stream. If bd serve won't start (older bd, Dolt server down), view-beads
quietly uses the CLI instead. It never starts a Dolt server for you.
Viewers of a shared dashboard keep polling every few seconds: Cloudflare quick tunnels hold event streams back, so the board only trusts a stream while its heartbeats arrive on time.
GitHub projects
Pick repos from the GitHub settings panel (the gear button in the sidebar's GitHub group),
which lists your gh repos and persists the selection to
~/.config/view-beads/config.json (override with VIEW_BEADS_CONFIG). The
change applies on the next request. Alternatively set
BEADS_GITHUB_REPOS=owner/repo,owner/repo; the env var wins when set.
Each repo is mirrored as a shallow, sparse clone (just the .beads directory)
under ~/.cache/view-beads/github (override with BEADS_GITHUB_CACHE) and
re-fetched at most once a minute.
Git only syncs the JSONL exports — the beads database is gitignored — so on
first sync a local database is materialized in the clone with bd init +
bd import (upserted after each re-fetch). The clone is a strictly read-only
mirror: bd init runs with --skip-agents --skip-hooks, the sync.remote
push channel it would otherwise wire back to GitHub is stripped, and nothing
is ever written back. Repos whose .beads has no synced issue data are
skipped.
Local projects always load instantly; GitHub repos stream into a separate sidebar group one at a time as each sync finishes, with a spinner while a repo syncs and a warning row if it fails.
Requires git and an authenticated gh CLI (gh auth login).
Sharing
The Share button in the header opens a panel that starts a
Cloudflare tunnel and
shows a public link, so co-workers and managers can watch the dashboard live
from their own machines. Pick a quick tunnel (no setup, ad-hoc link), or a
named/token tunnel for a stable, faster URL — the choice persists to the
local config file. Your machine stays the server — stop sharing or shut the
server down and the link dies. Requires cloudflared on your PATH (or
CLOUDFLARED_BIN). See docs/share.md.
View Beads is an independent dashboard, not an official Beads product. See asset sources and licenses for branding credits.
Development
nix develop # node, git, playwright with browsers
npm run dev # dev server on http://localhost:3000
npm test # unit tests (vitest)
npm run test:e2e # integration tests (playwright)
npm run lint # eslint
npm run build # production build (.next/standalone)Environment variables: BEADS_BIN (path to bd), BEADS_HOME (where
registry.json lives), BEADS_PROJECT_ROOTS, BEADS_GITHUB_REPOS,
BEADS_GITHUB_CACHE, GH_BIN (path to gh), CLOUDFLARED_BIN (path to
cloudflared for sharing), CLOUDFLARED_TUNNEL_TOKEN or
CLOUDFLARED_TUNNEL_NAME plus CLOUDFLARED_SHARE_URL (use a proper tunnel
instead of a quick one, see docs/share.md),
VIEW_BEADS_CONFIG (config file path), VIEW_BEADS_SERVER (built
server.js), VIEW_BEADS_NO_OPEN.
Publishing
npm publish builds the standalone server via the prepack hook and packs
bin/ plus .next/standalone/. outputFileTracingExcludes in
next.config.ts keeps local-only data (.git, .beads, docs, tests) out of
the build, and scripts/stage-standalone.mjs stages public/ and
.next/static/ into the standalone folder after each build. Installing from
git (rather than the registry) is not supported — the tarball is the only
distribution channel.
Architecture
src/lib/bd.ts— spawnsbd --json, the only data accesssrc/lib/discovery.ts— finds beads projects, flags git worktreessrc/lib/config.ts— local config file (repo selection), atomic writessrc/lib/github.ts— sparse-clone mirror of GitHub beads repossrc/lib/cache.ts— small TTL cache overbdoutputsrc/lib/events.ts— follows the beads events journal for open boardssrc/lib/serve.ts— runsbd servefor server-mode projectssrc/lib/issues.ts— board reads, throughbd servewhen it runssrc/app/api/*— thin JSON endpointssrc/components/*— board, sidebar, issue drawerbin/view-beads.mjs— CLI wrapper
