19. October 2026
A code graph is only as useful as the things it leaves out. This release is mostly about that, plus a way to get the graph’s numbers out of the tool.
symgraph is a Rust command-line tool and MCP server that indexes a codebase with tree-sitter into a SQLite graph of symbols and the relationships between them: calls, imports, inheritance, field reads and writes. You then ask it questions, either from the shell (symgraph callers <symbol>, symgraph impact <symbol>) or from an AI coding agent over MCP (symgraph serve). It’s for anyone who wants an agent, or themselves, to answer “who calls this?” and “what breaks if I change it?” without grepping. It handles Rust, TypeScript, JavaScript, Python, Go, Java, C, C++, C#, Kotlin, Scala, Groovy and Ruby. I’ve written about it before, most recently in Making a Code Graph Admit What It Doesn’t Know.
v2026.10.18 is tagged, six commits since v2026.10.1, with 12 files changed (879 insertions, 50 deletions). Most of the change landed on 5 October, and the tag came on the 18th.
The one fix in the release is the one most of you will notice. Before this, a vendored mermaid.min.js had been the top fan-in node of a project. Fan-in is the count of things that depend on a node, so a bundled third-party file sat at the top of the “most depended-on” list, above anything you’d written. The code comment that records the change says exactly that.
Now symgraph marks minified files as generated, and the dependency graph leaves generated code out. A file counts as minified if its path ends in .min.js, .min.mjs, .min.cjs or .bundle.js, or if its first line is longer than 2,000 characters. The generated-code markers that were already there (protobuf stubs, // Code generated by … DO NOT EDIT, @generated) feed the same flag, and the code excludes flagged nodes from the graph queries I checked.
So if you’ve been reading module-graph or coupling-score output on a repository with a checked-in bundle, the ranking should now be about your code. I’ve seen this on one project, my own. The test covers mermaid.min.js, app.bundle.js and a synthetic minified line, but I haven’t measured it across a range of repositories.
One consequence for upgrading: this bumps the extractor version to 4. symgraph tracks extractor changes separately from schema changes because they fail differently. A schema mismatch can’t be read at all, while an old extractor reads fine and quietly answers with old semantics. An index built before the upgrade is recognised as stale, and symgraph status reports whether an index is current. Re-run symgraph index after upgrading. [unverified: whether symgraph index rebuilds a stale-extractor index in full or only re-reads changed files]
symgraph export: the graph as JSON Lines
The new command writes code-structure records as JSON Lines on stdout, for every git checkout under a directory laid out <owner>/<name>. The records follow the delivery schema of my software-analytics project, and the README says insight-collect streams them into insight after each sync. The invocation from the README:
symgraph export --mirrors ~/workspace --state ~/.symgraph-export --since 0
Five record types come out, and the graph is folded to directories first, which works the same in every language:
coupling_snapshot, one per repository: directories, dependencies, cycles, the largest cycle and its share, god-structs, dead internal symbols and parse coverage.directory_coupling, one per directory: fan-in, fan-out, instability, whether it’s in a cycle, and churn.coupling_edge, for the top --top directory pairs (default 50): strength, distance, volatility, impact and edge kinds.god_struct, for the top --top structs: public and total fields, inbound references, churn and score.change_impact, one per commit since the last export (the last --days on the first run).That last one arrived in its own commit, and it’s the one I’d look at first. For a commit it records the files changed, the directories touched, the direct and transitive dependent directories, a reach share, and whether the change touches a cycle. In short, it’s the blast radius of a commit, measured on the graph. One caveat from the README: the reach is read off the graph at the exported commit (graph_commit), not at the change’s own commit. So for an older commit the numbers describe how far that change reaches in today’s structure, not in the structure it was made into.
Re-sending is safe. Records name the checked-out commit, so they’re idempotent. Each commit gets a sequence number (source_seq) kept in the --state directory, and a repository is exported again only when its commit changes or when its last export is newer than the --since cursor, which covers records that were sent but not yet confirmed by the caller. Index the checkout you want measured, because export reads the index. [unverified: whether export triggers indexing itself or needs symgraph index run first on each mirror]
If you’re not feeding an analytics pipeline, this won’t matter to you. If you are, it’s the first time the coupling numbers have had a stable, machine-readable home outside the MCP tools.
The remaining commit is a toolchain bump, Rust to v1.99.0 (#15). It doesn’t change what you run. The README’s stated minimum Rust for building from source is 1.90, and the changelog lists a CI job that builds against exactly that toolchain.
From the README, with Homebrew on macOS or Linux:
brew tap grahambrooks/symgraph https://github.com/grahambrooks/symgraph
brew install symgraph
Upgrade with brew upgrade symgraph. The formula installs one symgraph binary that carries both the CLI and the MCP server (symgraph serve).
Without Homebrew, the install script works on macOS and Linux:
curl -fsSL https://raw.githubusercontent.com/grahambrooks/symgraph/main/install.sh | bash
Add -s -- --mcp after bash to also configure symgraph as an MCP server for Claude Code and Claude Desktop. Windows has an equivalent install.ps1, there’s an MCPB bundle for Claude Desktop on the releases page, and you can build from source with git clone and make install. All of those are in the README.
Then, in each project you use it on:
symgraph index
If you only take one thing from this release, make it that re-index. The graph you’ve been querying may have had a minified bundle near the top of it.