tree-sitter-zig

A fast, incremental Zig grammar for tree-sitter that powers syntax highlighting, code folding, and structural code queries in editors and dev tools.

Library
PyPI
v1.1.2
41stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
28/100Needs Attention
Development Activity0
Maintenance20
Community20
Maturity52
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
59/100Fair
Architecture65
Code Quality55
Innovation80
Learning Curve35

tree-sitter-zig is the official Zig grammar for the tree-sitter incremental parsing library, maintained under the tree-sitter-grammars organization. It compiles the Zig language’s syntax (based on the upstream zig-spec grammar) into a tree-sitter parser, giving editors, linters, and static-analysis tools a fast, error-tolerant, incrementally-updatable syntax tree for Zig source code.

The grammar is published simultaneously to npm, crates.io, and PyPI from a single generated C parser, with matching query files for syntax highlighting, code folding, local-variable scoping, indentation, and language injection. It is validated in CI by parsing the entire upstream Zig compiler source tree on every change, making it a practical, low-friction dependency for any tool that needs to understand Zig code structurally rather than as plain text.

What You Get

  • A compiled tree-sitter parser for Zig (src/parser.c) generated from a single grammar.js source of truth, distributed to npm, crates.io, and PyPI
  • Prebuilt highlighting queries (queries/highlights.scm) for editor and terminal syntax highlighting
  • Code-folding, indentation, and local-variable-scope query files for editor integrations (folds.scm, indents.scm, locals.scm)
  • Language-injection queries (injections.scm) for embedding Zig parsing inside other file types
  • Native bindings for Node.js (node-gyp/prebuildify), Rust (a typed LanguageFn crate), and Zig (a build.zig-integrated module)
  • A node-types.json static type description of every AST node the grammar can produce

Common Use Cases

  • Adding Zig syntax highlighting to an editor, terminal pager, or documentation site via tree-sitter-powered highlighters
  • Building linters, formatters, or static-analysis tools that need a real Zig AST instead of regex/text scanning
  • Powering code folding, indentation, and ‘jump to definition’-style local-scope resolution in editor plugins
  • Embedding Zig code blocks inside other tree-sitter-parsed formats (e.g. Markdown, MDX) via injection queries
  • Using the Python binding to script structural queries or transformations over Zig codebases

Under The Hood

Architecture The grammar is authored once in grammar.js using tree-sitter’s JavaScript DSL (rules like container_field, expression, comptime_type_expression), which tree-sitter generate compiles into a large machine-generated C parser (src/parser.c, ~169k lines of LR/GLR state tables) plus a node-types.json/grammar.json description of the resulting AST shape. Every per-language binding is a thin wrapper around that same compiled parser: the Node binding (bindings/node/binding.cc) links it via node-addon-api and node-gyp-build/prebuildify, the Rust crate (bindings/rust/lib.rs) exposes it as a typed LanguageFn constant via the tree-sitter-language crate, and the Zig binding (bindings/zig/root.zig) wires it into a native build.zig module — so grammar.js is the single source of truth and everything else, including the file published to PyPI, is generated or derived from it.

Tech Stack The grammar itself is written against the tree-sitter-cli DSL (tree-sitter-cli ^0.25.8, peer dependency tree-sitter ^0.22.4) and compiles to C99. The Node package depends on node-addon-api ^8.5.0 and node-gyp-build ^4.8.4; the Rust crate (edition 2021) depends on tree-sitter-language 0.1 and cc 1.2 as a build-dependency; a native build.zig/build.zig.zon module serves Zig consumers directly. All three ecosystem packages, plus the PyPI package, are published from the same tagged commit via a shared tree-sitter/workflows reusable GitHub Actions pipeline (package-npm.yml, package-crates.yml, package-pypi.yml).

Code Quality There is no hand-written unit-test suite for grammar correctness beyond a one-line ‘can load grammar’ smoke test per binding (Rust #[cfg(test)], bindings/zig/test.zig, bindings/node/binding_test.js). Real correctness is instead validated externally in CI: the workflow clones the actual upstream ziglang/zig compiler source tree on every push/PR and parses every .zig file in it via tree-sitter/parse-action, maintaining an explicit allowlist of known-invalid fixture files, while a separate ts_query_ls-based job lints every query file for correctness. ESLint (eslint-config-treesitter) runs on grammar.js itself. There is no application-level type system or error handling beyond tree-sitter’s built-in error-recovery parsing, which is expected for a generated-parser project of this kind.

API Design Consumption is idiomatic and near-zero-configuration in every supported ecosystem: Node just require("tree-sitter-zig") (which transparently selects a prebuilt binary via node-gyp-build, with a separate static-analyzable path for bun build --compile), Rust consumers import a single typed tree_sitter_zig::LANGUAGE constant plus a re-exported NODE_TYPES string, and Zig consumers get a build.zig-integrated module — all following the same three-line ‘create parser, set language, parse’ pattern documented in the crate’s own doc example. The only project-specific surface is the .scm query files, which follow the same conventions used across the entire tree-sitter grammar ecosystem, so familiarity with any other tree-sitter-* grammar transfers directly.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search