# Tree-sitter Parsers in Graphify: Complete Configuration Guide

> Explore Tree-sitter parsers in Graphify configuration options. Customize syntax tree parsing with over 20 fields including node types and callbacks. Learn more today.

- Repository: [Graphify Labs/graphify](https://github.com/Graphify-Labs/graphify)
- Tags: how-to-guide
- Published: 2026-07-15

---

**Tree-sitter parsers in Graphify are controlled through the `LanguageConfig` dataclass in [`graphify/extractors/models.py`](https://github.com/Graphify-Labs/graphify/blob/main/graphify/extractors/models.py), which exposes over 20 configuration fields specifying node types, field names, and optional callbacks that customize how the generic extraction engine parses language-specific syntax trees.**

Graphify relies on Tree-sitter grammars to extract abstract syntax trees (ASTs) from source code. Rather than hardcoding language logic, the framework uses a declarative configuration system that allows fine-grained control over parser behavior. The `LanguageConfig` dataclass serves as the central contract between language-specific extractors and the generic engine located in [`graphify/extractors/engine.py`](https://github.com/Graphify-Labs/graphify/blob/main/graphify/extractors/engine.py).

## Core Configuration Structure

All Tree-sitter parser behavior in Graphify flows through the **`LanguageConfig`** dataclass. This single structure defines which compiled Tree-sitter module to load, which node types represent classes and functions, how to resolve identifier names, and how to traverse call expressions.

According to the Graphify source code, the engine imports this configuration and uses it to drive the AST walker without requiring language-specific hardcoding in the core logic.

## Key Configuration Categories

### Parser Loading Options

Two fields control how Graphify loads the compiled Tree-sitter library:

- **`ts_module`** (`str`): The Python module name providing the compiled language (e.g., `"tree_sitter_python"`). This is required for every configuration.
- **`ts_language_fn`** (`str`, default `"language"`): The attribute name on the module that returns the `Language` object. Most parsers expose this as `language()`, but custom builds may use different names.

### Node Type Definitions

These `frozenset` fields map Graphify's internal concepts to specific Tree-sitter node type strings:

- **`class_types`**: Node types representing class-like definitions (e.g., `{"class_declaration", "struct"}`).
- **`function_types`**: Node types for function or method definitions (e.g., `{"function_definition", "method_definition"}`).
- **`import_types`**: Node types representing import statements (e.g., `{"import_statement", "using_directive"}`).
- **`call_types`**: Node types denoting call expressions (e.g., `{"call_expression", "method_invocation"}`).
- **`static_prop_types`**: Node types for static property declarations.
- **`function_boundary_types`**: Node types where the recursive call-walker should stop to prevent infinite recursion in nested constructs like lambdas.

### Specialized Recognition Fields

Graphify supports complex language constructs through additional node type sets:

- **`helper_fn_names`**: Function names treated as "inline" (e.g., getters) during call walking.
- **`container_bind_methods`**: Method names that bind containers (e.g., C++ `operator=`), helping the engine stop recursion appropriately.
- **`event_listener_properties`**: Property names representing event listeners (e.g., JavaScript `onClick`).

### Field Resolution

These string fields specify which Tree-sitter node attributes contain key metadata:

- **`name_field`** (`str`, default `"name"`): The field storing the identifier name. Some languages use `"identifier"` instead.
- **`name_fallback_child_types`** (`tuple`): Alternate child node types to search when `name_field` is missing.
- **`body_field`** (`str`, default `"body"`): The field containing a declaration's executable body.
- **`body_fallback_child_types`** (`tuple`): Alternate child types when `body_field` is absent (e.g., `compound_statement`).

### Call Graph Construction

Four fields control how the engine resolves method calls and member access:

- **`call_function_field`** (`str`, default `"function"`): The field on a call node pointing to the callee.
- **`call_accessor_node_types`** (`frozenset`): Node types for member access (e.g., `member_expression`).
- **`call_accessor_field`** (`str`, default `"attribute"`): The field on an accessor node holding the member name.
- **`call_accessor_object_field`** (`str`, default `""`): Optional field storing the receiver/object (e.g., for `this` in C#).

### Language-Specific Hooks

Three optional callbacks enable custom logic:

- **`import_handler`** (`Callable | None`): Custom handler for import nodes, enabling language-specific resolution such as Go's dot imports.
- **`resolve_function_name_fn`** (`Callable | None`): Hook to post-process function names (e.g., unwrap C/C++ declarators).
- **`extra_walk_fn`** (`Callable | None`): Hook executed after the generic walk for a node, useful for extensions like JavaScript arrow functions or C# namespaces.

### Display Options

- **`function_label_parens`** (`bool`, default `True`): When `True`, appends `()` to function node labels in the generated graph for improved readability.

## Practical Configuration Examples

### Basic Python Configuration

This example configures the Python parser using standard Tree-sitter node types:

```python
from graphify.extractors.models import LanguageConfig

python_cfg = LanguageConfig(
    ts_module="tree_sitter_python",
    class_types=frozenset({"class_definition"}),
    function_types=frozenset({"function_definition", "lambda"}),
    import_types=frozenset({"import_statement", "import_from_statement"}),
    call_types=frozenset({"call"}),
    name_field="name",
    body_field="body",
    call_function_field="function",
    call_accessor_node_types=frozenset({"attribute", "subscript"}),
    call_accessor_field="attribute",
)

```

*Source*: [`graphify/extractors/models.py`](https://github.com/Graphify-Labs/graphify/blob/main/graphify/extractors/models.py)

### JavaScript/TypeScript with Extra Walk Hook

This configuration demonstrates using `extra_walk_fn` to handle anonymous arrow functions:

```python
def js_extra_walk(node, ctx):
    # Arrow functions have their body under the "body" field but lack a name.

    if node.type == "arrow_function":
        ctx.add_anonymous_function(node)

js_cfg = LanguageConfig(
    ts_module="tree_sitter_javascript",
    class_types=frozenset({"class_declaration"}),
    function_types=frozenset({"function_declaration", "method_definition", "arrow_function"}),
    import_types=frozenset({"import_statement", "export_statement"}),
    call_types=frozenset({"call_expression"}),
    call_accessor_node_types=frozenset({"member_expression"}),
    extra_walk_fn=js_extra_walk,
)

```

*Source*: [`graphify/extractors/engine.py`](https://github.com/Graphify-Labs/graphify/blob/main/graphify/extractors/engine.py)

### Custom Import Handler for Go

This example shows how to implement language-specific import resolution using `import_handler`:

```python
def go_import_handler(node, ctx):
    # Go's import specs may contain a dot import; treat specially.

    if node.type == "dot_import":
        ctx.register_dot_import(node)

go_cfg = LanguageConfig(
    ts_module="tree_sitter_go",
    import_handler=go_import_handler,
    class_types=frozenset({"type_declaration"}),
    function_types=frozenset({"function_declaration"}),
    call_types=frozenset({"call_expression"}),
)

```

*Source*: [`graphify/extractors/engine.py`](https://github.com/Graphify-Labs/graphify/blob/main/graphify/extractors/engine.py)

### Using the Configuration

Once defined, pass the configuration to the generic extractor:

```python
from graphify.extractors.engine import extract_generic

# source_bytes contains the file contents.

graph = extract_generic(source_bytes, config=python_cfg)

```

*Source*: [`graphify/extractors/engine.py`](https://github.com/Graphify-Labs/graphify/blob/main/graphify/extractors/engine.py)

## How the Engine Interprets These Settings

The generic extraction engine in [`graphify/extractors/engine.py`](https://github.com/Graphify-Labs/graphify/blob/main/graphify/extractors/engine.py) reads the supplied `LanguageConfig` and applies it during the AST traversal. The engine uses `class_types` and `function_types` to locate definitions, `name_field` and `body_field` to extract identifiers and implementation blocks, and `call_types` combined with `call_accessor_*` fields to build call graphs.

Because the configuration is a plain dataclass, adding support for a new language requires only constructing a `LanguageConfig` instance with appropriate node-type strings and optional callbacks, then passing it to the engine via the language-specific extractor (e.g., [`graphify/extractors/python.py`](https://github.com/Graphify-Labs/graphify/blob/main/graphify/extractors/python.py) or [`graphify/extractors/javascript.py`](https://github.com/Graphify-Labs/graphify/blob/main/graphify/extractors/javascript.py)).

## Summary

- The **`LanguageConfig`** dataclass in [`graphify/extractors/models.py`](https://github.com/Graphify-Labs/graphify/blob/main/graphify/extractors/models.py) defines all Tree-sitter parser configuration options in Graphify.
- **Required fields** include `ts_module` (specifying the parser library) and various node type sets (`class_types`, `function_types`, `call_types`).
- **Field resolution** is controlled through `name_field`, `body_field`, and their fallback counterparts.
- **Call graph construction** relies on `call_function_field`, `call_accessor_node_types`, and `call_accessor_field`.
- **Language-specific customization** is enabled through optional callbacks: `import_handler`, `resolve_function_name_fn`, and `extra_walk_fn`.
- The generic engine in [`graphify/extractors/engine.py`](https://github.com/Graphify-Labs/graphify/blob/main/graphify/extractors/engine.py) consumes these configurations to perform language-agnostic AST extraction.

## Frequently Asked Questions

### What is the minimum required configuration for a new language in Graphify?

At minimum, you must specify `ts_module` (the Tree-sitter Python module name) and define the core node type sets: `class_types`, `function_types`, `import_types`, and `call_types`. Without these, the generic engine cannot identify definitions or calls in the AST. You may also need to adjust `name_field` if the language uses a non-standard identifier field.

### How does Graphify handle languages with different naming conventions for AST nodes?

Use the `name_field` and `name_fallback_child_types` options. If a language stores identifiers in a field other than `name`, set `name_field` to the correct attribute name (e.g., `"identifier"`). If the name might be stored in different node types depending on context, populate `name_fallback_child_types` with a tuple of alternative node types to search.

### Can I customize how Graphify resolves imports for a specific language?

Yes. Provide a callable to the `import_handler` field in `LanguageConfig`. This callback receives the import node and the extraction context, allowing you to implement language-specific logic such as handling Go's dot imports or Python's relative imports. The engine invokes this handler instead of the generic import processing logic when it is provided.

### What is the purpose of the `extra_walk_fn` callback?

The `extra_walk_fn` callback allows you to extend the generic AST traversal with language-specific logic. It is executed after the generic walk for each node. For example, JavaScript extractors use this to handle arrow functions, which lack a `name` field but require special handling to register as anonymous functions in the call graph.