Use this file to discover all available pages before exploring further.
This guide walks you through parsing your first source code file with Tree-sitter. We’ll use real examples from the Tree-sitter codebase to show you the basics.
Parse source code stored in a custom data structure:
const sourceLines = [ 'let x = 1;', 'console.log(x);'];const tree = parser.parse((index, position) => { let line = sourceLines[position.row]; if (line) return line.slice(position.column);});
// Access all childrenlet child_count = root_node.child_count();for i in 0..child_count { let child = root_node.child(i).unwrap(); println!("Child {}: {}", i, child.kind());}// Access named children only (skip tokens like punctuation)let named_child_count = root_node.named_child_count();for i in 0..named_child_count { let child = root_node.named_child(i).unwrap(); println!("Named child {}: {}", i, child.kind());}// Navigate siblings and parentif let Some(next_sibling) = root_node.next_sibling() { println!("Next sibling: {}", next_sibling.kind());}
// Access all childrenfor (let i = 0; i < rootNode.childCount; i++) { const child = rootNode.child(i); console.log(`Child ${i}: ${child.type}`);}// Access named children only (skip tokens like punctuation)for (let i = 0; i < rootNode.namedChildCount; i++) { const child = rootNode.namedChild(i); console.log(`Named child ${i}: ${child.type}`);}// Navigate siblings and parentif (rootNode.nextSibling) { console.log('Next sibling:', rootNode.nextSibling.type);}
// Access all childrenuint32_t child_count = ts_node_child_count(root_node);for (uint32_t i = 0; i < child_count; i++) { TSNode child = ts_node_child(root_node, i); printf("Child %d: %s\n", i, ts_node_type(child));}// Access named children onlyuint32_t named_child_count = ts_node_named_child_count(root_node);for (uint32_t i = 0; i < named_child_count; i++) { TSNode child = ts_node_named_child(root_node, i); printf("Named child %d: %s\n", i, ts_node_type(child));}// Navigate siblingsTSNode next_sibling = ts_node_next_sibling(root_node);if (!ts_node_is_null(next_sibling)) { printf("Next sibling: %s\n", ts_node_type(next_sibling));}
Use the “named” variants of navigation methods (named_child, next_named_sibling, etc.) to work with the tree as an abstract syntax tree, skipping punctuation tokens.
One of Tree-sitter’s key features is efficient incremental parsing. When source code changes, you can update the tree instead of reparsing from scratch:
Rust
JavaScript
C
use tree_sitter::{InputEdit, Point};let source_code = "fn test() {}";let mut tree = parser.parse(source_code, None).unwrap();// The source code changed from "fn test() {}" to "fn test(a: u32) {}"let new_source_code = "fn test(a: u32) {}";// Tell the tree about the edittree.edit(&InputEdit { start_byte: 8, old_end_byte: 8, new_end_byte: 14, start_position: Point::new(0, 8), old_end_position: Point::new(0, 8), new_end_position: Point::new(0, 14),});// Reparse with the old tree for efficiencylet new_tree = parser.parse(new_source_code, Some(&tree));
let sourceCode = 'let x = 1;';let tree = parser.parse(sourceCode);// The source code changed from "let" to "const"const newSourceCode = 'const x = 1;';// Tell the tree about the edittree.edit({ startIndex: 0, oldEndIndex: 3, newEndIndex: 5, startPosition: {row: 0, column: 0}, oldEndPosition: {row: 0, column: 3}, newEndPosition: {row: 0, column: 5},});// Reparse with the old tree for efficiencyconst newTree = parser.parse(newSourceCode, tree);
const char *source_code = "[1, null]";TSTree *tree = ts_parser_parse_string(parser, NULL, source_code, strlen(source_code));// The source code changedconst char *new_source_code = "[1, 2, null]";// Tell the tree about the editTSInputEdit edit = { .start_byte = 3, .old_end_byte = 3, .new_end_byte = 6, .start_point = {0, 3}, .old_end_point = {0, 3}, .new_end_point = {0, 6},};ts_tree_edit(tree, &edit);// Reparse with the old tree for efficiencyTSTree *new_tree = ts_parser_parse_string( parser, tree, // Pass the old tree new_source_code, strlen(new_source_code));
Incremental parsing is significantly faster than reparsing from scratch. Tree-sitter reuses unchanged portions of the tree, making it ideal for text editors and other real-time applications.
You can load language grammars compiled to WebAssembly:
use tree_sitter::{Parser, WasmStore};use tree_sitter::wasmtime::Engine;// Create a Wasm engine and storelet engine = Engine::default();let mut store = WasmStore::new(&engine).unwrap();let mut parser = Parser::new();parser.set_wasm_store(store).unwrap();// Load a language from a Wasm fileconst JAVASCRIPT_GRAMMAR: &[u8] = include_bytes!("path/to/tree-sitter-javascript.wasm");let mut store = WasmStore::new(&engine).unwrap();let javascript = store .load_language("javascript", JAVASCRIPT_GRAMMAR) .unwrap();parser.set_language(&javascript).unwrap();// Now parse JavaScript codelet source_code = "let x = 1;";let tree = parser.parse(source_code, None).unwrap();
The wasm feature must be enabled in your Cargo.toml to use Wasm grammars.