Interactive visualiser for classical pathfinding algorithms on Euclidean graphs. Rust core, WASM-powered browser UI, side-by-side benchmarks.
Live demo: https://afitzy98.github.io/pathviz/
All implementations live in core/src/algo and share a single Solver-style API plus a common test suite (10 shared invariants + per-algorithm tests).
| Algorithm | Optimises | Notes |
|---|---|---|
| Dijkstra | min total weight | Priority-queue search, non-negative weights |
| A* | min total weight | Dijkstra + Euclidean heuristic → fewest nodes expanded |
| BFS | min hop count | FIFO queue; ignores edge weights |
| Bidirectional Dijkstra | min total weight | Two Dijkstras meeting in the middle |
| Bellman-Ford | min total weight | V−1 relaxation passes; detects negative cycles |
pathviz/
├── core/ # Pure Rust: graph types, generator, algorithms, testkit
├── wasm/ # wasm-bindgen layer — exposes solve() + generate_graph()
├── cli/ # Two binaries:
│ # `pathviz-cli` — solve a graph from the terminal
│ # `bench` — benchmark all algos, emit JSON
└── web/ # Vite + React frontend (consumes wasm/pkg)
- Rust stable (1.80+) with the
wasm32-unknown-unknowntarget wasm-pack- Node 20+ and npm
# 1. Build the WASM bindings
cd wasm
wasm-pack build --target web --release
cd ..
# 2. Install web deps and start Vite
cd web
npm install
npm run dev
# open http://localhost:5173/The Vite dev server serves from / locally and from /pathviz/ in production — this is handled in web/vite.config.ts.
cargo test --workspace # 89 tests across the algo crate
cd web && npx tsc -b --noEmit # TypeScript type-checkThe bench binary runs every algorithm against 4 graph sizes (50/100/300/1000 nodes) with a fixed seed, 25 warmup + 250 timed samples per config, and writes a JSON report the Benchmarks tab renders as a grouped bar chart.
cargo run --release -p pathviz-cli --bin bench -- web/public/benchmarks.jsonResults are measured on the native Rust binary — the browser runs slightly slower due to WASM overhead and JSON serialisation across the JS ↔ Rust boundary. The Benchmarks tab makes this explicit.
# Solve a 200-node graph with A*
cargo run --release -p pathviz-cli -- --algo astar --nodes 200 --repeats 5
# Dump the full graph + solve trace to JSON for offline inspection
cargo run --release -p pathviz-cli -- --algo dijkstra --dump /tmp/solve.jsonCI runs on every push; the Deploy workflow publishes to Pages on every merge to main.
One-time repo setup:
- Push the repo to GitHub.
- Settings → Pages → Source: GitHub Actions.
- Merge something to
main(or run theDeployworkflow manually from the Actions tab).
The deploy workflow:
- installs the Rust toolchain + wasm-pack
- builds the WASM bindings
- runs the benchmark binary, writing fresh results into
web/public/benchmarks.json npm ci && npm run buildinweb/- uploads
web/distas the Pages artifact and deploys
- Trace vocabulary: algorithms emit
Step::Visit(u),Step::Relax { from, to, new_distance }, andStep::Pass(n)(Bellman-Ford only). The React app reconstructs which edges have been relaxed up to the current playback index and highlights the active step. - Undirected Euclidean graphs: the generator does rejection-sampled scatter, then k-NN with symmetrisation, then stitches any disconnected components by closest-pair bridges. See
core/src/generator.rs. - Negative cycles: Bellman-Ford returns a
NegativeCycle { cycle: Vec<usize> }outcome when it detects one. The UI highlights the cycle in red. (In practice this only fires on hand-built graphs — the generator only produces non-negative weights.)
MIT. See LICENSE.