Your codebase, mapped for agents.

A small index and an interactive map, generated locally in one pass.

$ stacklit derivegin v1.10.0, 137 tokens
gin | go | 8 modules | 19,537 lines | Gin, GitHub Actions, net/http
test: go test ./... | env: PORT

modules:
  .github             .github
  .github/workflows   workflows
  binding             binding | depends: bytesconv, json
  ginS                gins
  internal/bytesconv  bytesconv | depended-by: binding, render, root
  internal/json       json | depended-by: binding, render, root
  render              render | depends: bytesconv, json
  root                root package | depends: binding, bytesconv, json, render
do-not-touch: .github/

Install, then run it in your repo

Pick one. The first run scans the current directory and writes the index.

  • $ npx stacklit init No install. Downloads the binary on first use.
  • $ brew install glincker/tap/stacklit Homebrew tap for macOS and Linux.
  • $ go install github.com/glincker/stacklit/cmd/stacklit@latest From source, needs Go.

Then commit stacklit.json, and run stacklit setup to wire up your AI tools. Quickstart

What a run looks like

The real output of stacklit generate --graph on gin v1.10.0 (101 files) from a cold cache. It writes stacklit.json, a Mermaid diagram and a self-contained HTML map.

Browse the generated maps

$ stacklit generate --graphgin v1.10.0
[stacklit] found 101 files
[stacklit] parsed 101 files (0 errors, 0 cached)
[stacklit] done in 37ms -- wrote stacklit.json, DEPENDENCIES.md, stacklit.html

What you get

An index agents can read

Modules, what each exports, who depends on whom, and hints for tests and where to add code. Plain JSON you commit next to the source.

Index format

stacklit.json, one modulegin v1.10.0
{
  "render": {
    "purpose": "Render",
    "language": "go",
    "files": 15,
    "lines": 1304,
    "exports": [
      "type JSON",
      "type IndentedJSON",
      "type SecureJSON",
      "type JsonpJSON"
    ],
    "depends_on": [
      "internal/bytesconv",
      "internal/json"
    ],
    "depended_by": [
      "root"
    ]
  }
}

Excerpt. Export lists are capped by default, so a module entry is not exhaustive.

A small map to steer the agent

stacklit derive prints a compact map of a few hundred tokens. stacklit setup injects it into the config of your assistant, so a new session starts oriented. The same graph answers token-budgeted queries, also exposed as MCP tools.

Assistants and setup

$ stacklit query "how are route params bound to a handler" --budget 500excerpt
query "how are route params bound to a handler"
60 seeds, 83 candidates
context.go
  404-406 func (c *Context) Param(key string) string  // Param returns the value of the URL param.
gin.go
  298-301 func (engine *Engine) NoRoute(handlers ...HandlerFunc)  // NoRoute adds handlers for NoRoute.
  336-358 func (engine *Engine) addRoute(method, path string, handlers HandlersChain)
      calls tree.go::node.addRoute E0.90
  605-671 func (engine *Engine) handleHTTPRequest(c *Context)
ginS/gins.go
  41-43 func NoRoute(handlers ...gin.HandlerFunc)  // NoRoute adds handlers for NoRoute.
      calls gin.go::Engine.NoRoute I0.55
routergroup.go

Output cut to the first lines. MCP tools

A map you can open

Every run also writes one HTML file with graph, tree, table and flow views. No server and no build step. Six maps generated from pinned public repos are on the demos page.

See the demos

stacklit exportformats
Markdown index, GraphML, Cypher, JSON, DOT,
Mermaid, an Obsidian vault, a markdown wiki

From the commands reference. Commands

The same bytes every time

Output has no timestamps by default, so the file changes only when the code does. Two cold runs on the same checkout gave one hash.

Keep it fresh in CI

$ shasum stacklit.jsontwo cold runs
run 1  03b6d695713b8088911157b95a0e5c2303a00007
run 2  03b6d695713b8088911157b95a0e5c2303a00007
$ stacklit diff
Index is up to date. No source changes detected.

Works with

Setup covers 26 assistants. These are some of them. Aider has no logo on thesvg.org, so it keeps its letter.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Cline
  • Zed
  • Codex
  • Gemini CLI
  • Continue
  • OpenCode
  • Junie
  • Kilo Code
  • Aider

Any MCP client works through stacklit serve, and anything else can read stacklit.json directly. Logos load from thesvg.org when you view this page. Without them the letters stay.

Plain terms

  • MIT licenseRead it, fork it, ship it.
  • FreeNo paid tier, no gated features, no account.
  • Local onlyNo telemetry, no upload.
  • One Go binaryNothing to run alongside it.
  • DeterministicSame code, same bytes.

What we measured

47 "where is this implemented?" tasks across 6 pinned public repos in six languages, run on 2026-11-08. No model was involved, and tokens are bytes divided by four. Intervals are 95% bootstrap intervals over tasks.

ApproachFound firstFound in top 5Tokens to find
grep and read89% [81-98]100% [100-100]5.9k [3.8k-8.7k]
BM25 over the question57% [43-72]89% [81-98]11k [6.7k-15k]
stacklit map plus lookup55% [40-70]74% [62-87]5.9k [4.6k-7.3k]
stacklit query 1000, read in printed order81% [70-91]96% [89-100]9.1k [6.2k-13k]
  • Grep and read leads on accuracy, and its search pattern was written by someone who knew the answer. The query command's gap to it, in percentage points with an interval, is -9 [-23, +6] at found first and -4 [-11, +0] at top 5. Both intervals reach 0, so the gap is suggestive, not settled.
  • The token intervals overlap. We claim no token saving over grep or BM25, and when you already know the exact symbol, grep is cheaper than loading a map.
  • The query command used to print files sorted by path. Printed by relevance, the order an agent reads it, it beats BM25 on finding the right file first. It is a proxy, not an agent evaluation, and the scoring was tuned after looking at some benchmark failures.

Index size on each repo. Generation times are on the benchmark page, where they are marked as upper bounds from a loaded machine.

RepoLanguageSource linesModulesstacklit.json tokensderive map tokens
ginGo19,53782,491137
flaskPython18,515142,818221
honoTypeScript57,2637716,0221,351
ripgrepRust52,215348,586477
gsonJava53,490155,748340
rackRuby19,80592,391151

Read the full benchmark page, with 58 tasks in all, methodology, the dependents results and limitations.