# How to Configure Custom Language Parsing for Unsupported Languages in Code-Review-Graph

> Learn to configure custom language parsing for unsupported languages in Code-Review-Graph by creating a languages.toml file. Easily add Tree-sitter grammar support without code changes.

- Repository: [Tirth Kanani/code-review-graph](https://github.com/tirth8205/code-review-graph)
- Tags: how-to-guide
- Published: 2026-07-18

---

**Developers can add support for any Tree-sitter grammar without forking or modifying the source code by creating a [`languages.toml`](https://github.com/tirth8205/code-review-graph/blob/main/languages.toml) configuration file inside the repository's `.code-review-graph` directory.**

The `code-review-graph` tool uses Tree-sitter for parsing source files, and while it ships with built-in support for popular languages, it exposes a declarative configuration system to extend coverage to any grammar available in the `tree_sitter_language_pack`. This guide explains how to configure custom language parsing for unsupported languages using the repository-level configuration architecture.

## Architecture of Custom Language Support

The custom language system is designed to operate without code changes, leveraging a configuration-driven architecture that merges user-defined mappings with built-in parsers at runtime.

### How the Loader Interacts with the Parser

When `CodeParser` initializes in [`code_review_graph/parser.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/parser.py), it invokes `load_custom_languages` from [`code_review_graph/custom_languages.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/custom_languages.py) to read and validate the TOML configuration. This function returns a mapping that gets merged into the internal `EXTENSION_TO_LANGUAGE` table, enabling the `detect_language` method to recognize files with custom extensions. During parsing, the generic Tree-sitter walker uses the node-type lists defined in the configuration to extract `Function`, `Class`, `IMPORTS_FROM`, and `CALLS` edges without requiring language-specific code paths.

## Step-by-Step Configuration Guide

Follow these steps to enable parsing for an unsupported language using an Erlang configuration as a working example.

### 1. Create the Configuration File

Create a file named [`languages.toml`](https://github.com/tirth8205/code-review-graph/blob/main/languages.toml) inside the `.code-review-graph` directory at your repository root:

```toml

# .code-review-graph/languages.toml

[languages.erlang]
extensions = [".erl"]
grammar = "erlang"                     # Grammar name from tree-sitter-language-pack

function_node_types = ["function_clause"]
class_node_types    = ["record_decl"]
import_node_types   = ["import_attribute"]
call_node_types     = ["call"]
comment = "Erlang via the bundled tree-sitter-erlang grammar"

```

### 2. Define Language Metadata and Grammar

Each language block under `[languages.<name>]` requires:

- **extensions**: A list of file suffixes that trigger this parser.
- **grammar**: The exact name of the Tree-sitter grammar as distributed in `tree_sitter_language_pack`.
- **comment**: Optional description for debugging purposes.

The system enforces collision rules where built-in languages take precedence, and validates that each extension is unique across all configured languages.

### 3. Map Tree-sitter Node Types to Graph Entities

Specify which Tree-sitter AST nodes should be converted to graph entities:

- **function_node_types**: Nodes representing functions or methods.
- **class_node_types**: Nodes representing classes, structs, or records.
- **import_node_types**: Nodes representing module imports or includes.
- **call_node_types**: Nodes representing function or method invocations.

These mappings allow the generic walker in [`code_review_graph/custom_languages.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/custom_languages.py) to process the syntax tree without language-specific logic.

### 4. Rebuild the Graph Index

After creating the configuration, trigger a full rebuild to index the new language:

```bash

# From the repository root

uv run code-review-graph build

```

The incremental build system in [`code_review_graph/incremental.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/incremental.py) reprocesses all matching files and persists nodes to SQLite with the custom language identifier stored in the `language` field.

## Validation and Testing

Verify that your configuration loads correctly and integrates with the parser before running full analysis.

### Verify Configuration Loading

Use the Python API to confirm that `load_custom_languages` returns your custom definition:

```python
from code_review_graph.custom_languages import load_custom_languages
from pathlib import Path

repo = Path(".")
langs = load_custom_languages(
    repo,
    builtin_extensions=EXTENSION_TO_LANGUAGE,
    builtin_languages=_builtin_language_names(),
)
print(langs)  # → {'erlang': CustomLanguage(...)}

```

### Test File Detection and Parsing

Instantiate `CodeParser` with the repository root to enable custom language detection, then verify parsing produces the expected node types:

```python
from code_review_graph.parser import CodeParser
from pathlib import Path

parser = CodeParser(Path("."))  # repo_root required for custom languages

lang = parser.detect_language(Path("src/math_utils.erl"))
print(lang)  # → "erlang"

nodes, edges = parser.parse_file(Path("src/math_utils.erl"))
assert any(n.kind == "Function" and n.language == "erlang" for n in nodes)

```

## Technical Implementation Details

Understanding the internal validation and constraints helps prevent configuration errors.

### The CustomLanguages Loader Architecture

The `load_custom_languages` function in [`code_review_graph/custom_languages.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/custom_languages.py) implements a defensive loading strategy that:

- Caches configurations to avoid repeated disk I/O during batch processing.
- Enforces a maximum limit of 20 custom languages per repository.
- Validates TOML schema and ensures broken configurations never crash the build.
- Resolves extension collisions by prioritizing built-in parsers over custom definitions.

### Parser Integration and Extension Mapping

In [`code_review_graph/parser.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/parser.py), the `CodeParser` constructor calls `load_custom_languages` and merges the returned dictionary into its `EXTENSION_TO_LANGUAGE` mapping. This design ensures that `detect_language` works transparently for both built-in and custom languages. The generic Tree-sitter walker then retrieves the node-type lists from the `CustomLanguage` object to extract definitions and relationships, enabling impact analysis, semantic search, and community detection features for the newly configured language without additional code changes.

## Summary

- **Configuration-driven**: Add unsupported languages by creating [`.code-review-graph/languages.toml`](https://github.com/tirth8205/code-review-graph/blob/main/.code-review-graph/languages.toml) without modifying source code.
- **Tree-sitter integration**: Leverage any grammar from `tree_sitter_language_pack` by specifying the grammar name and mapping AST node types to graph entities.
- **Validation safeguards**: The `load_custom_languages` function in [`code_review_graph/custom_languages.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/custom_languages.py) enforces limits (max 20 languages), prevents collisions, and ensures malformed configs fail gracefully.
- **Full rebuild required**: Run `code-review-graph build` after configuration changes to index files with the new language parser.
- **Generic processing**: The walker in [`code_review_graph/custom_languages.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/custom_languages.py) handles both built-in and custom languages identically, supporting all downstream analysis features.

## Frequently Asked Questions

### What Tree-sitter grammars are supported for custom languages?

Any grammar distributed in the `tree_sitter_language_pack` can be used. The `grammar` field in [`languages.toml`](https://github.com/tirth8205/code-review-graph/blob/main/languages.toml) must match the exact package name as defined in that collection, such as `"erlang"`, `"dart"`, or `"kotlin"`.

### Why does my custom language configuration not appear to work?

Ensure you have triggered a full rebuild using `code-review-graph build` or `uv run code-review-graph build`. The incremental indexing system in [`code_review_graph/incremental.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/incremental.py) only picks up new language mappings during a full graph rebuild, not during incremental updates.

### Is there a limit to how many custom languages I can configure?

Yes, the system enforces a maximum of 20 custom languages per repository. This limit is hardcoded in [`code_review_graph/custom_languages.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/custom_languages.py) to prevent configuration bloat and ensure build performance remains consistent.

### How does the system handle file extensions that conflict with built-in languages?

Built-in languages always take precedence over custom definitions. If you declare an extension that matches a built-in parser, the `load_custom_languages` function in [`code_review_graph/custom_languages.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/custom_languages.py) will skip the custom mapping and emit a warning, ensuring standard language detection remains unaffected.