# How to Add Custom Language Support to code-review-graph: A Complete Guide

> Add custom language support to code-review-graph by creating a languages.toml file. Specify file extensions, Tree-sitter grammar, and AST nodes for seamless integration.

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

---

**You can add custom language support to code-review-graph by creating a [`languages.toml`](https://github.com/tirth8205/code-review-graph/blob/main/languages.toml) configuration file in your repository's `.code-review-graph/` directory, specifying the file extensions, Tree-sitter grammar, and AST node types for your target language.**

The `code-review-graph` tool analyzes repository source files by mapping file extensions to language identifiers and parsing them with Tree-sitter grammars. While it ships with built-in support for common languages defined in [`code_review_graph/constants.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/constants.py) via dictionaries like `EXTENSION_TO_LANGUAGE` and `_FUNCTION_TYPES`, you can extend the parser to support additional languages without modifying the core codebase using a declarative configuration approach.

## How the Custom Language System Works

The custom language mechanism follows a defensive, config-driven architecture that merges user-defined language definitions into the parser at runtime.

### Configuration File Location and Structure

The system expects a TOML file named [`languages.toml`](https://github.com/tirth8205/code-review-graph/blob/main/languages.toml) placed under the repository's `.code-review-graph/` directory. This path is defined by the constant `CONFIG_RELATIVE_PATH = Path(".code-review-graph") / "languages.toml"` in [`code_review_graph/custom_languages.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/custom_languages.py) (line 47).

### Validation and Caching

The loader implements strict validation through the `_validate_entry` and `_load_uncached` functions in [`custom_languages.py`](https://github.com/tirth8205/code-review-graph/blob/main/custom_languages.py) (lines 97-102). Each entry must specify a unique language name, valid file extensions, an existing Tree-sitter grammar (verified via `tslp.get_language`), and appropriate node-type lists. To optimize performance, the loader maintains a per-path cache keyed by file modification time and size, avoiding unnecessary re-parsing of unchanged configuration files.

### Parser Integration

Upon loading, custom language data merges into the parser's internal lookup tables. The `CodeParser` class in [`code_review_graph/parser.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/parser.py) combines your custom extensions with built-in mappings, populating node-type dictionaries including `_class_types`, `_function_types`, `_import_types`, and `_call_types` (lines 53-71). The `_get_parser` method (lines 72-77) then uses your custom grammar field to instantiate the correct Tree-sitter parser.

## Creating Your Custom Language Definition

Define your language by specifying file extensions, the Tree-sitter grammar name, and the AST node types that represent functions, classes, imports, and calls.

### Example: Adding Erlang Support

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

```toml
[languages.erlang]
extensions = [".erl", ".hrl"]
grammar = "erlang"
function_node_types = ["function_clause"]
class_node_types = ["record_decl"]
import_node_types = ["import_attribute"]
call_node_types = ["call"]
comment = "Erlang support via bundled grammar"

```

The `grammar` field must reference a parser available in the bundled `tree-sitter-language-pack`. After adding this file, rebuild your code review graph to index `.erl` and `.hrl` files.

### Handling Non-Standard Name Fields

Some Tree-sitter grammars store identifier names in unconventional AST fields. Use the `name_field` array to specify alternative field names:

```toml
[languages.latex]
extensions = [".tex"]
grammar = "latex"
class_node_types = ["section", "chapter", "subsection"]
name_field = ["name", "text", "declaration"]

```

## Step-by-Step Implementation Guide

Follow these steps to add custom language support to your repository:

1. **Create the configuration directory**

   ```bash
   mkdir -p .code-review-graph
   ```

2. **Write the language definition**

   Create [`.code-review-graph/languages.toml`](https://github.com/tirth8205/code-review-graph/blob/main/.code-review-graph/languages.toml) with your language specifications, ensuring the grammar exists in `tree-sitter-language-pack`.

3. **Trigger a rebuild**

   ```bash
   uv run code-review-graph build
   ```

4. **Verify the integration**

   ```bash
   uv run code-review-graph graph --path src/math_utils.erl
   ```

   The output should show nodes with `language = "erlang"` containing properly typed Function and Class entries.

## Programmatic Access

You can inspect loaded custom languages programmatically using the loader directly:

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

repo_root = Path(".")
custom = load_custom_languages(
    repo_root,
    builtin_extensions=EXTENSION_TO_LANGUAGE,
    builtin_languages=_builtin_language_names(),
)
print(custom)   # => {'erlang': CustomLanguage(...)}

```

This approach is useful for testing configuration validity before running a full build.

## Summary

- **Config-driven approach**: Place a [`languages.toml`](https://github.com/tirth8205/code-review-graph/blob/main/languages.toml) file in `.code-review-graph/` to define custom languages without modifying source code.
- **Validation system**: The loader in [`code_review_graph/custom_languages.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/custom_languages.py) validates grammar availability and extension uniqueness, logging warnings for invalid entries while allowing the build to continue.
- **Parser integration**: Custom definitions merge into `CodeParser`'s internal tables (`_extension_map`, `_class_types`, etc.) during initialization at lines 53-71 of [`parser.py`](https://github.com/tirth8205/code-review-graph/blob/main/parser.py).
- **Tree-sitter dependency**: The `grammar` field must match a language available in the bundled `tree-sitter-language-pack`.

## Frequently Asked Questions

### What happens if I specify a grammar that isn't in the tree-sitter-language-pack?

The loader skips the entry with a warning message and continues processing other languages. This defensive behavior ensures that missing grammars never break existing functionality, as implemented in the `_validate_entry` function within [`code_review_graph/custom_languages.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/custom_languages.py).

### Can I override built-in language definitions?

Yes. When `load_custom_languages()` merges custom languages into the parser's tables in [`code_review_graph/parser.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/parser.py), your custom extensions and node types take precedence over the built-in mappings defined in [`code_review_graph/constants.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/constants.py).

### How does the caching mechanism work?

The loader in [`code_review_graph/custom_languages.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/custom_languages.py) caches parsed configurations based on file modification time and size (line 97). This prevents re-parsing [`languages.toml`](https://github.com/tirth8205/code-review-graph/blob/main/languages.toml) on every build, significantly improving performance for large repositories.

### What node types should I specify for my language?

You must provide arrays for `function_node_types`, `class_node_types`, `import_node_types`, and `call_node_types`. These correspond to Tree-sitter AST node names specific to your grammar. Consult your Tree-sitter grammar's documentation or use the `tree-sitter parse` command to identify correct node names.