tree-sitter-bash
Incremental Bash/shell grammar for the tree-sitter parsing library
Repository Health
Technical Analysis
tree-sitter-bash is the official Bash grammar for tree-sitter, the incremental parsing library used by editors and developer tools to build and maintain concrete syntax trees as shell scripts are edited. It ships a hand-tuned grammar covering Bash’s shell-specific syntax — command substitution, heredocs, parameter expansion, conditionals — along with bundled queries for syntax highlighting.
Because tree-sitter grammars re-parse only the changed portion of a file, tools built on tree-sitter-bash get fast, editor-grade syntax trees for .sh scripts without re-parsing the whole file on every keystroke, making it a common building block for shell linters, highlighters, and script-analysis tools.
What You Get
- A Bash/shell grammar covering command substitution, heredocs, expansions, and control flow
- Bundled
node-types.jsonmetadata describing the grammar’s AST node shapes - A prebuilt tree-sitter highlighting query (
queries/highlights.scm) - Official bindings for multiple ecosystems: Rust, Node.js, Python, Go, C, and Swift
Common Use Cases
- Powering Bash/shell syntax highlighting in editors and terminal tools built on tree-sitter
- Building shell-script linters or static analyzers that need a concrete syntax tree
- Code-navigation and structural-search tooling for
.sh/.bashfiles - Embedding incremental shell-script parsing inside a larger multi-language dev tool
Under The Hood
Architecture: The grammar is defined in JavaScript (grammar.js) using tree-sitter’s grammar DSL, then compiled ahead of time into a generated C parser (src/parser.c) that ships in the published crate. The Rust binding (bindings/rust/lib.rs, build.rs) links this C parser via extern "C" FFI and wraps its single entry point (tree_sitter_bash) as a safe LanguageFn constant, following the same shape as every other official tree-sitter grammar crate (including tree-sitter-php, added alongside this package).
Tech Stack: The repo is primarily C (the generated parser) with a JavaScript grammar source and native bindings for Rust, Node (binding.gyp), Python (setup.py/pyproject.toml), Go (go.mod), Swift (Package.swift), and CMake for C consumers. The Rust crate’s only runtime dependency is tree-sitter-language, with cc as a build-time dependency to compile the bundled C source.
Code Quality: The Rust binding includes an inline doctest parsing example and a #[cfg(test)] module verifying the grammar loads correctly. The test/ directory holds corpus-style test cases exercising Bash syntax edge cases (quoting, expansions, redirections) against expected parse trees, the standard tree-sitter grammar-testing convention. Recent commit activity is comparatively low relative to actively-developed grammars, consistent with Bash syntax being a stable, slowly-evolving target.
API Design: The public API is a single LANGUAGE constant plus a NODE_TYPES/HIGHLIGHT_QUERY string, mirroring the minimal-surface convention shared across tree-sitter language crates so switching grammars requires no API relearning. Getting started needs only tree_sitter::Parser::set_language(), though effective use assumes familiarity with tree-sitter’s own query and tree-traversal API, which lives in a separate crate.