Skip to content

Multi-Language Repo

import { Aside, Tabs, TabItem } from ‘@astrojs/starlight/components’;

Forge indexes all supported languages in a single pass. A repo with TypeScript frontend, Python backend, and Rust services gets one unified index — searches, dependency graphs, and health checks span the whole codebase.

LanguageExtensionsFeatures
TypeScript.ts, .tsxFull — symbols, imports, AST patterns, graph
JavaScript.js, .jsx, .mjs, .cjsFull — symbols, imports, AST patterns, graph
Python.pyFull — symbols, imports, AST patterns, graph
Rust.rsFull — symbols, imports (use declarations), AST patterns, graph
Go.goFull — symbols, imports, AST patterns, graph

Other file types (YAML, TOML, JSON, Markdown) are indexed for full-text search but not AST-parsed.

No special flags required. Run forge index at the repo root:

Terminal window
forge index /path/to/repo --with-search --with-git

Forge detects languages automatically from file extensions. After indexing, verify all languages were picked up:

Terminal window
forge stats

Expected output for a TypeScript + Python repo:

forge stats: /home/you/repos/myapp
Files indexed: 3,847
Symbols extracted: 41,203
Languages: TypeScript (2,891), Python (956)
Index size: 94 MB
Last indexed: 2026-04-16 15:01:44 (just now)

If a language you expected is missing, check that files with those extensions exist in non-ignored paths.

Use forge search with --language to limit results to a specific language:

Terminal window
# Find "checkout" in TypeScript files only
forge search "checkout" --language typescript
# Find "checkout" in Python files only
forge search "checkout" --language python

Without --language, results span all indexed languages.

Via MCP (in Claude Code, Cursor, etc.):

Call forge_search with query="checkout" and language="typescript"

forge pattern_search (and forge_pattern_search via MCP) uses ast-grep syntax. Patterns are language-specific — specify which language to match:

Find all async function declarations:

Terminal window
forge pattern "async function $NAME($$$PARAMS) { $$$BODY }" --language typescript

Find all React useEffect calls:

Terminal window
forge pattern "useEffect($$$)" --language typescript

Find all class definitions:

Terminal window
forge pattern "class $NAME: $$$BODY" --language python

Find all with statements:

Terminal window
forge pattern "with $CTX as $VAR: $$$BODY" --language python

Find all impl blocks:

Terminal window
forge pattern "impl $TRAIT for $TYPE { $$$BODY }" --language rust

Find unwrap() calls (for audit):

Terminal window
forge pattern "$EXPR.unwrap()" --language rust

Find all error returns:

Terminal window
forge pattern "return nil, $ERR" --language go

Find goroutine spawns:

Terminal window
forge pattern "go $FUNC($$$ARGS)" --language go

Forge tracks dependencies within each language. Cross-language calls (e.g., a TypeScript frontend calling a Python REST API) are not tracked automatically — Forge works at the source level, not the network level. However, you can:

  1. Use forge search to find the API endpoint in both codebases simultaneously.
  2. Use forge_trace_dependents on the TypeScript API client module to find all callers.
  3. Use forge_trace_dependents on the Python endpoint to find all its imports and dependencies.

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 both:

Terminal window
forge index . --with-search --with-git

Search across both simultaneously:

Terminal window
forge search "payment"

Output:

frontend/src/api/client.ts:14 const paymentResponse = await post('/api/payments', ...)
frontend/src/components/Cart.tsx:87 import { createPayment } from '../api/client'
backend/app/routes/payments.py:1 from fastapi import APIRouter
backend/app/routes/payments.py:12 @router.post("/payments")
backend/app/services/payment.py:3 class PaymentService:

One query, both languages.

forge health runs checks across all indexed languages. Health check findings are scoped to the language they apply to — broken_import for a TypeScript module won’t appear for Python files.

Custom health check plugins can target specific languages. See Write a Custom Health Check.

Python files indexed but no symbols extracted This typically means the Python files use syntax from Python 3.10+ (structural pattern matching, union type syntax) that Forge’s parser doesn’t yet support. Check FORGE_LOG=debug forge index . for parse errors.

Go files missing from index Make sure Go files aren’t inside vendor/ (which is excluded by default). If vendor/ contains first-party code (unusual but it happens), add a specific include_paths override in .forge/config.toml.

Pattern search returns no results across languages Each forge pattern call targets one language. If you don’t specify --language, it searches all languages — but the pattern syntax must be valid in the target language. A TypeScript-specific pattern run without --language may silently skip Python files where the pattern is syntactically invalid.