Skip to main content

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.

A Tree-sitter query consists of one or more patterns written as S-expressions. Each pattern matches a certain set of nodes in a syntax tree.

Basic Node Matching

The expression to match a given node consists of a pair of parentheses containing the node’s type and optionally, patterns for the node’s children.

Matching with All Children

This pattern matches any binary_expression node whose children are both number_literal nodes:
(binary_expression (number_literal) (number_literal))

Matching with Some Children

Children can be omitted. This matches any binary_expression where at least one child is a string_literal node:
(binary_expression (string_literal))

Fields

It’s good practice to make patterns more specific by specifying field names associated with child nodes. Prefix a child pattern with a field name followed by a colon.

Using Field Names

This pattern matches an assignment_expression node where the left child is a member_expression whose object is a call_expression:
(assignment_expression
  left: (member_expression
    object: (call_expression)))
Using field names makes your queries more robust and easier to understand. They document the semantic role of each child in the pattern.

Negated Fields

You can constrain a pattern to only match nodes that lack a certain field by prefixing the field name with !. This pattern matches a class declaration with no type parameters:
(class_declaration
  name: (identifier) @class_name
  !type_parameters)
Negated fields are useful for matching simpler variants of a node type, like functions without generic parameters or classes without decorators.

Anonymous Nodes

The parenthesized syntax only applies to named nodes. To match specific anonymous nodes (like operators or punctuation), write their name between double quotes. This pattern matches any binary_expression where the operator is != and the right side is null:
(binary_expression
  operator: "!="
  right: (null))

Common Anonymous Nodes

Anonymous nodes typically include:
  • Operators: "+", "-", "*", "/", "==", "!="
  • Punctuation: "(", ")", "{", "}", "[", "]", ",", ";"
  • Keywords: Language-specific keywords that appear literally in code

Special Nodes

The Wildcard Node

A wildcard node matches any node, similar to . in regular expressions.
(_) matches any named node:
(call (_) @call.inner)
This matches any named node inside a call.

The ERROR Node

When the parser encounters text it does not recognize, it creates an ERROR node. These can be queried to detect syntax errors:
(ERROR) @error-node
ERROR nodes indicate unparseable code. They’re useful for error detection but may not provide detailed structure.

The MISSING Node

If the parser recovers from errors by inserting a missing token, it creates a MISSING node. These are zero-width nodes that represent inserted tokens. Query all missing nodes:
(MISSING) @missing-node
Query specific missing node types:
(MISSING identifier) @missing-identifier
(MISSING ";") @missing-semicolon
MISSING nodes are not captured by (ERROR) queries. Use both to detect all syntax errors in a parse tree.

Supertype Nodes

Some node types are marked as supertypes in a grammar. A supertype contains multiple subtypes, allowing you to match any of them without listing each individually.

Matching Any Subtype

For example, expression is often a supertype that can represent any kind of expression:
(expression) @any-expression
This matches binary_expression, call_expression, identifier, and any other expression subtype.

Matching Specific Subtypes

Use the syntax supertype/subtype to query specific subtypes:
(expression/binary_expression) @binary-expression
This matches a binary_expression only if it is a child of the expression supertype.

Supertypes with Anonymous Nodes

This also works with anonymous nodes:
(expression/"()") @empty-expression

Best Practices

Field names make queries more maintainable and self-documenting. They also make queries more resilient to grammar changes that affect child ordering but not field names.
Begin with specific patterns that match exactly what you need. Generalize only if you need broader matches. This reduces false positives.
Use supertypes when you want to match multiple related node types. This keeps queries concise and easier to maintain.
Consider whether your query should match on partial or erroneous code. Use ERROR and MISSING nodes to handle syntax errors gracefully.

Next Steps

Query Operators

Learn how to capture nodes, use quantifiers, and create complex patterns

Predicates

Add conditions and metadata to your patterns