gitatlas.
GitAtlas

MIT open source / local only / 21 languages

One map. Every repo. Down to the function.

Point it at a folder of repositories, or at a GitHub repo. Get one interactive HTML file that zooms from your whole system, to a repo, to a module, to a single function. No server, no cloud, no account. Your code never leaves your machine.

shell
$ npm install -g gitatlas $ gitatlas extract /path/to/your/repos $ gitatlas extract expressjs/express # or any GitHub repo # open the index.html it prints. # that is the whole install.
21languages
4zoom levels
1HTML file
0servers
module level / payments-stack
exact resolved inferred call hub

01 the bottleneck moved

Agents write the code now. Somebody still has to understand it.

Writing code stopped being the bottleneck. Understanding a codebase you did not write, and increasingly a codebase nobody wrote, is the expensive part. Your architecture diagram describes a company you no longer work at, and the one person who understood billing left in March.

gitatlas makes the map a file. One command, one HTML file, openable by anyone from the intern to the VP. It regenerates from the code, so it cannot drift the way the wiki diagram did.

02 the map

Four zoom levels. The camera flies between them.

x1

Tree

Every repo, directory, and file on one page, folding and unfolding, with languages and symbol counts inline.

x4

Group

Repos as nodes. The whole system at cruising altitude, small enough for a manager, honest enough for an engineer.

x16

Module

Files and their imports, shaded neighborhoods, red-ringed hubs. The level where refactors are planned.

x64

Symbol

Functions, classes, methods, inheritance, and gold call edges. Who actually invokes whom.

gitatlas module map of the flask repository, showing shaded neighborhoods and red-ringed hub modules gitatlas module map of the flask repository in the light theme
Fig. 01Real output: flask, click, and jinja in one map. 216 modules, 4,083 symbols, 6,679 edges.
Symbol level inside flask/app.py showing Flask class methods connected by gold call edges
Fig. 02Symbol level inside flask/app.py. Gold lines are calls: who actually invokes whom.

Neighborhoods are computed, not filed

Shaded regions group files that lean on each other and touch the rest lightly. When a utils file has quietly become load-bearing for billing, it shows up inside the billing neighborhood no matter which folder it lives in.

Hubs are where change ripples widest

A red ring marks the modules far above typical connection count. First place to look before a refactor, last place to edit casually on a Friday.

Press ⌘K and go anywhere

Type a few letters of any repo, file, class, or function across the entire group, and the camera flies to it. Hovering a node dims everything except its direct connections.

Command palette searching for render, returning results from both the click and flask repositories
Fig. 03The command palette searching for "render", returning results from both click and flask.

03 demo

Five real maps. Open one, or take it with you.

Each demo below is the actual extractor output for a well-known GitHub repository, untouched. One self-contained HTML file per map: open it in a new tab, or download it and open it on a plane. Every one was built with a single gitatlas extract command.

Python

FastAPI

A famous API framework with a clean layered structure. The best first impression of what a map looks like.

1,144 modules, 5,290 symbols, 6,396 edges

JavaScript

Express

Small and famous. The whole framework and its tests fit in one readable picture.

141 modules, 127 symbols, 84 edges

Go

Gin

A compact Go web framework with a clear module and handler split. Shows the tree-sitter side of extraction.

99 modules, 1,533 symbols, 2,434 edges

Python, 3 repos

Flask + Click + Jinja

Three related repos in one grouped map. The group level a single repo cannot show, with cross-repo neighborhoods.

3 repos, 216 modules, 4,097 symbols, 6,700 edges

Rust

ripgrep

A production CLI tool. Big enough for hub detection and neighborhood clustering to earn their keep.

110 modules, 3,333 symbols, 3,875 edges

No mockupsThese files are unedited extractor output. Regenerate any of them with gitatlas extract owner/repo.

04 feed it to your agent

Agents are brilliant sprinters with amnesia.

Every session, yours greps around, rebuilds a mental model from scratch, and bills you for it. Hand it the map instead. Both doors re-verify source fingerprints before answering, so an agent is never handed stale file:line data without a warning inside the result.

01brief 02scope 03find_symbol 04module_info 05check_freshness

A map that has drifted from the code is worse than no map. gitatlas check exits 1 when anything is stale, and gitatlas extract --if-stale is the one-liner for CI jobs and agent hooks.

digest for a system prompt
$ gitatlas brief --budget 1500 # token-budgeted markdown digest. # cuts are announced, never silent.
serve it over MCP
$ claude mcp add gitatlas -- gitatlas mcp \ --out /path/to/repos/.gitatlas # five tools over stdio. dependency-free.
stack trace to suspects
$ gitatlas scope --trace crash.txt # ranks the neighborhood around the crash.

05 the contract

Three rules it will not break.

1

The schema is the contract

Extractor and viewer never know about each other. They agree on a versioned JSON schema and nothing else, which is why you can throw the viewer away and feed the graphs to something else.

2

Artifacts are files

No daemon, no database, no required network. The map opens offline, on a plane, in a bunker. Only the webfonts phone home, and when they cannot, you get system faces and the exact same map. Handing it a GitHub repo is the one time it dials out, and only because you asked it to.

3

Every edge carries confidence

Edges are exact, resolved, or inferred. Guesses are drawn dashed and labeled. When helper() could be three different symbols, gitatlas emits no edge rather than a wrong one. Nothing is upgraded to a fact.

Nothing comes from a language model

Same repos in, pixel-identical map out, every run. Layout is computed once at extract time, sorted iteration, explicit tie-breaking. Determinism is load-bearing, and the tests assert it.

06 the instrument panel

Six commands. Twenty-one languages.

gitatlas extract <folder | github repo>Build the map
gitatlas check <folder | github repo>Exit 0 fresh, 1 stale
gitatlas briefToken-budgeted digest for agent context
gitatlas mcpServe the map to agents over MCP
gitatlas scopeRank the neighborhood around a bug signal
gitatlas siteHosted playground for public GitHub repos

A target is a folder or a GitHub repo, in whatever spelling you have on the clipboard: owner/repo, a browser URL, or a git@github.com:owner/repo.git address. The repo is shallow-cloned into ~/.gitatlas and refreshed in place on later runs, so check and --if-stale stay meaningful against a moving upstream. A path that exists on disk always wins. The reading commands take the same target: gitatlas brief --target owner/repo.

Pin a branch, tag, or commit with --ref v4.18.2, or paste the /tree/v4.18.2 URL you were already reading. Each ref gets its own clone and its own map, named for it, so a branch map is never mistaken for the default branch's.

TypeScriptJavaScript PythonGoJava RubyCC++ C#PHPRust KotlinSwiftDart ScalaLuaBash ElixirObjective-COCaml Zig

TypeScript and JavaScript go through the TypeScript compiler API. The other nineteen go through tree-sitter grammars compiled to WebAssembly, so the install has zero native build steps and works on Windows the first time.

>
Call edges resolve in 14 of the 21 languages so far. The rest still get symbols, imports, and inheritance.
>
No cross-repo edges yet. Repo A calling repo B over HTTP is invisible to static analysis. The boundary stitcher is next on the roadmap.
>
Unused-symbol rings are a hint, not a verdict. Matching is name-based and repo-local, so a function consumed from another repo looks lonelier than it is.
>
The viewer's fonts load from Google Fonts. d3 is vendored in, so the map itself renders offline. Only the type falls back to system faces.
Honest limitationsListed here on purpose. The full set lives in the internals doc.

07 ship it with the code

Every repo should ship with its own map.

The same way it ships with a README. Copy the GitHub Action from the repo and every push to main regenerates the map. Point it at GitHub Pages and it becomes a URL your team can bookmark.

shell
$ npx gitatlas extract /path/to/your/repos