Languages
greppy bundles tree-sitter parsers for more than 60 languages. Support comes in three tiers, and each tier is measured.
| Tier | Languages | What works |
|---|---|---|
| Graph fully tested | Rust, Python, Java, JavaScript, TypeScript, Go, C++, C#, Kotlin, Swift, Ruby | everything; callers, callees, usages and impact are checked in per-language test grids |
| Graph relations | other programming languages, for example Elixir, Scala, PHP and Haskell | symbols, definition and text search, plus call, usage and import relations |
| Symbols and text | declarative formats such as JSON, YAML, TOML and Markdown | symbols and text search; these formats have no call graph by nature |
Three languages in one repository
A small project in Python, Go and TypeScript has one function per language and its caller in a second file. Here are the six files, cut down to the lines that carry the example:
py/pricing.py def apply_discount(price, percent)
py/cart.py from pricing import apply_discount · Cart.total() calls apply_discount
go/tax.go func ApplyTax(net float64) float64
go/invoice.go func (i Invoice) Total() calls ApplyTax
ts/format.ts export function formatPrice(cents: number)
ts/receipt.ts import { formatPrice } from "./format" · renderReceipt() calls formatPrice
One index covers all three languages:
$ greppy index .
indexed 6 files (0 unsupported, 0 unreadable, 0 oversize, 0 file-limit, 0 time-budget); 9 nodes extracted; generation 1 (project: shop)
embedded 9 code spans (0 local-store reused, 9 global-cache hits, 0 inference misses, 25 considered, 16 non-definition skipped, 0 missing-file, 0 invalid-span, 0 oversize, 0 failed, 0 stale pruned)
One call asks for the callers in all three languages. For Python, the file-level import appears as well:
$ greppy who-calls apply_discount ApplyTax formatPrice
apply_discount
py/cart.py:1 __file__
py/cart.py:9 Cart::total
ApplyTax
go/invoice.go:7 Invoice::Total
formatPrice
ts/receipt.ts:3 renderReceipt
Semantic search ranks across all languages:
$ greppy search "add VAT to a net amount"
go/invoice.go:7 Invoice::Total — returns the total by applying tax to Net
go/tax.go:4 ApplyTax — returns the net value multiplied by 1.19
go/invoice.go:3 Invoice
ts/format.ts:1 formatPrice — formats a number of cents as a two-decimal EUR string
ts/receipt.ts:3 renderReceipt — formats a list of line pairs into a single string
py/pricing.py:1 apply_discount — reduces a price by a percentage and rounds the result
py/cart.py:9 Cart::total — computes the total price by summing item prices and applying a discount
py/cart.py:4 Cart
The first line of greppy where-am-i names the languages of your repository: for this project go, python, typescript, 6 files, 9 definitions, for serde 1.0.229 rust, toml, markdown, 339 files, 3,908 definitions.
Every language
greppy 0.4.1 detects and indexes these 63 languages. Each one is tested with one sample file and the extension listed:
| Group | Languages |
|---|---|
| Systems and hardware | C (.c, .h), C++ (.cpp, .hpp), CUDA (.cu), Objective-C (.m), D (.d), Rust (.rs), Zig (.zig), Go (.go), Swift (.swift), Ada (.adb), Fortran (.f90), Pascal (.pas), GLSL (.glsl), Verilog (.sv), VHDL (.vhd) |
| JVM and .NET | Java (.java), Kotlin (.kt), Scala (.scala), Groovy (.groovy), Clojure (.clj), C# (.cs), F# (.fs) |
| Web | JavaScript (.js, .jsx, .mjs), TypeScript (.ts, .tsx), Vue (.vue), Svelte (.svelte), CSS (.css), PHP (.php), Dart (.dart), Solidity (.sol) |
| Scripting | Python (.py), Ruby (.rb), Crystal (.cr), Lua (.lua), Bash (.sh), PowerShell (.ps1), R (.R), Julia (.jl), MATLAB (.matlab), GDScript (.gd) |
| Functional | Haskell (.hs), OCaml (.ml), Elixir (.ex), Erlang (.erl), Elm (.elm), Gleam (.gleam), PureScript (.purs), Racket (.rkt), Scheme (.scm), Common Lisp (.lisp, .cl), Nix (.nix) |
| Data, schema and build | JSON, YAML, TOML, Markdown (.md), SQL, GraphQL, Protobuf (.proto), Prisma, HCL (.tf, .hcl), CMake (.cmake), Make (Makefile, .mk), Dockerfile (.dockerfile) |
In every one of these languages, search, search-symbol, search-pattern, read and the edit commands work on the indexed definitions. greppy diagnostics lists every language detected in your repository with the number of its indexed files.
Call graph
Each sample file contains a function add and a second function that calls it. greppy who-calls finds this call with no extra setup in 33 languages:
Bash, C, C++, C#, Clojure, Crystal, CUDA, D, Dart, Elixir, F#, GDScript, Gleam, GLSL, Go, Groovy, Haskell, Java, JavaScript, Kotlin, Lua, OCaml, PHP, Python, R, Racket, Ruby, Rust, Scala, Scheme, Swift, TypeScript, Zig.
callees, path and impact work there as well. Outside the fully tested languages, treat the graph as strong evidence and check it against the source.
Fully tested graph
Eleven languages have a fully tested graph:
- Rust
- Python
- Java
- JavaScript
- TypeScript
- Go
- C++
- C#
- Kotlin
- Swift
- Ruby
Each is fully tested by a grid of 12 cells per language: cross-file CALLS, USAGE, TYPE_REF and IMPORTS edges, plus reindex stability and freshness behavior, together with language fixtures and tests on real repositories. The grids and fixtures are integration tests in crates/cli/tests/, for example graph_nav.rs and graph_grid_ruby.rs. The remaining programming languages follow in waves.
Semantic search
search works on definitions in every indexed language: EmbeddingGemma embeds the definitions, and the navigation hint under each hit comes from greppy's fine-tuned Qwen3.5 model. Semantic search does not depend on graph edges, so it also finds code the graph does not connect.
What no parser sees
Static analysis can miss reflection, runtime dependency injection, generated code, macro expansion, monkeypatching and dynamic dispatch, in every language. Evidence freshness is fail-closed: greppy does not knowingly return stale source evidence. Verify proposed changes with the language toolchain and the test suite. See Limits.
Multi-package repositories
A repository with several packages, such as a Cargo, npm or Go workspace, gets one index. where-am-i, search, search-symbol and search-pattern cover all packages in one call. For serde, serde/, serde_core/, serde_derive/, serde_derive_internals/ and test_suite/ appear in one overview.
Add a language
The repository contains ADDING_A_LANGUAGE.md, a self-contained playbook: add extraction for one language, verify it to the project's correctness bar and open a pull request. Contributions follow CONTRIBUTING.md.