Readme
Plotnik
A type-safe query language for Tree-sitter .
Powered by the arborium grammar collection.
⚠️ BETA: NOT FOR PRODUCTION USE ⚠️
Tree-sitter gives you the syntax tree. Extracting structured data from it still means writing imperative navigation code, null checks, and maintaining type definitions by hand. Plotnik makes extraction declarative: write a pattern, get typed data. The query is the type definition.
Features
Installation
cargo install plotnik
By default, 15 common languages are included. To add specific languages:
cargo install plotnik -- features lang-ruby,lang-elixir
Or with all 80+ languages:
cargo install plotnik -- features all-languages
Example
Extract function signatures from Rust. Type references itself to handle nested generics like Option < Vec < String > > .
query. ptk :
Type = [
Simple: [ ( type_identifier ) ( primitive_type ) ] @ name :: string
Generic: ( generic_type
type: ( type_identifier ) @ name :: string
type_arguments: ( type_arguments ( Type ) * @ args) )
]
Func = ( function_item
name: ( identifier ) @ name :: string
parameters: ( parameters
( parameter
pattern: ( identifier ) @ param :: string
type: ( Type ) @ type
) * @ params) )
Funcs = ( source_file ( Func ) * @ funcs)
lib.rs :
fn get ( key : Option < Vec < String > > ) { }
fn set ( key : String, val : i32 ) { }
Plotnik infers TypeScript types from the query structure. Type is recursive: args: Type[ ] .
❯ plotnik infer query.ptk -- lang rust
export type Type =
| { $ tag : " Simple" ; $ data : { name: string } }
| { $ tag : " Generic" ; $ data : { name: string; args: Type[ ] } } ;
export interface Func {
name: string;
params: { param: string; type: Type } [ ] ;
}
export interface Funcs {
funcs: Func[ ] ;
}
Run the query against lib.rs to extract structured JSON:
❯ plotnik exec query.ptk lib.rs
{
" funcs" : [
{
" name" : " get" ,
" params" : [{
" param" : " key" ,
" type" : {
" $ tag " : " Generic" ,
" $ data " : {
" name" : " Option" ,
" args" : [{
" $ tag " : " Generic" ,
" $ data " : {
" name" : " Vec" ,
" args" : [ { " $ tag " : " Simple" , " $ data " : { " name" : " String" } } ]
}
} ]
}
}
} ]
},
{
" name" : " set" ,
" params" : [
{ " param" : " key" , " type" : { " $ tag " : " Simple" , " $ data " : { " name" : " String" } } } ,
{ " param" : " val" , " type" : { " $ tag " : " Simple" , " $ data " : { " name" : " i32" } } }
]
}
]
}
Why
Pattern matching over syntax trees is powerful, but tree-sitter queries produce flat capture lists. You still need to assemble the results, handle missing captures, and define types by hand. Plotnik closes this gap: the query describes structure, the engine guarantees it.
Documentation
Acknowledgments
Max Brunsfeld created Tree-sitter; Amaan Qureshi and other contributors maintain the parser ecosystem that makes this project possible.
License
This project is licensed under the Apache License (Version 2.0) .