> ## Documentation Index
> Fetch the complete documentation index at: https://differens.ossl.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Language Support

> Which languages get semantic diffs and what that means

# Language Support

Differens parses code with tree-sitter and diffs the resulting trees. Any language with a tree-sitter grammar gets structural diffing. The real question is how much semantics a language gets: Differens either recognizes a node as a `Function` or a `Class`, or it just sees a tree-sitter node type like `function_item`.

## Two levels of support

**Semantic extractors (T5, L6).** Four languages ship a per-language extractor: TypeScript/JavaScript, Python, Rust, and Go. An extractor maps tree-sitter node types to canonical concepts like `Function`, `Class`, `Method`, `Import`, `Export`, `Variable`, `Type`, `Enum`, `Struct`, and `Trait`, then pulls the declaration name out of the tree. With an extractor, a rename is a *rename* and a move is a *move*. Narration can say "renamed `computeTotal` to `calculateTotalAmount`".

**Generic structural diff (T5, L5).** Every other language with a tree-sitter grammar still gets structural diffing. The CST is parsed into a tree and matched structurally, but nodes keep their raw tree-sitter type names instead of canonical concepts, and labels come from the generic `name`-field rule. Reformatting and restructure are caught. Semantic narration is not.

## Languages with full extractors

| Language                      | Tier    | Extractor             | What it detects                                                                                                               |
| ----------------------------- | ------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| TypeScript / JavaScript       | T5 (L6) | `TypeScriptExtractor` | functions, arrow functions, methods, classes, interfaces, type aliases, enums, imports, exports, variables, JSX, control flow |
| Python                        | T5 (L6) | `PythonExtractor`     | functions (including async), classes, imports, decorators, assignments, comprehensions, type annotations, control flow        |
| Rust                          | T5 (L6) | `RustExtractor`       | functions, structs, enums, traits, impls, macros, `use` imports, modules, types                                               |
| Go                            | T5 (L6) | `GoExtractor`         | functions, methods, structs, interfaces, imports, variables, constants, goroutines                                            |
| Any other tree-sitter grammar | T5 (L5) | n/a                   | structural diff with raw tree-sitter node type labels                                                                         |

Anything tree-sitter has a grammar for falls back to the generic structural level (T5, L5). No extractor needed. If no grammar is registered at all, the file falls down the tier ladder to a line diff.

## The LanguageExtractor interface

An extractor is a few dozen match arms, not a parser:

```typescript theme={null}
export interface LanguageExtractor {
  /** Language identifier, e.g. "typescript" */
  readonly language: string;
  /** File extensions this extractor handles */
  readonly extensions: string[];
  /** Map a tree-sitter node type to a canonical concept */
  extractConcept(nodeType: string): string;
  /** Extract the label (name) from a node if it has one */
  extractLabel(node: Parser.SyntaxNode, source: string): string | undefined;
  /** Node types whose label does NOT come from a plain `name` field */
  readonly labelFallbackTypes?: ReadonlySet<string>;
}
```

The tree-sitter cursor walk reads the `name` field directly for every node. `extractLabel` only runs for the types listed in `labelFallbackTypes`. That is a set lookup instead of a `childForFieldName` call per node.

## Adding a language

To give a language semantic diffs, implement `LanguageExtractor` and register the extractor with the code tier. See [Adding a language extractor](/guides/contributing#adding-a-language-extractor) in the contributing guide.

## Language pages

* [TypeScript / JavaScript](/languages/typescript)
* [Python](/languages/python)
* [Rust](/languages/rust)
* [Go](/languages/go)
* [Tier adapters](/languages/tiers)
