Claude Code & coding agents

Graphify tested: what the knowledge graph of your code sees and what it misses (November 2026)

Graphify turns your code into a knowledge graph your coding agent can query. Tested on 153 PHP files: fast and free, but code outside a function gets no edges at all. What the token claims are worth, and a script to check your own project.

Erik van de Blaak
Erik van de Blaak
18 min read • 26 views
Graphify tested: what the knowledge graph of your code sees and what it misses (November 2026)

I asked Graphify what would be affected if I changed Auth::requireAuth(), the function that puts every admin page of this site behind a login. The answer came back in half a second: No affected nodes found. Eighteen files call that function. A coding agent that believes the answer could change or remove the check on the assumption that nothing depends on it.

In November 2026 Graphify is one of the fastest-growing developer tools on GitHub, with more than 144,000 stars in seven months. It promises that your coding agent uses fewer tokens because it consults a knowledge graph of your project instead of grepping. I ran version 0.9.104 on the 153 PHP files of this website, read the source of its benchmark and looked up the independent measurements. Below: what the program does, what it is good at, why it misses half of an ordinary PHP site, and how to check that in your own project in ten seconds.

Short answer. Graphify (Python, Apache 2.0) turns your code into a graph of classes, functions, calls and imports, with tree-sitter and without a language model. Your agent queries that graph with graphify query, path, explain and affected. For code inside classes and functions this is fast and reliable: 153 files in 3.5 seconds. Code that sits directly in a file, outside any function, gets no edges at all. On this site that means the graph misses 21 of the 25 files that use the class Post. The promised token savings have not been independently confirmed. Use it as a map of your architecture, not as proof that something is unused.

What is Graphify?

Graphify is a command-line program and a skill for coding agents such as Claude Code, Codex, Cursor and Gemini CLI. It reads a folder of code, and optionally documents, PDFs and images, and writes three files: graph.json with the full graph, GRAPH_REPORT.md with the most important nodes, and an interactive graph.html. The agent then asks the graph questions instead of opening files.

The repository appeared on 3 April 2026, a day after Andrej Karpathy described on X how to build personal knowledge bases with language models. Its maker, Safi Shamsi, writes that the project went viral 48 hours after that post. The company, Graphify Labs, is now in Y Combinator's summer 2026 batch and sells a paid cloud version. The open-source program was MIT-licensed until 22 July and has been Apache 2.0 since, for the explicit patent grant. If you want to know how Karpathy works with agents: I wrote earlier about Andrej Karpathy's skills.

Watch the package name. On PyPI it is graphifyy, with two y's; the command itself is graphify. The README warns that other packages with "graphify" in the name are not from the makers, and issue #280 already pointed out that confusion.

How does Graphify build the graph?

According to its own explanation it works in three passes, and only the last one costs money.

PassWhatHowCost
1. CodeClasses, functions, methods, calls, imports, inheritancetree-sitter, about 40 languages (33 with a tree-sitter grammar, 7 with a built-in parser)Free, local
2. Video and audioTranscriptfaster-whisper, localFree, compute
3. Documents, PDFs, imagesConcepts and relationsSubagents of your coding agent, or an API (Gemini, Claude, OpenAI, Kimi, Ollama …)Tokens

Then the Leiden algorithm splits the graph into groups of densely connected nodes, the "communities". Without the optional leiden extra, the README says Graphify silently falls back to Louvain, an older algorithm with the same goal. Every edge gets a label: EXTRACTED when the relation is literally in the code, INFERRED when Graphify derives it (with a score from 0.55 to 0.95), AMBIGUOUS when it is unsure. There are no embeddings and no vector database. That is a deliberate choice and a real difference from searching by meaning with vectors: Graphify only finds what is literally connected.

That third pass adds up faster than you might expect. One user measured 28,000 to 30,000 tokens per image, another paid $4.31 where $1.50 was expected. --code-only skips that pass. That is what I used.

The test: 153 PHP files of this site

This website runs on PHP without a framework: classes in classes/ with a small autoloader, and pages such as blog/post.php that call new Post() at the top and then output HTML. That is the shape of countless PHP projects, from old custom sites to WordPress themes. I installed Graphify 0.9.104 in a separate Python environment and ran it on a copy of every PHP file in git, without the migrations and vendor/: 153 files, 29,304 lines.

uv venv --python 3.12 venv
uv pip install --python venv/Scripts/python.exe "graphifyy==0.9.104"
cd site
set GRAPHIFY_BACKEND=none
venv\Scripts\graphify extract . --code-only

GRAPHIFY_BACKEND=none switches off every language model, including the one that names the communities. On my laptop (Windows 11, i9-13980HX, 16 GB) a cold run took 3.4 to 3.8 seconds, and 1.7 seconds with the cache. Graphify processes files in parallel in 32 worker processes.

[graphify extract] found 153 code, 0 docs, 0 papers, 0 images
  warning: 53 code file(s) yielded no symbols (0.18 MB) — a data file, or source
  this extractor models no symbols for: 404.php, admin/_sidebar.php, admin/activity.php, …
[graphify extract] wrote …/graph.json: 957 nodes, 1360 edges, 124 communities

The list of most-connected nodes ("god nodes") is right: Database with 32 edges, then Backup, Post, SearchConsoleClient, HealthCheck, Portfolio and Auth. Someone who has never seen this code knows where to start after reading those ten lines. 92 percent of the edges are EXTRACTED. The JavaScript in the <script> blocks of the PHP pages is in the graph too, since version 0.9.64 of 18 September.

The rest of the report is less useful. The communities are called "Community 0" to "Community 123", because naming them takes a language model. The "surprising connections" are five test files calling the class they test. And the warning about 53 files without symbols turned out to be the most important line of the whole output.

The graph does not see code outside a function

Those 53 files are not data files. They are the pages of the site: the home page, the blog, the RSS feed, the whole admin area. They contain no classes or functions, just code that runs from top to bottom. Two five-line files show what happens then:

Left, two PHP files. page.php calls new Post(), getBySlug() and Post::description() directly in the file: Graphify turns it into 0 nodes and 0 edges. page_fn.php does the same inside a function render(): Graphify creates 3 edges to Post, getBySlug() and description(). Right, the numbers for this site: of the 25 files that use Post, 4 are in the graph; of the 18 files that call Auth::requireAuth(), none are; and graphify affected answers No affected nodes found.
The same three calls: 0 edges outside a function, 3 inside one. Measured with Graphify 0.9.104 on 9 November 2026.

This is not a PHP bug. Graphify attaches a call to the function or method it sits in. Code at the top of a file has no such wrapper, so there is no "caller" and therefore no edge. A user described this in July in issue #1972 as "uniform across languages": it applies to Python scripts, Ruby rake files and plain JavaScript modules as well. A fix that uses the file itself as the caller has been waiting since 19 July in pull request #2016, but has not been merged as of 9 November.

For a project where everything lives in classes, this hardly matters. A Laravel app with controllers, models and services should be mostly visible; that is an inference from how the extractor works, I did not test a Laravel project. For a site like this one the gap is large, and exactly where it hurts. Admin pages start with an access check, and that check always sits at the top.

Ask the graph about such code and you get no error, just an empty answer. graphify affected ".requireAuth()" reports No affected nodes found., and an agent following the instruction to consult the graph first may read that as "nobody uses this".

How to check your own project

The following script puts graph.json next to a plain text search. It looks up the class and its methods in the graph, collects the files with a real edge to them (call, import, reference), and compares those with the files that contain new ClassName or ClassName::. It needs PHP 7.4 or later and no packages.

graph-blind-spots.php

<?php
declare(strict_types=1);

/**
 * graph-blind-spots.php: puts Graphify's graph.json next to a plain text search.
 * Usage: php graph-blind-spots.php <project-dir> <ClassName>
 * Lists the PHP files that use the class (new X, X::) but have no edge to X in the graph.
 * Exit code: 0 = no blind spots, 1 = blind spots found, 2 = bad input.
 */

if ($argc !== 3) {
    fwrite(STDERR, "Usage: php {$argv[0]} <project-dir> <ClassName>\n");
    exit(2);
}
[, $root, $class] = $argv;

$norm = static fn (?string $path): string => str_replace('\\', '/', (string) $path);
$root = rtrim($norm(realpath($root) ?: ''), '/');
if ($root === '' || !preg_match('/^[A-Za-z_][A-Za-z0-9_]*$/', $class)) {
    fwrite(STDERR, "Unknown directory or invalid class name\n");
    exit(2);
}

$graphFile = "$root/graphify-out/graph.json";
$json = is_file($graphFile) ? file_get_contents($graphFile) : false;
$graph = $json === false ? null : json_decode($json, true);
if (!is_array($graph) || !isset($graph['nodes'])) {
    fwrite(STDERR, "No readable $graphFile. Run first: graphify extract . --code-only\n");
    exit(2);
}

// 1. The class node and its methods (Graphify links methods with the relation "method").
$targets = [];
foreach ($graph['nodes'] as $node) {
    if (($node['label'] ?? '') === $class) {
        $targets[$node['id']] = true;
    }
}
if ($targets === []) {
    fwrite(STDERR, "Class $class is not in the graph\n");
    exit(2);
}
$edges = $graph['links'] ?? $graph['edges'] ?? [];
foreach ($edges as $edge) {
    if ($edge['relation'] === 'method' && isset($targets[$edge['source']])) {
        $targets[$edge['target']] = true;
    }
}

// 2. Files in which the graph has a real edge to those nodes (structural edges do not count).
$structural = ['method' => true, 'contains' => true];
$inGraph = [];
foreach ($edges as $edge) {
    if (!isset($structural[$edge['relation']]) && isset($targets[$edge['target']])) {
        $inGraph[$norm($edge['source_file'] ?? '')] = true;
    }
}

// 3. Files that use the class in their text.
$pattern = '/\bnew\s+\\\\?' . $class . '\b|\b' . $class . '::/';
$inText = [];
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($root, FilesystemIterator::SKIP_DOTS));
foreach ($files as $file) {
    $path = $norm($file->getPathname());
    if ($file->getExtension() !== 'php' || preg_match('#/(vendor|graphify-out|node_modules)/#', $path)) {
        continue;
    }
    if (preg_match($pattern, (string) file_get_contents($path))) {
        $inText[substr($path, strlen($root) + 1)] = true;
    }
}

$missing = array_keys(array_diff_key($inText, $inGraph));
sort($missing);
printf(
    "%s: %d files use the class, the graph has an edge for %d of them.\n",
    $class,
    count($inText),
    count(array_intersect_key($inText, $inGraph))
);
foreach ($missing as $path) {
    echo "  not in the graph: $path\n";
}
exit($missing === [] ? 0 : 1);

On this site:

$ php graph-blind-spots.php . Post
Post: 26 files use the class, the graph has an edge for 4 of them.
  not in the graph: admin/analytics.php
  not in the graph: admin/api-seo-ai.php
  …
  not in the graph: blog/post.php
  not in the graph: classes/PostRevision.php
  …
  not in the graph: tests/unit/slug_redirects.php

One of those 22 is a false alarm: classes/PostRevision.php only mentions Post::update() in a comment. Here the graph is smarter than a text search, because tree-sitter knows what a comment is. The other 21 are real calls, such as line 10 of blog/post.php: $postModel = new Post();. For Auth the gap is larger still: 33 files, 1 of them in the graph.

The script exits with code 1 when it finds blind spots, so you can put it in a CI step for the classes that a lot depends on. Tested with PHP 7.4.33, 8.2.35 and 8.3.36 on the graph of this site, on the two example files and on bad input.

Does Graphify really save tokens?

Three numbers circulate around Graphify, and each measures something different.

"Cut agent token spend by 80%" is at the top of the README, but it is about the paid cloud version. I found no measurement behind it, and neither did explainx.ai.

"71.5x fewer tokens per query" comes from the project's own documentation, measured on 52 files: Karpathy repositories, five papers and four images. For a six-file library the same table says "~1x". The comparison is always the graph's answer text against reading the whole corpus in one go.

The built-in benchmark reported "25.8x fewer tokens per query" on my code. I read its source to see where that comes from. When you call graphify benchmark on its own, it does not count your files. It estimates the size as the number of nodes times 50 words: 957 × 50 = 47,850 words, or about 63,800 tokens. My PHP files add up to 1,432,136 characters, which by the same rule of four characters per token is about 358,000 tokens. Two of the five test questions found nothing ("how does authentication work" and "how are errors handled") and are left out. So the number says little, in either direction.

More important: no agent ever reads a whole project to answer one question. An agent greps and then opens a few files. Against that way of working the difference is smaller, and that has been measured:

  • In issue #985 (May 2026, still open) a user who introduced Graphify at their company writes that "Claude Code alone seems to provide similar results with the same or even lower token consumption". A second user measured 1.6 to 1.9 times higher cost with Graphify on a large .NET monorepo, for a less complete answer.
  • Srijan, who contributes code to Graphify, ran 360 trials on Airflow, VS Code and Spring with Claude Code and Codex (16 October). The conclusion: the graph did not make strong agents "clearly more accurate or cheaper". The agents found the right files with grep in the first few steps and then read them anyway. A new version of the hook saved about 13 percent in a small run.
  • The project's own benchmark on ERPNext, a codebase of roughly a million lines, shows something positive: with Graphify as an extra tool the answers covered 82.0 percent of the key facts, against 70.8 percent with grep alone. That is six questions, at about 140,000 tokens per question, measured by the makers.

My reading: the graph helps with questions about structure in a large, unfamiliar project, such as "how do these two subsystems connect?". For "where is this function?" grep is done in one step and cheaper.

I also noticed that the search works literally. graphify query "how does authentication work" returned "No matching nodes found", because the class is called Auth, not "authentication". graphify query "how does Auth check the CSRF token" did return a tidy subgraph of 24 nodes with every CSRF method and its line number. The question has to contain the names in your code.

What Graphify changes in Claude Code

graphify claude install adds a block to CLAUDE.md with the rule: "run graphify query before your first grep, search or source-file read". It also adds a PreToolUse hook that nudges the agent when it starts searching or reading files anyway. With --strict that hook even denies a read once per session, when the graph knows the file and the agent has not queried the graph in the last half hour. If you are new to Claude Code: rules like these decide how the agent works, so read them before you install them.

Those nudges cost money. A user counted in issue #3435 8,348 reminders in 87 sessions, about 651,000 tokens together, 3.7 times more than all real Graphify queries in those sessions. That is capped now: five reminders per session by default (GRAPHIFY_HOOK_NUDGE_CAP).

Another problem still exists. Issue #3791 reports that reinstalling can wipe everything in CLAUDE.md below the Graphify block when no heading with a single # follows that block. The reporter lost 217 lines. I ran the reproduction from the issue with 0.9.104, in a temporary folder via CLAUDE_CONFIG_DIR: the file went from 7 lines to 3, and my "## My own rules" section was gone. There was no warning; the output ended with a link to the cloud trial. So copy your CLAUDE.md before you install, or install per project with --project in a folder under git.

Security and privacy

  • Code stays local as long as you use --code-only or set GRAPHIFY_BACKEND=none. Without that, graphify extract picks a provider based on the API keys it finds, in the order Gemini, Kimi, Claude, OpenAI. The README notes that Kimi goes to Moonshot AI servers in China.
  • Every query is logged to ~/.cache/graphify-queries.log: time, question, project. Switch it off with GRAPHIFY_QUERY_LOG_DISABLE=1.
  • graph.html loads a script from the internet: vis-network 9.1.6 via unpkg.com. Open the graph offline or on a locked-down machine and you see nothing.
  • Do not index code you do not trust with an old version. Security advisory GHSA-pcc4-rvhr-2pr8 (severity high, 27 September) describes how a Fortran file with a crafted #include could pull files from your computer into the graph, such as an SSH key. Fixed in 0.9.70.

When is Graphify worth it?

SituationAdvice
Large, unfamiliar project built from classes (Java, C#, Laravel, Symfony)Try it. The report and graphify path give a quick overview, and building costs nothing.
Code with many standalone scripts or pages (PHP without a framework, WordPress themes, Python scripts)Only as an architecture map. Do not trust affected; run the check script above.
Small project, or one you know wellSkip it. Grep is faster and the agent reads the files anyway.
Documents, PDFs and code together in one graphOnly with a budget: the third pass costs tokens per file.
Refactoring or deleting based on "what depends on this"Not on the graph alone. No edge means "unknown" here, not "nothing".

Frequently asked questions

Is Graphify free?

Yes. The open-source program is Apache 2.0, and building a code-only graph costs no tokens. You only pay for the semantic pass over documents, PDFs and images, or for Graphify Labs' cloud version.

Does Graphify send my code to a language model?

Not the code: that is read locally with tree-sitter. Documents, PDFs and images do go to your coding agent's model or to an API whose key you have set. --code-only or GRAPHIFY_BACKEND=none rules that out.

Does Graphify work with PHP?

Yes, for classes, functions, methods, closures, use imports, new and static calls inside functions. Code that sits directly in a file, outside any function, gets no edges in version 0.9.104 (issue #1972). require_once and include are not recorded as imports.

How is this different from a vector database or RAG?

A vector database finds text whose meaning resembles your question. Graphify finds what is connected in the code: who calls whom, who inherits from whom. That is why it found nothing for "authentication" while the class is called Auth.

How do I remove Graphify again?

graphify uninstall removes the skill, the CLAUDE.md block and the hooks for all platforms, and --purge also deletes graphify-out/. Copy CLAUDE.md first here too: the reporter of issue #3791 suspects, from reading the code, that uninstalling has the same bug as installing.

A knowledge graph that says nothing depends on requireAuth() is more dangerous than no knowledge graph, because the answer sounds so certain. Graphify is a well-made map of what is in your classes and functions, free to build and ready in a few seconds. So read an empty answer as "the graph does not know", and let your agent grep in that case. Run the check script once on your own project: then you know how large the unknown part is for you.

Further reading on this site

Sources

Official documentation and source code

Issues and pull requests

  • #1972 code outside a definition gets no edges (17 July 2026, open) and PR #2016 with a fix (19 July 2026, open)
  • #985 Graphify versus Claude Code alone (22 May 2026, open)
  • #3435 token cost of the hook (9 September 2026, closed 12 October)
  • #3791 install wipes content of CLAUDE.md (24 September 2026, open)
  • #450 and #730 cost of the semantic pass; #280 confusion over the package name

Independent and other sources

Own measurements

  • 9 November 2026, Windows 11, Intel i9-13980HX, 16 GB, Python 3.12, graphifyy 0.9.104 without extras (so Louvain instead of Leiden), GRAPHIFY_BACKEND=none. Corpus: the 153 PHP files of vandeblaak.com tracked in git, without migrations and vendor, 29,304 lines, 1,432,136 characters. Timings: three cold runs (3.4 to 3.8 s) and three runs with the cache (1.7 s), measured with PowerShell Measure-Command.
  • "Uses the class" counts come from a text search for new ClassName and ClassName::; for Post one hit is a comment line (counted in the 26, not in the 25). The 18 calls to requireAuth were checked by hand.
  • Issue #3791 reproduced with the steps from the issue, in a temporary folder via CLAUDE_CONFIG_DIR.
  • The check script was tested with PHP 7.4.33, 8.2.35 and 8.3.36.

Share this article

Erik van de Blaak

Written by

Erik van de Blaak

AI Solutions Engineer & Full-Stack Developer

Erik van de Blaak is an AI Solutions Engineer and full-stack developer at CareerValue BV. Here he writes about AI coding tools and agents, such as Claude Code.

Comments (0)

Comment on this article

Never published

I read every comment before it goes online.

No comments on this article yet.