by , AWS's spec-driven AI IDE, and there was nothing equivalent for it. So I did what any reasonable developer does when they see a good idea: I ported it.
💸 Why this should matters to us (the token problem)
When you ask an AI agent to work on a complex task, "fix the auth bug", "add rate limiting to the API", "refactor the payment service", the agent needs to understand your codebase before it can do anything useful. The way it typically does that is by reading files, running grep, globbing directories. Every one of those is a tool call.
Tool calls cost tokens. Lots of them. And they're slow.
Aside from cost, we’re currently in a period where reasonable plans for using AI are either being rate-limited or subject to increasingly restrictive limits. The community is actively exploring solutions to optimize requests and responses, reduce token usage, and improve overall efficiency.
The insight behind KiroGraph (and CodeGraph before it) is simple: your codebase doesn't change that often. Between agent runs, you might touch a handful of files.
Why should the agent re-discover the structure from scratch every single time?
KiroGraph pre-indexes everything, functions, methods, classes, interfaces, types, call relationships, import graphs, type hierarchies, into a 100% local SQLite database. When Kiro needs context, it doesn't read files. It queries the graph. One MCP tool call instead of twenty file reads and multiple tool calls.
The impact is real: tasks that once consumed entire context windows simply don’t anymore: saving tokens, improving efficiency, and delivering greater speed.
⚖️ Benchmark
An image is worth a thousand words
parses every source file into an AST and extracts nodes (functions, classes, routes, components, 24 kinds total) and edges (calls, imports, extends, implements, references, and more). Everything lands in kirograph.db. This powers all the graph traversal tools: find callers, trace impact, detect circular deps, find dead code.
Semantic indexing is opt-in. When you enable it, KiroGraph generates 768-dimensional vector embeddings for every embeddable symbol using nomic-ai/nomic-embed-text-v1.5 (~130MB, downloaded once to ~/.kirograph/models/). This powers natural-language search, ask for "auth middleware" and get the relevant functions even if they're named validateJwt or checkPermissions.
The index stays fresh automatically via Kiro hooks.
File saved, mark dirty. Agent stops, sync if dirty.
Batched, efficient, zero overhead during active editing.
The agent knows what to do through a Kiro steering file, which the final KiroGraph adopter can easily adapt to suit their specific needs.
🧠 Is KiroGraph a RAG/GraphRAG?
It’s useful to compare KiroGraph to both a classic RAG system and a GraphRAG approach, because it sits somewhere in between—but also slightly outside both categories.
1) A local RAG works on unstructured text, splitting documents into chunks and retrieving the most relevant pieces via embeddings.
KiroGraph instead indexes code structure, where functions, classes, and relationships come directly from the AST.
This removes chunking entirely and replaces text retrieval with symbol-level navigation over a code graph.
2) GraphRAG builds graphs by extracting entities and relationships from documents, then uses them to improve retrieval quality.
KiroGraph doesn’t infer the graph from text, it derives it deterministically from the codebase structure itself.
As a result, its graph is not an approximation of knowledge, but a direct representation of the system architecture.
The key difference: RAG retrieves text, GraphRAG organizes text, KiroGraph represents code structure.
And embeddings in KiroGraph are optional, not foundational.
The core idea is not better retrieval, but queryable program structure with semantic enrichment on top.
brings ANN search to SQLite via a native extension. Sub-linear query time, stays in the SQLite ecosystem. Best for large codebases that don't want to run a separate process.
is PostgreSQL compiled to WASM with the pgvector extension. You get exact (not approximate) nearest-neighbour search, ON CONFLICT upserts, HNSW indexing, all the PostgreSQL semantics, in-process, no server. Pure WASM means no native binaries and no compilation. And because it's exact, results are deterministic and reproducible. I particularly like this one.
is a dedicated vector database, HNSW index, cosine distance, the full feature set. KiroGraph spawns the Qdrant binary as a managed child process via qdrant-local. The server runs as a persistent background daemon, state tracked in .kirograph/qdrant-server.json. This is the heavy option. You get Qdrant's full query capabilities and a proper production-grade vector store. The trade-off is you're now running a binary.
Here's every decision the installer walks you through, and why each one matters.
Enable semantic embeddings
Once you enable embeddings, the installer asks which HuggingFace model to use. The default is nomic-ai/nomic-embed-text-v1.5, a solid general-purpose model that produces 768-dimensional embeddings and runs well locally via Ollama.
You can enter any HuggingFace model identifier in org/model-name format. If you enter something non-standard, the installer rejects it and explains the expected format. If you enter a non-default model, it reminds you to run ollama pull <model> before indexing.
The reason this is configurable: embedding quality varies by domain. Code-specific models like jinaai/jina-embeddings-v2-base-code may outperform general models on certain queries.
Giving you control here means you're not locked in.
Semantic engine
Extract docstrings
This controls whether KiroGraph records the exact line and column of every function call when building call graph edges. Enabled by default.
With call sites tracked, you get precise "go to call site" information in addition to "which functions call this symbol". The kirograph_callers and kirograph_callees MCP tools return not just the caller's name and file, but the exact location of the call. This is what makes the call graph actually useful for debugging and impact analysis.
The trade-off is index size: call site data adds rows to the edges table. On codebases with millions of call expressions this can get large. If you only care about the structural shape of the call graph and not the precise locations, you can disable this to keep the database lean.
Indexing
is served by Qdrant itself. KiroGraph downloads the dist-qdrant.zip release asset, extracts it with unzip, caches it, and sets the env var before spawning the binary. The dashboard is then available at http://127.0.0.1:<port>/dashboard natively.
is a static React app. KiroGraph downloads it from GitHub, caches it at .kirograph/typesense/dashboard/, and serves it locally via a Node HTTP server.
by , are very interesting candidates. I should evaluate if they fit the ecosystem and what they offer as peculiarity. Maybe a "plugin system" would be a good implementation to let folks implement their preferred semantic engine.
More languages and frameworks. Also here a "plug'n'play" system to add new definition for languages and frameworks could be a good choice.
Embed in a Kiro Power. KiroGraph works with Kiro's hooks and steering, and is basically a CLI tool: a good choice could be to embed it into a configurable Kiro power to reduce the friction for folks who wants just install and vibe.
Smarter sync. Currently, sync re-embeds every changed symbol. I’m considering introducing a content hash per embedding so we can skip unchanged symbols, even when the file has been modified.
Cross-project search. The graph is per-project right now. For monorepos or workspaces with shared libraries, cross-project symbol resolution would be genuinely useful.
Richer graph traversal. kirograph_path finds the shortest path between two symbols. I would love to add something like "explain this path", not just the nodes, but the semantic reason for each edge.
🚀 Just try it
Go to /
Semantic code knowledge graph for by to parse your source files into an AST and extract:
Nodes — functions, methods…
SOCIAL SHARE CARD GENERATOR