An interactive graph editor for Beads issues. Run one command in a repository that has a .beads store and a browser opens on a dependency graph you can actually edit — create issues, drag to connect dependencies, change status, all written straight back through the bd CLI.
npx @halaprix/beads-viewer # in a repo with a .beads storeThe Everything view on this project's own store. Column position is dependency depth, so
the leftmost work is startable; solid edges are blocks, dashed are parent-child. The
default view is narrower than this on purpose.
bd graph --html loads D3 from a CDN, so it needs the network and cannot be archived. bd graph in a terminal is static. Both are read-only. Meanwhile the graph is the one place where a dependency mistake is obvious at a glance — and the one place you cannot fix it.
Not a Beads replacement, and not a second source of truth. The bd CLI is the only writer; this is a lens on the store that happens to be able to write through itself. Close the tab and nothing is lost or pending.
The design principle, taken from what actually works in comparable tools: a graph that answers a question, never a graph of everything. Rendering the whole store is how Backstage's catalog graph and Obsidian's global graph became things people call pretty and don't use.
In 0.2.0:
- Scoped graph by default — one epic, or a bounded focus around a chosen issue. The whole store is an explicit opt-in, with a warning past the readability cliff.
- Layered layout, left to right, where the column is topological depth: column 0 is startable work. Deterministic — the same store always draws the same picture.
- Detail panel with field-level editing. Only the field you touched is written.
- Create a child issue from the detail panel.
- Drag to connect a dependency, select an edge to remove it. Grouped edges are read-only until expanded.
bdrejects cycles for us, and the rejection is surfaced verbatim. - Live refresh — a human or an agent running
bdin a terminal shows up in the UI within about a second.
npm test— pure-logic tests: the graph model, layout, and browser-detection helpers. Nobdneeded, always safe to run.npm run test:integration— spins up a real server against a real, isolated Beads store. NeedsbdonPATH.npm run test:smoke— installs the real published tarball and separately renders the built page in headless Chromium, asserting the canvas has real size, the node count matches the store, and there are zero console errors and zero failed requests. Needsbdandnpx playwright install chromium.
All three ran in this repository's own past releases and none of them would have caught
the bugs that actually shipped: a broken CLI entry point, a dead change-detection path, a
404'd lazily-loaded chunk, a zero-height canvas, and a store with exactly one issue
collapsing to a single object instead of a list. Every one of those only failed when the
real, built, installed, rendered artifact was exercised - which is what
test:integration and test:smoke exist to do, and why CI now runs them rather than
only the pure-logic suite.
- Node >= 22.13.0
bdonPATH, and a.beadsstore discoverable from the working directory
beads-viewer [--port <number>] [--strict-port] [--no-open] [--debug]
beads-viewer --help
beads-viewer --version
The server binds to 127.0.0.1 only. Its printed URL carries a one-time token in the
fragment; if a browser cannot be opened automatically, open that URL exactly as printed.
npm install
npm run check # lint, typecheck, tests, and production build
npm start # from any repo with a .beads storeThe CLI and security integration tests use temporary isolated stores and skip cleanly
when bd is not installed.
Version 0.2.0 provides scoped graph views, a detail panel with field-level edits,
child creation, dependency editing, and live refresh. Everything remains an explicit
view and warns when it is too crowded to answer anything.
Known gaps: no test covers the React components (the graph model and the server are
tested); collapse state is not persisted across reloads; layout runs on the main thread,
which is fine at these sizes but would want a worker past a few hundred nodes; the
elk.js chunk is 442kB gzipped and only loads when a graph is first laid out.
The package is public and has zero runtime dependencies: prepack builds the SPA, and
the tarball contains the server plus prebuilt assets. The release workflow checks that
the vX.Y.Z tag matches package.json, publishes with npm provenance, and creates the
matching GitHub Release. See CHANGELOG.md for shipped changes.
MIT. Bundles elkjs (EPL-2.0) for layout — see docs/decisions.md for why, and NOTICE for its terms.
