tree-sitter-bash

Incremental Bash/shell grammar for the tree-sitter parsing library

Library
Cargo
v0.25.1
327stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
45/100Fair
Development Activity0
Maintenance20
Community80
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
70/100Good
Architecture74
Code Quality74
Innovation60
Learning Curve70

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.json metadata 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/.bash files
  • 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.

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