Skip to main content

Code of Conduct

Contributors to Tree-sitter should abide by the Contributor Covenant.

Developing Tree-sitter

Prerequisites

To make changes to Tree-sitter, you should have:
  1. A C compiler, for compiling the core library and the generated parsers.
  2. A Rust toolchain, for compiling the Rust bindings, the highlighting library, and the CLI.
  3. Node.js and NPM, for generating parsers from grammar.js files.
  4. Either Emscripten, Docker, or podman for compiling the library to Wasm.

Building

Clone the repository:
Optionally, build the Wasm library. If you skip this step, then the tree-sitter playground command will require an internet connection. If you have Emscripten installed, this will use your emcc compiler. Otherwise, it will use Docker or Podman:
Build the Rust libraries and the CLI:
This will create the tree-sitter CLI executable in the target/release folder. If you want to automatically install the tree-sitter CLI in your system, you can run:
For faster iteration during development, you can use the release-dev profile:

Testing

Before you can run the tests, you need to fetch some upstream grammars that are used for testing:
To test any changes you’ve made to the CLI, you can regenerate these parsers using your current CLI code:
Then you can run the tests:
Similarly, to test the Wasm binding, you need to compile these parsers to Wasm:

Wasm Stdlib

The tree-sitter Wasm stdlib can be built via xtask:
This command looks for the Wasi SDK indicated by the TREE_SITTER_WASI_SDK_PATH environment variable. You can download it from the releases page. Similarly, this command also looks for the wasm-opt tool from binaryen indicated by the TREE_SITTER_BINARYEN_PATH environment variable. You can download it from the releases page.
Any changes to crates/language/wasm/** requires rebuilding the tree-sitter Wasm stdlib via cargo xtask build-wasm-stdlib.

Debugging

The test script has a number of useful flags. You can list them all by running cargo xtask test -h. If you want to run a specific unit test, pass its name (or part of its name) as an argument:
You can run the tests under the debugger (either lldb or gdb) using the -g flag:
To run tests for a particular language, you can pass the -l flag. Additionally, if you want to run a particular example from the corpus, you can pass the -e flag:
If you are using lldb to debug the C library, tree-sitter provides custom pretty printers for several of its types. You can enable these helpers by importing them:

Published Packages

The main tree-sitter/tree-sitter repository contains the source code for several packages that are published to package registries:

Rust Crates on crates.io

tree-sitter

A Rust binding to the core library

tree-sitter-config

User configuration of the command-line tool

tree-sitter-cli

The command-line tool

tree-sitter-generate

The parser-generation library

tree-sitter-highlight

The syntax-highlighting library

tree-sitter-language

Language type for grammars

tree-sitter-loader

Parser building and loading library

tree-sitter-tags

The syntax-tagging library

JavaScript Modules on npmjs.com

web-tree-sitter

A Wasm-based JavaScript binding to the core library

tree-sitter-cli

The command-line tool

Other Language Bindings

There are also several other dependent repositories that contain published packages:

node-tree-sitter

Node.js bindings published as tree-sitter on npmjs.com

py-tree-sitter

Python bindings published as tree-sitter on PyPI.org

go-tree-sitter

Go bindings published as tree_sitter on pkg.go.dev

Release Workflow

Tree-sitter follows semver (pre-1.0.0) with a dual development strategy:
  • All development happens on the master branch. Any new PR (bugfix or feature) must target master.
  • Applicable bugfixes and minor improvements are backported to the latest release-0.x branch.
No new features or breaking changes should be backported. This ensures patch releases are drop-in replacements that are always safe to update to.
Important: All crates within the project are versioned in lockstep with the exception of tree-sitter-language, which is versioned independently and only bumped when necessary.

Minor Releases

Minor releases (0.x.0) are made from the master branch:
  1. Create a “release v0.x.0” PR on master and apply the ci:check release label
  2. If indicated, bump the patch version of the language crate
  3. Once the PR is merged, tag the commit and push via git push --tags
  4. Edit the GitHub release to include release notes
  5. Create a new release-0.x branch and push to GitHub
  6. Bump all version numbers (except language crate) to 0.{x+1}.0
On average, minor releases should happen 1-3 times a year.

Patch Releases

Patch releases (0.x.y) are made from the release-0.x branch:
  1. Bump all version numbers (except language crate) to 0.x.y
  2. Create a “release v0.x.y” PR on release-0.x and apply the ci:check release label
  3. If indicated, bump the patch version of the language crate
  4. Once the PR is merged, tag the commit and push via git push --tags
  5. Edit the GitHub release to include release notes
On average, patch releases should happen every six weeks.

Developing Documentation

The documentation is built using mdBook. Most of the documentation is written in Markdown, and you can find these files at docs/src.

Prerequisites for Local Development

To run and iterate on the docs locally, install the required tools:

Running the Documentation Server

Start a local server with live-reload:
Any changes you make to the markdown files will be reflected in the browser after a short delay.

Improving the Playground

The playground code can be found in: The playground uses CodeMirror as the editor, and fetches the tree-sitter module from the tree-sitter.github.io repo.