Tree Sitter NG
May 1, 2026 ยท View on GitHub
Next generation Tree Sitter Java binding.
Getting started
Add dependencies to your build.gradle or pom.xml.
// Gradle
dependencies {
// add tree sitter
implementation 'io.github.bonede:tree-sitter:$VERSION'
// add json parser
implementation 'io.github.bonede:tree-sitter-json:$VERSION'
}
<!-- Maven -->
<dpendencies>
<!-- add tree sitter -->
<dependency>
<groupId>io.github.bonede</groupId>
<artifactId>tree-sitter</artifactId>
<version>$VERSION</version>
</dependency>
<!-- add json parser -->
<dependency>
<groupId>io.github.bonede</groupId>
<artifactId>tree-sitter-json</artifactId>
<version>$VERSION</version>
</dependency>
</dpendencies>
Start hacking!
// imports are omitted
class Main {
public static void main(String[] args) {
TSParser parser = new TSParser();
// Use `TSLanguage.load` instead if you would like to load parsers as shared object(.so, .dylib, or .dll).
// TSLanguage.load("path/to/languane/shared/object", "tree_sitter_some_lang");
TSLanguage json = new TreeSitterJson();
parser.setLanguage(json);
TSTree tree = parser.parseString(null, "[1, null]");
TSNode rootNode = tree.getRootNode();
TSNode arrayNode = rootNode.getNamedChild(0);
TSNode numberNode = arrayNode.getNamedChild(0);
}
}
Features
- 100% Tree Sitter API coverage.
- Easy to bootstrap cross compiling environments powered by Zig.
- Built-in official parsers.
- Load parsers as shared object from disk.
Supported CPUs and OSes
- x86_64-windows
- x86_64-macos
- aarch64-macos
- x86_64-linux
- aarch64-linux
- aarch64-linux-android
Android native builds
Android native builds use the Android NDK compiler. If ANDROID_NDK_HOME, ANDROID_NDK_ROOT, ANDROID_HOME, or ANDROID_SDK_ROOT points to an installed NDK, the build uses it. Otherwise, Gradle downloads the NDK version configured by androidNdkVersion in gradle.properties into the root build/android-ndk directory.
Developers: How to Add a Parser
To add a new language parser to this project, we provide a code generation task that handles most of the boilerplate. This is also how you can add an "unofficial" or community parser.
-
Generate the subproject: Run the
gentask, providing the language name (in this example, Kotlin), its version, and the URL to its source code zip file../gradlew gen --parser-name=kotlin --parser-version=0.3.8 --parser-zip=https://github.com/fwcd/tree-sitter-kotlin/archive/refs/tags/0.3.8.zipThis will create a new directory
tree-sitter-kotlinwith the correctbuild.gradle,gradle.properties, JNI bindings, and Java class extendingTSLanguage. Finally, an entry ofinclude 'tree-sitter-kotlin'will be inserted intosettings.gradle. -
Build native modules and test: Our build system automatically uses Zig to cross-compile the native shared libraries for the new parser. You can trigger the download, native compilation, and tests:
./gradlew :tree-sitter-kotlin:buildNative ./gradlew :tree-sitter-kotlin:test
Built-in official parsers
| Name | Version |
|---|---|
tree-sitter-agda | |
tree-sitter-bash | |
tree-sitter-c | |
tree-sitter-c-sharp | |
tree-sitter-cpp | |
tree-sitter-css | |
tree-sitter-embedded-template | |
tree-sitter-go | |
tree-sitter-haskell | |
tree-sitter-html | |
tree-sitter-java | |
tree-sitter-javascript | |
tree-sitter-json | |
tree-sitter-julia | |
tree-sitter-ocaml | |
tree-sitter-php | |
tree-sitter-python | |
tree-sitter-regex | |
tree-sitter-ruby | |
tree-sitter-rust | |
tree-sitter-scala | |
tree-sitter-tsx | |
tree-sitter-typescript | |
tree-sitter-verilog |
API Tour
class Main {
public static void main(String[] args) {
String jsonSource = "[1, null]";
TSParser parser = new TSParser();
TSLanguage json = new TreeSitterJson();
// set language parser
parser.setLanguage(json);
// parser with string input
parser.parseString(null, jsonSource);
parser.reset();
// or parser with encoding
parser.parseStringEncoding(null, JSON_SRC, TSInputEncoding.TSInputEncodingUTF8);
parser.reset();
// or parser with custom reader
byte[] buffer = new byte[1024];
TSReader reader = (buf, offset, position) -> {
if(offset >= jsonSource.length()){
return 0;
}
ByteBuffer charBuffer = ByteBuffer.wrap(buf);
charBuffer.put(jsonSource.getBytes());
return jsonSource.length();
};
TSTree tree = parser.parse(buffer, null, reader, TSInputEncoding.TSInputEncodingUTF8);
// traverse the AST tree with DOM like APIs
TSNode rootNode = tree.getRootNode();
TSNode arrayNode = rootNode.getNamedChild(0);
// or travers the AST with cursor
TSTreeCursor rootCursor = new TSTreeCursor(rootNode);
rootCursor.gotoFirstChild();
// or query the AST with S-expression
TreeSitterQuery query = new TSQuery(json, "((document) @root)");
TSQueryCursor cursor = new TSQueryCursor();
cursor.exec(query, rootNode);
SQueryMatch match = new TSQueryMatch();
while(cursor.nextMatch(match)){
// do something with the match
}
// debug the parser with a logger
TSLogger logger = (type, message) -> {
System.out.println(message);
};
parser.setLogger(logger);
// or output the AST tree as DOT graph
File dotFile = File.createTempFile("json", ".dot");
parser.printDotGraphs(dotFile);
}
}