A fast, dependency-light CLI that turns Git history into a graph — right in your terminal, or exported as PNG/SVG/HTML.
git log --graph gets unreadable fast once a repo has real branch/merge structure. git-visualizer shells out to git log --topo-order with a NUL-delimited pretty-format, runs the commit DAG through its own lane-assignment algorithm, and renders the result as a clean, colored graph — either as box-drawing characters in your terminal or as a static PNG/SVG/HTML file you can drop in docs or a PR.
It's a portfolio project: no framework magic, no native-git bindings — just Node's child_process, a hand-rolled layout engine, and a renderer per output target.
- Terminal graph rendering — one line per commit with rounded box-drawing connectors (
╭ ╮ ╰ ╯ ┼), colored lanes,[branch]/[origin/x]/[⚑ tag]badges, and relative timestamps. Adapts to terminal width and disables color automatically when piped or whenNO_COLORis set. - Static export —
--export svg|png|htmlrenders the same graph to a file. PNG is rasterized with@resvg/resvg-js(no headless browser); HTML export produces a standalone report. - Filtering — narrow history by
--branch,--author(regex),--since(e.g."30 days ago"), and--max-commits(0 = unlimited), all translated directly intogit log/git rev-listarguments. - Local web server —
--webstarts a Node HTTP server (binds to127.0.0.1only) exposing a JSON API (/api/graph,/api/commit/:sha,/api/search,/api/branch-rows) with pagination, in-memory layout caching, and SHA/ref validation. The browser-side React app that consumes it (theming and typed fetch client are in place) is still under active development. - Handles big histories without choking — commits are parsed from a streamed
git log, so memory stays flat on 50k+ commit repos; the lane-assignment layout is O(commits × active lanes), not O(commits²). - Clear failure modes — a
GitErrortype distinguishes "not a git repo," "git not installed," and "unknown ref" and prints an actionable one-line message instead of a stack trace.
- TypeScript (strict, ESM) throughout
- Commander for CLI flag parsing
- Picocolors for terminal color (plus a small custom xterm-256 helper for the lane palette)
- @resvg/resvg-js for native SVG → PNG rasterization
- Node's
httpmodule for the embedded web server (no Express — four routes didn't justify a framework) - React 18 + Zustand + D3 (
d3-selection,d3-zoom) + Tailwind + Vite for the in-progress browser UI - tsup to bundle the CLI, Vitest configured for the test suite
- Zero dependency on git bindings — everything shells out to the system
gitbinary viachild_process
git clone https://github.com/advayiscoding/Git-visualizer-cli-tool.git
cd Git-visualizer-cli-tool
npm install
npm run build
npm link # optional: exposes the `git-visualizer` command globallyRun inside any Git repository:
# Render the graph for the current repo in your terminal
git-visualizer
# Only a specific branch
git-visualizer --branch main
# Filter by author (regex) and time window
git-visualizer --author "advay" --since "30 days ago"
# Cap (or lift the cap on) how many commits are rendered
git-visualizer --max-commits 500
git-visualizer --max-commits 0 # unlimited
# Export a static graph instead of printing to the terminal
git-visualizer --export svg -o history.svg
git-visualizer --export png --theme light
git-visualizer --export html -o report.html
# Start the local web server (binds to 127.0.0.1)
git-visualizer --web --port 7644
git-visualizer --web --no-openFull flag reference:
Usage: git-visualizer [options]
Visualize Git repository history as an interactive graph — in the terminal, the browser, or an exported file.
Options:
-V, --version output the version number
-w, --web open an interactive graph in the browser
-p, --port <number> port for the web server (default: 7644)
--no-open do not auto-open the browser in --web mode
-b, --branch <name> show only history reachable from this ref
-a, --author <pattern> filter commits by author (regex, like git log --author)
-s, --since <date> only commits newer than a date, e.g. "30 days ago"
-e, --export <format> export instead of displaying: png | svg | html
-o, --output <file> output file for --export (default: ./git-visualizer-export.<ext>)
-t, --theme <theme> export theme: dark | light (default: "dark")
-n, --max-commits <count> max commits in terminal/export mode, 0 = unlimited (default: 2000)
-h, --help display help for command
src/git/—repository.tslocates the repo root and runs/streamsgit;log.tsstreamsgit log --topo-orderwith a NUL/RS-delimited custom format (no escaping concerns, flat memory on huge histories);refs.tspulls branches/remotes/tags viagit for-each-ref, peeling annotated tags to their commit SHA.src/graph/layout.ts— the core algorithm. Walks commits in topological order maintaining an array of "active lanes," each tracking the parent SHA it's traveling toward. Converging commits merge into the lowest matching lane; branch tips claim the lowest free lane so the graph stays compact instead of growing unbounded width. First parents continue their commit's lane (so a branch reads as one continuous line); merge parents either join an existing lane or open a transient one.src/render/—ascii.tsturns the lane/edge layout into a terminal grid with box-drawing glyph merging (precedence: node > corner > crossing > line);svg.ts/html-report.tsrender the same layout as static output;themes.tsdefines the shared dark/light color tokens used by both static export and the web UI.src/export/— dispatches to SVG, PNG (viaresvg), or HTML, each with a row cap sized to keep output files sane (e.g. PNG caps at 1,500 rows to avoid multi-million-pixel images).src/server/— a plainhttp.createServerexposing a small JSON API over the same snapshot/layout pipeline, with an in-memory LRU-ish cache keyed by filter combination and static-file serving (with path-traversal guards) for the browser UI build indist/ui.
- CLI design — flag parsing, validation, and help text with Commander; sane defaults; distinct exit paths for terminal/export/web modes
- Git internals — driving
git log/git for-each-ref/rev-listplumbing directly, understanding topological ordering, parent chains, detached HEAD, and annotated tag peeling - Algorithm design — a from-scratch DAG lane-assignment/layout algorithm (the same family of technique used by
tigand GitKraken-style graph viewers), reasoned about for both correctness and complexity - Terminal UI rendering — building a character-grid renderer with Unicode box-drawing glyphs, ANSI 256-color output, glyph-merge precedence rules, and responsive width handling
- Streaming & performance — parsing an unbounded
git logstream incrementally instead of buffering, keeping memory flat on 50k+ commit repositories - Small-footprint HTTP services — a dependency-free Node
httpserver with a JSON API, input validation, and static-asset traversal protection - TypeScript project structure — strict, ESM-first, modules cleanly separated by concern (
git/graph/render/export/server/ui) with shared types
MIT