Skip to content
Canopy is in pre-release. These docs describe the product at its public launch — commands, tool names, and integration examples reflect what you'll see once binaries ship. Join the waitlist →

Multi-Language Repo

Canopy indexes every supported language in a single pass. A repo with a TypeScript frontend, a Python backend, and Rust services gets one unified index — and one tool, canopy_answer, that answers the same question shapes across all of it.

Canopy’s AST extractors cover 55+ languages and formats — symbols and imports are extracted for each. The set includes Rust, TypeScript/TSX, JavaScript, Python, Go, Java, Kotlin, C, C++, C#, Swift, Ruby, PHP, Lua, Perl, Objective-C, shell/PowerShell/batch, HTML/CSS, GraphQL, Protobuf, Prisma, Dockerfile, CMake/Make/Gradle/MSBuild, YAML/TOML/INI/JSON, GDScript/Godot, Jupyter, Markdown, and more.

Language detection is automatic, by file content and extension. Files outside the extractor set are still indexed for full-text search.

No special flags. Run canopy index at the repo root:

Terminal window
canopy index /path/to/repo

Indexing is incremental by default and builds the full-text search index and vector embeddings automatically; git history is ingested whenever a .git/ directory is present. That’s everything canopy_answer needs across every language in the tree.

Phrasing picks the recipe regardless of language. Name the entity type and backtick paths and symbols:

Terminal window
# Python
canopy answer "where is the function `create_payment_route` defined?"
# TypeScript
canopy answer "what does `frontend/src/api/client.ts` import?"
# Anywhere in the tree
canopy answer "list functions defined in `backend/app/routes/`"
canopy answer "what depends on `backend/app/services/payment.py`?"
canopy answer "architecture overview"

The architecture overview spans the whole repo — frontend, backend, and services in one answer.

Example: TypeScript frontend + Python backend

Section titled “Example: TypeScript frontend + Python backend”

A common structure:

repo/
├── frontend/ (TypeScript/React)
│ └── src/
│ └── api/
│ └── client.ts
└── backend/ (Python/FastAPI)
└── app/
└── routes/
└── payments.py

Index once at the root, then ask on either side of the boundary:

Terminal window
canopy answer "what depends on `frontend/src/api/client.ts`?"
canopy answer "public surface of `backend/app/routes/payments.py`"
canopy answer "what tests cover `backend/app/routes/payments.py`?"

One index, one tool, both languages.

Dependency edges follow each language’s module system. A TypeScript frontend calling a Python REST API over HTTP is not a static import, so it doesn’t appear as a graph edge — Canopy works at the source level, not the network level. Cover the boundary from both sides:

  1. “what depends on frontend/src/api/client.ts?” — every frontend caller of the API client.
  2. “what depends on backend/app/routes/payments.py?” — everything wired to the endpoint on the backend.

To confirm a directory or language made it into the index, check what the walker includes and skips — without running an index:

Terminal window
canopy index --list-ignored

This prints what would be indexed vs skipped, grouped by top-level directory. For a structural sanity check, canopy answer "architecture overview" should reflect every major language area of the repo; canopy doctor reports overall index status.

A language is missing from answers The files are almost always being skipped by an ignore layer: the bundled defaults (build artifacts and vendored dependencies), .gitignore, .canopyignore, or an --ignore-pattern glob. Run canopy index --list-ignored to see the skip list; re-run with --no-default-ignore, --no-gitignore, or --no-canopyignore to attribute a specific file to a layer.

First-party code inside a default-ignored directory If first-party code lives somewhere the default ignore set excludes (unusual, but it happens), --no-default-ignore indexes it — at the cost of also indexing build artifacts. Prefer restructuring or a narrower .canopyignore where possible.

Stale answers after adding a new service Re-run canopy index (incremental) after large structural additions, or run canopy serve --watch so the index tracks changes automatically during development.