Skip to content

Development and Building

CapsaicinBunny edited this page Jun 20, 2026 · 1 revision

Development & Building

Everything here is for building from source or running the web/CLI version — end-users just install the app.

Prerequisites

  • Bun — the runtime, package manager, and test runner.
  • A Rust toolchain only if you rebuild the native analyzer-core or the vello-renderer WASM. The prebuilt artifacts are committed, so you don't need Rust for normal app/UI work.

Run it

bun install
bun run dev      # Next.js dev server → http://localhost:3003  ·  analysis sidecar on a loopback port

Open http://localhost:3003 (needs a WebGPU-capable browser), paste an absolute folder path into Scan a folder, and explore.

Scripts

bun run dev            # Next dev server (port 3003) + analysis sidecar
bun run build          # production build → static export in out/
bun run build:sidecar  # compile the sidecar to a standalone binary (dist/)
bun run start          # serve the static export locally (out/)
bun run check          # architecture rules check on the current directory
bun run diff           # graph diff of the current directory vs. HEAD
bun run typecheck      # tsgo --noEmit
bun test               # analyzer + view unit tests + golden/stability snapshots
bun run lint           # oxlint --type-aware   (lint:fix to autofix)
bun run format         # oxfmt                 (format:check in CI)
bun run bench          # measure perf fixtures (bench:check / bench:update / bench:fetch)
bun run tauri          # Tauri CLI (desktop shell)

The polygraph CLI runs from source via bun run cli/index.ts <command> (the package is "private", so the bin isn't published). See CLI: Rules & Diff.

Repository layout

lib/
  graph/types.ts        GraphModel types + id helpers (incl. edge evidence)
  graph/visual.ts       colors / glyphs / icons per node & edge kind
  graph/scene.ts        geometry-free scene (shared by layout + renderer)
  graph/query.ts        impact analysis (dependencies/dependents/blast radius/paths)
  graph/insights.ts     architectural-issue detectors (Problems panel)
  graph/query-language/ the search/select query language
  graph/levels/         package- & workspace-level projection
  kernel/               language kernel: provider interface, registry, tree-sitter glue
  analyzer/             ts-morph TypeScript/JS provider (the precise plugin)
  aggregate.ts          collapse/expand view projection (+ edge aggregation)
  layout.ts, layout/    layout engines (+ layout.worker.ts off-main-thread)
  server/               framework-agnostic runScan / runAnalyze + manifest discovery
  telemetry/            structured logging / metrics / global error capture
  cli/ config/ rules/ glob/ diff/    CLI: check + diff, rules engine, SARIF
  export/ workspace/ editor/         exports, saved workspaces, editor jump
language-packs/         declarative tree-sitter packs (one folder per language)
analyzer-core/          native Rust (napi-rs) tree-sitter core (+ vendor/wat)
vello-renderer/         Rust→WASM WebGPU vector renderer
sidecar/server.ts       Bun loopback server (/scan, /analyze, /health)
cli/index.ts            the polygraph CLI entrypoint
src-tauri/              Tauri v2 desktop shell
app/                    Next.js App Router (static-exported SPA)
components/             Explorer, VelloGraphCanvas, Sidebar, detail/Problems panels
bench/                  perf + golden-graph + layout-stability suite

A guided tour of how these fit together is in Architecture Overview.

Rebuilding the native artifacts

Both Rust artifacts are committed prebuilt; rebuild and commit the output when you change their sources, or the change won't take effect at runtime.

# Native analysis core → analyzer-core/analyzer-core.node
cd analyzer-core && bunx @napi-rs/cli build --release

# WASM renderer → vello-renderer/pkg/ (wasm-bindgen output: _bg.wasm + .js + .d.ts)
cd vello-renderer && wasm-pack build --release   # requires the Rust + wasm toolchain

The desktop build wires the per-platform sidecar via bun run tauri:sidecar (scripts/build-sidecar.mjs).

Benchmarks (bench/)

The bench suite tracks performance and guards correctness and layout stability — and the golden/stability snapshots run inside bun test, so CI gates them on every PR.

bun run bench           # measure all fixtures, write bench/results/latest.json
bun run bench:check     # fail if a metric regressed past its threshold (vs baselines)
bun run bench:update    # rewrite bench/baselines.json
bun run bench:fetch     # clone the optional pinned real-world repos
bun test bench/         # golden-graph + layout-stability snapshot tests

What's tracked: scan/layout/memory time per fixture; golden graphs (structural snapshot — counts by kind, cycles, top hubs, content hash); layout stability (node positions per algorithm, ±2px); and a synthetic 100k-scale path (SCALE_SIZES default 1000 / 8000 / 100000). Absolute timings are machine-dependent, so baselines only mean something on the machine that produced them; CI runs bench in report mode.

Updating snapshots is intentional. A changed golden/stability snapshot means the analyzer's output or a layout changed — review the diff before committing: bun test bench/golden.test.ts --update-snapshots · BENCH_UPDATE=1 bun test bench/stability.test.ts

Testing

bun test runs unit tests (*.test.ts next to the code) using happy-dom + Testing Library for the React pieces. The pure modules — kernel, layout, query language, rules engine, diff, exports, editor commands — are heavily unit-tested; follow the adjacent-*.test.ts pattern for new code. See Releasing & Contributing for the pre-push gates.

Clone this wiki locally