tree-sitter-javascript
JavaScript and JSX grammar for the tree-sitter incremental parsing library
Repository Health
Technical Analysis
tree-sitter-javascript is the official JavaScript grammar for tree-sitter, the incremental parsing library used by editors, linters, and code-intelligence tools to build and update syntax trees in real time as code is edited. The grammar aims for close conformance to the ECMAScript specification while adding JSX syntax support, and ships pre-generated parser tables (parser.c) plus hand-written scanner logic (scanner.c) for the constructs regular grammars can’t express cleanly, like automatic semicolon insertion and template literals.
As a Rust crate it exposes a LANGUAGE constant that plugs directly into a tree_sitter::Parser, along with bundled syntax-highlighting, local-variable, and symbol-tagging queries (.scm files) that consuming tools use for editor features like highlighting, code folding, and “go to definition”. The same grammar is also published for Node.js, Python, Go, and Swift, making it the shared JS/JSX parsing foundation across many tree-sitter-based tools (Neovim, Helix, GitHub’s code navigation, and others).
What You Get
- A
LANGUAGEconstant (Rust) or equivalent binding (Node, Python, Go, Swift) that plugs directly into atree_sitter::Parser - Pre-generated
parser.c/grammar.json/node-types.jsonso consumers don’t need thetree-sitterCLI to use the grammar - A hand-written C scanner (
scanner.c) handling context-sensitive lexing tree-sitter’s declarative grammar can’t express alone (ASI, template strings, JSX text) - Bundled
.scmquery files for syntax highlighting, JSX highlighting, local-variable resolution, and symbol tagging - Multi-language bindings published to crates.io, npm, PyPI, Go modules, and Swift Package Manager from a single grammar source
Common Use Cases
- Building editor syntax highlighting and code folding for JavaScript/JSX files (used by Neovim, Helix, and other tree-sitter-based editors)
- Powering static analysis, linting, or code-navigation tools that need a real syntax tree rather than regex-based parsing
- Embedding incremental JS/JSX parsing in a Rust, Node.js, Python, or Go application via the corresponding language binding
- Extracting local-variable and symbol information from JavaScript source for “go to definition” or refactoring tooling
Under The Hood
Architecture - The grammar itself is authored in grammar.js as a declarative DSL (rules, precedences, conflicts, external tokens) which the tree-sitter CLI compiles ahead of time into the checked-in src/parser.c, src/grammar.json, and src/node-types.json — so consuming crates never need to run code generation themselves. Context-sensitive lexing that the declarative grammar can’t express (automatic semicolon insertion, template literal interpolation boundaries, JSX text vs. tag detection) is handled by a hand-written external scanner in src/scanner.c, referenced from grammar.js’s externals array. The queries/ directory (highlights.scm, highlights-jsx.scm, locals.scm, tags.scm, injections.scm) provides tree-sitter-query-language rules that map syntax nodes to highlight scopes, variable-scoping information, and taggable symbols — the layer most editor integrations actually consume.
Tech Stack - The grammar source is JavaScript (grammar.js), compiled to C for the actual parser tables; the Rust binding (bindings/rust/lib.rs) is a thin extern "C" wrapper depending only on the lightweight tree-sitter-language crate, with cc as a build-dependency to compile parser.c/scanner.c. Equivalent thin bindings exist for Node.js (binding.gyp), Python (setup.py/pyproject.toml), Go (go.mod), and Swift (Package.swift), all wrapping the same generated C sources.
Code Quality - test/ contains corpus-based parse tests (input source plus expected S-expression trees), which is the standard tree-sitter testing convention and gives good coverage of grammar edge cases across ECMAScript features and JSX. CI (.github/workflows/ci.yml) runs across the multi-language binding matrix. The Rust binding includes an inline doc-test demonstrating a minimal parse, and a #[test] fn test_can_load_grammar() smoke test verifying the compiled language loads correctly.
API Design - Consumers only need one call — parser.set_language(&tree_sitter_javascript::LANGUAGE.into()) — to get a working parser; the crate’s real surface area is the constants it exports (LANGUAGE, NODE_TYPES, HIGHLIGHT_QUERY, LOCALS_QUERY, TAGS_QUERY) rather than functions to call, which keeps integration boilerplate minimal for editor and tooling authors.
Used by 2 apps in this directory
cocoindex
Data Engineering · AI Development
An incremental data indexing engine that keeps AI agent context perpetually fresh by reprocessing only what changed.
codegraph
Developer Tools · AI Code Assistants
A pre-indexed code knowledge graph that cuts AI tool calls by 58% and token costs by 16% — auto-syncing, 100% local, works with Claude Code, Cursor, Codex, and more.