The Query API provides functions to create, execute, and manage queries programmatically. This reference covers the C API, which is the foundation for language bindings.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/tree-sitter/tree-sitter/llms.txt
Use this file to discover all available pages before exploring further.
Creating Queries
ts_query_new
Create a query by specifying a string containing one or more patterns.
Parameters
The language to create the query for. Must match the grammar used to parse the target syntax trees.
A string containing one or more query patterns written in the query syntax.
The length of the source string in bytes.
Output parameter. If there’s an error, this will be set to the byte offset where the error occurred.
Output parameter. If there’s an error, this will be set to the error type.
Returns
A pointer to aTSQuery object, or NULL if there was an error.
Error Handling
If the query has syntax errors or references invalid node types or fields, the function still returns aTSQuery, but error_offset and error_type indicate the problem.
The
TSQuery value is immutable and can be safely shared between threads.Error Types
TSQueryError
Enumerates possible query errors:
No error occurred. The query is valid.
TSQueryErrorSyntax
The query has a syntax error. Check the S-expression structure.
TSQueryErrorNodeType
The query references a node type that doesn’t exist in the grammar.
TSQueryErrorField
The query references a field name that doesn’t exist in the grammar.
TSQueryErrorCapture
The query has an invalid capture name or usage.
Creating Query Cursors
ts_query_cursor_new
Create a cursor for executing queries.
Returns
A pointer to a newTSQueryCursor object.
Executing Queries
ts_query_cursor_exec
Execute a query on a syntax node.
Parameters
The query cursor to use for execution.
The query to execute.
The syntax tree node to search within. The query will match against this node and all its descendants.
Iterating Over Matches
Data Structures
The API provides structures for representing captures and matches:TSQueryCapture
Represents a single captured node.
node: The captured syntax tree nodeindex: The index of the capture in the query (corresponds to the order of@capturenames)
TSQueryMatch
Represents a complete pattern match.
id: Unique identifier for this matchpattern_index: Which pattern in the query matched (0-based)capture_count: Number of captures in this matchcaptures: Array of captured nodes
ts_query_cursor_next_match
Retrieve the next match from the query cursor.
Parameters
The query cursor to retrieve matches from.
Output parameter. Will be populated with the next match’s data.
Returns
trueif a match was found andmatchwas populatedfalseif there are no more matches
Example Usage
Basic Query Execution
Error Handling
Reusing Query Cursors
Memory Management
Query Lifecycle
Query Lifecycle
- Create with
ts_query_new() - Use across multiple threads (read-only)
- Delete with
ts_query_delete()when done - Deletion is thread-safe if no queries are executing
Cursor Lifecycle
Cursor Lifecycle
- Create with
ts_query_cursor_new() - Use for one or more query executions (single thread)
- Delete with
ts_query_cursor_delete()when done - Do not share cursors between threads
Match Data
Match Data
TSQueryMatchis populated by reference- The
capturesarray is valid until the next call tots_query_cursor_next_match() - Copy data if you need to retain it longer
Advanced Features
Query Introspection
Queries expose information about their structure:Query Predicates
Access predicates and directives programmatically:Predicate evaluation is typically implemented in language bindings, not the C library. The C API exposes predicates in structured form for bindings to interpret.
Language Bindings
Most users interact with queries through language bindings:Rust
tree-sitter crate provides idiomatic Rust API with predicate supportJavaScript
web-tree-sitter and Node bindings offer promise-based APIsPython
tree-sitter package provides Pythonic interface with predicate evaluation- Predicate implementation
- Iterator patterns
- Integration with language features
Performance Considerations
Share Queries
Create queries once and share them across threads. Query creation has overhead, especially for complex patterns.
Reuse Cursors
Within a thread, reuse query cursors for multiple executions. Cursor creation and deletion have some overhead.
Limit Query Scope
Execute queries on the smallest node that contains your target. Don’t query the entire tree if you only need a function body.
Next Steps
Query Syntax
Learn how to write query patterns
Predicates
Understand how to implement and use predicates
Parsers
Learn about parsing and syntax trees
Language Bindings
Explore Tree-sitter APIs in other languages