Arborist
Multi-language code complexity metrics powered by tree-sitter.
Arborist computes cognitive complexity (SonarSource), cyclomatic complexity (McCabe), and source lines of code (SLOC) for functions and methods across 12 programming languages -- all from a single, embeddable Rust library.
Supported Languages
| Language | Feature flag | Extensions | Default |
|---|---|---|---|
| Rust | rust |
.rs |
Yes |
| Python | python |
.py, .pyi |
Yes |
| JavaScript | javascript |
.js, .jsx, .mjs, .cjs |
Yes |
| TypeScript | typescript |
.ts, .tsx, .mts, .cts |
Yes |
| Java | java |
.java |
Yes |
| Go | go |
.go |
Yes |
| C# | csharp |
.cs |
Opt-in |
| C++ | cpp |
.cpp, .cc, .cxx, .hpp, .hxx, .hh |
Opt-in |
| C | c |
.c, .h |
Opt-in |
| PHP | php |
.php |
Opt-in |
| Kotlin | kotlin |
.kt, .kts |
Opt-in |
| Swift | swift |
.swift |
Opt-in |
Feature Flags
Arborist uses Cargo feature flags to control which tree-sitter grammars are compiled. Each language is an independent, optional feature that pulls in its corresponding tree-sitter grammar crate.
To enable all 12 languages, use features = ["all"].
Tiers
- Tier 1 (default): Rust, Python, JavaScript, TypeScript, Java, Go --
the most mature tree-sitter grammars. Enabled automatically unless you
set
default-features = false. - Tier 2 (opt-in): C#, C++, C, PHP, Kotlin, Swift -- require enabling
their feature flag explicitly or using the
allcomposite feature.
Individual features
| Feature flag | Language | Tier | tree-sitter crate |
|---|---|---|---|
rust |
Rust | 1 | tree-sitter-rust |
python |
Python | 1 | tree-sitter-python |
javascript |
JavaScript | 1 | tree-sitter-javascript |
typescript |
TypeScript | 1 | tree-sitter-typescript |
java |
Java | 1 | tree-sitter-java |
go |
Go | 1 | tree-sitter-go |
csharp |
C# | 2 | tree-sitter-c-sharp |
cpp |
C++ | 2 | tree-sitter-cpp |
c |
C | 2 | tree-sitter-c |
php |
PHP | 2 | tree-sitter-php |
kotlin |
Kotlin | 2 | tree-sitter-kotlin-ng |
swift |
Swift | 2 | tree-sitter-swift |
Composite features
| Feature | Expands to |
|---|---|
default |
rust, python, javascript, typescript, java, go |
all |
All 12 languages (default + csharp, cpp, c, php, kotlin, swift) |
Compile-time note: Each grammar adds compile time and binary size. Use
default-features = falsewith only the languages you need for minimal builds, orallwhen you need broad language coverage.
Installation
Add to your Cargo.toml:
# Default features (Tier 1): Rust, Python, JavaScript, TypeScript, Java, Go
[]
= "0.1"
Select specific languages to reduce compile time:
[]
= { = "0.1", = false, = ["rust", "python"] }
Enable all 12 languages:
[]
= { = "0.1", = ["all"] }
Quick Start
Analyze a file
use ;
Analyze source code from memory
use ;
let source = r#"
def hello(name):
if name:
print(f"Hello, {name}!")
else:
print("Hello, world!")
"#;
let report = analyze_source?;
// report.functions[0].cognitive == 2 (if + else)
# Ok::
Configure thresholds
use ;
let config = AnalysisConfig ;
let report = analyze_file_with_config?;
for func in &report.functions
# Ok::
Serialize to JSON
let report = analyze_file?;
let json = to_string_pretty?;
println!;
# Ok::
Metrics
Cognitive Complexity
Follows the SonarSource specification by G. Ann Campbell. Measures how difficult code is to understand:
- +1 for each control flow break (
if,for,while,match,catch, etc.) - Nesting penalty: nested control flow adds the current nesting depth
- Boolean operator sequences: one increment per operator switch (
&&to||) - Flat
else if: does not increase nesting - +1 for recursive calls and lambda/closure nesting
Cyclomatic Complexity
Standard McCabe cyclomatic complexity (base 1 + decision points). Measures the number of linearly independent paths through a function.
SLOC
Physical source lines of code, excluding blank lines and comment-only lines.
Contributing
- Fork the repository
- Create a feature branch
- Follow TDD: write fixtures and failing tests before implementation
- Run
cargo clippy -- -D warningsandcargo test --all-features - Submit a pull request
Adding a new language
- Create
src/languages/<lang>.rsimplementing theLanguageProfiletrait - Add the grammar crate as an optional dependency in
Cargo.toml - Add a feature flag and wire up detection in
src/languages/mod.rs - Create 6 test fixtures in
tests/fixtures/<lang>/ - Write integration tests
Built with AI · Powered by StrayMark
Arborist is an experiment in disciplined AI-assisted development. The implementation — tree-sitter integration, the 177-test suite, all 12 language profiles — was authored largely by AI agents under human direction.
To make that velocity sustainable, we use StrayMark:
a CLI for cognitive discipline in AI-assisted engineering. It turned every
architectural choice into an AIDEC record, every implementation block into
an AILOG, and the test plan into a TES — all under .straymark/, append-only
and audit-ready. The governance artifacts emerged alongside the code,
not as homework after.
StrayMark is built by Strange Days Tech — the same team behind Arborist. It is the tool we made to solve our own problem.
License
Licensed under either of:
at your option.
Copyright
Arborist is © 2026 Strange Days Tech S.A.S. de C.V. — original author and intellectual-property holder of the source code.
The library is released under the dual MIT / Apache-2.0 license above; this notice records authorship and does not modify those license terms. Each source file carries an SPDX header reflecting the same.
Built by Strange Days Tech — México.