tree_sitter_typescript::language_tsx in Rust — the right way to wire it up

How to use tree_sitter_typescript::language_tsx() from Rust without crashing on JSX-heavy files. Crate version compatibility, parser init, and how Aura uses it.

The tree-sitter-typescript crate exposes two grammars: language_typescript() for plain .ts files, and tree_sitter_typescript::language_tsx() for .tsx files containing JSX. Pick the wrong one and the parser silently truncates every JSX subtree to ERROR nodes — which is exactly what Aura's AST-diff engine handled wrong in v0.4 and now treats as a hard precondition.

Cargo.toml

[dependencies]
tree-sitter        = "0.22"
tree-sitter-typescript = "0.21"

Minimal parser setup

use tree_sitter::Parser;

fn parse_tsx(source: &str) -> tree_sitter::Tree {
    let mut parser = Parser::new();
    parser
        .set_language(&tree_sitter_typescript::language_tsx())
        .expect("load tsx grammar");
    parser.parse(source, None).expect("parse")
}

Pitfalls Aura hit (so you don't have to)

  • One parser, one grammar. Re-using the same Parser across .ts and .tsx files without calling set_language again leaves you parsing TSX with the TypeScript grammar — most JSX becomes ERROR nodes and your diff is meaningless.
  • Version skew. tree-sitter 0.22 ABI requires a tree-sitter-typescript built against the same major. Mixing 0.20 + 0.22 compiles fine, then segfaults at runtime when the parser walks a sufficiently deep tree.
  • UTF-16 source. parse assumes UTF-8. If you're feeding it bytes from VS Code over LSP, decode first or use parse_with_options.
  • Cancellation timeouts. Set parser.set_timeout_micros(…) for adversarial inputs — a hand-crafted JSX file can blow up the parser for > 30s otherwise.

How Aura uses it

Aura's AST-diff engine runs language_tsx() against every .tsx commit, extracts named function nodes, and hashes their structural skeleton (rename-proof identity). When Claude rewrites <UserCard> from a class component to a functional one, Aura sees one node updated, not 200 lines deleted + 180 added — and the intent log says exactly that.

Reference

The grammar source lives at tree-sitter/tree-sitter-typescript. The Aura wrapper that picks the right grammar per file extension is in aura-stackgraph/src/lang/typescript.rs (Apache 2.0).