Zero-config, polyglot CLI that reads source files and emits a queryable knowledge graph of import relationships.
Supported languages: Python, TypeScript, JavaScript, Java, Rust, Go, C, C++, Zig, C#, Objective-C, Swift, Ruby, PHP, Scala, Lua, Elixir, Haskell, Bash — 19 in total
No Rust toolchain required: prebuilt binaries are published on every release for macOS (Intel + Apple Silicon), Linux (x86_64 glibc/musl, aarch64), and Windows (x86_64 + arm64).
On x86_64 Linux, the installer downloads the fully static musl build by default so it runs on any distro regardless of glibc version. The glibc artifact is still published if you'd rather grab it manually from the Releases page.
curl -fsSL https://raw.githubusercontent.com/joeaguilar/kgr/main/install.sh | bashThe script auto-detects your platform, downloads the matching tarball from the latest GitHub Release, verifies its SHA256 checksum, and installs to an existing kgr location on PATH, ~/.cargo/bin if it is already on PATH, or ~/.local/bin.
To update an existing install, rerun the installer:
curl -fsSL https://raw.githubusercontent.com/joeaguilar/kgr/main/install.sh | bash -s -- --updateEnvironment overrides:
| Variable | Effect |
|---|---|
KGR_VERSION |
Pin a specific tag (e.g. v0.2.0). Defaults to latest. |
KGR_INSTALL_DIR |
Install directory. Defaults to the active kgr on PATH, ~/.cargo/bin, or ~/.local/bin. |
KGR_FROM_SOURCE=1 |
Skip download and build with cargo. Must be run from a cloned repo. |
iwr -useb https://raw.githubusercontent.com/joeaguilar/kgr/main/install.ps1 | iexInstalls kgr.exe into %LOCALAPPDATA%\Programs\kgr and adds that directory to your user PATH. Use -Version, -InstallDir, or -Repo parameters to override defaults.
Grab a release archive for your platform from GitHub Releases, verify the bundled .sha256, extract it, and drop kgr (or kgr.exe) anywhere on your PATH.
If you'd rather build locally, or no prebuilt binary exists for your target, install Rust 1.85+ and run:
cargo install --git https://github.com/joeaguilar/kgr --bin kgr
# or
git clone https://github.com/joeaguilar/kgr && cd kgr && cargo install --path crates/kgrFor source installs, keep it up to date with:
kgr upgrade # git pull + cargo build --release + in-place replacekgr # dependency tree of current directory
kgr graph --format json . # full graph as JSON
kgr check . # check for cycles, orphans, rule violations
kgr check --format json . # structured check output for CI/agents
kgr query --cycles . # list all cycles
kgr query --who-imports src/core/db.ts .
kgr init . # generate .kgr.toml config
kgr agent-info # machine-readable guide for AI agentsScan PATH (default: .) and print the dependency graph.
| Flag | Description |
|---|---|
-f, --format |
tree (default), json, table, dot, mermaid |
-l, --lang |
Filter by language: py, ts, js, rs, java, c, cpp, go |
--no-external |
Hide third-party package nodes |
--show-external |
Show external package names as leaf nodes (tree/table) |
-o, --output |
Write output to file |
--no-progress |
Disable progress bar (use in CI/pipes) |
kgr graph --format dot . | dot -Tsvg -o graph.svg
kgr graph --format mermaid . > deps.md
kgr graph --format json --no-progress . | jq '.external_deps'Check for dependency issues. Exits 0 if clean, 1 if errors found.
| Flag | Description |
|---|---|
-f, --format |
text (default), json |
--update-baseline |
Record current violations as baseline (exits 0) |
--baseline <file> |
Path to baseline file (default: .kgr-baseline.json) |
JSON output:
{
"ok": true,
"cycles": [["a.py", "b.py"]],
"orphans": ["unused.py"],
"rule_violations": [{"rule": "no-legacy-to-core", "from": "...", "to": "...", "severity": "error"}],
"suppressed": 0
}| Flag | Description |
|---|---|
--who-imports <file> |
Files that import the given file |
--deps-of <file> |
All transitive dependencies of a file |
--path-between <a> <b> |
Shortest dependency path |
--cycles |
List all cycles |
--orphans |
List orphaned files |
--heaviest |
Files ranked by number of dependents |
-f, --format |
table (default), json |
Print the definition body of a symbol, straight from source, located via the index — replaces grep -n + sed -n chains.
$ kgr show render_table
── crates/kgr/src/render/table.rs:6-41 (function render_table) ──
6 pub fn render_table(rows: &[Row], opts: &TableOpts) -> String {
7 let widths = column_widths(rows);
…
41 }
| Flag | Description |
|---|---|
-c, --context <n> |
Include n lines before/after the definition (default 0) |
--all |
Print every match; default prints the first and lists the rest as one-line pointers |
-k, --kind <fn|class|method> |
Disambiguate same-named symbols |
-f, --format |
text (default), json — {name, kind, path, start_line, end_line, exported, body} per match |
--no-linenos |
Raw body, pipe-friendly |
Printed paths are relative to the scanned PATH; kgr slice resolves against the current directory, so prefix pointers with the scanned PATH when slicing them from elsewhere.
Print a numbered, bounded line window from any file — no index, works on files kgr doesn't parse (.toml, .md, logs). Replaces sed -n 'X,Yp'.
$ kgr slice crates/kgr/src/main.rs:100-140
$ kgr slice engine.py:1134 -c 20 # single line ± context
| Flag | Description |
|---|---|
-c, --context <n> |
Expand a single-line target both ways (default 10 when no end given) |
--no-linenos |
Raw text, byte-identical to the source window |
-f, --format |
text (default), json — {path, start_line, end_line, lines[]} |
--max <n> |
Raise the 500-line output cap |
Generates a .kgr.toml with detected languages and commented rule examples.
[[rules]]
name = "no-legacy-to-core"
from = "legacy/**" # glob matched against relative file paths
to = "core/**"
severity = "error" # "error" → exit 1 | "warn" → exit 0Use kgr check --update-baseline to suppress known violations during a migration, then tighten the rules incrementally.
kgr graph --format json emits a DepGraph:
{
"root": "/abs/path",
"files": [{ "path": "...", "lang": "python", "imports": [...] }],
"edges": [{ "from": "...", "to": "...", "kind": "local|external|system" }],
"cycles": [[...]],
"roots": [...],
"orphans": [...],
"test_entries": [...],
"external_deps": { "main.ts": ["express", "lodash"] }
}
kgr agent-info # plain-text workflow guide
kgr agent-info --format json # same, wrapped in {"guide": "..."}Always pass --no-progress when parsing output programmatically.