Nextflow grammar for tree-sitter.
Target: Nextflow Strict Syntax (v2 Parser) -
NXF_SYNTAX_PARSER=v2This grammar is designed to support Nextflow's strict syntax mode, focusing on the cleaner, more consistent v2 parser syntax patterns.
- Parse rate: 100% error-free over the pinned nf-core/modules corpus
(2077/2077 files), measured by
scripts/parse_rate.py. - Corpus tests: 96 passing (
tree-sitter test). - Bindings: Node.js, Rust, C, and Python.
See ROADMAP.md for the parity roadmap and remaining work, and
CHANGELOG.md for release history.
- Core Nextflow syntax: process, workflow, and function definitions, variable declarations, includes, and parameters.
- DSL2: channel factories and operators, chained/piped channel operations,
take:/main:/emit:workflow sections. - Process bodies: directives,
input:/output:/when:sections, andscript:/shell:/exec:/stub:blocks. - Expressions: binary/unary operators, casts, ranges, lists, maps, closures
(including typed parameters), safe navigation (
?.), and spread (*.). - Strings: single/double/triple-quoted strings, GString interpolation, and slashy-string regexes.
- Control flow:
if/else,for-in loops,try/catch/finally,assert, andworkflow.onComplete/onErrorevent handlers. - Language injection: Bash/shell highlighting inside script blocks.
Scope: the grammar targets the Nextflow strict syntax only. Non-strict constructs (
while,switch, classes) are intentionally out of scope.
Published to PyPI on each tagged release:
pip install tree-sitter-nextflowThe Node, Rust, and C bindings are built from source:
git clone https://github.com/nextflow-io/tree-sitter-nextflow.git
cd tree-sitter-nextflow
tree-sitter generate
tree-sitter test- Node.js:
npm install(builds vianode-gyp-build). - Rust: add a path/git dependency on this repo in
Cargo.toml. - C:
makebuilds the shared library.
This grammar includes full ast-grep support for advanced Nextflow code analysis, linting, and refactoring.
Install ast-grep support with a single command:
curl -fsSL https://raw.githubusercontent.com/nextflow-io/tree-sitter-nextflow/main/scripts/install-ast-grep.sh | bashFor global installation:
curl -fsSL https://raw.githubusercontent.com/nextflow-io/tree-sitter-nextflow/main/scripts/install-ast-grep.sh | bash -s -- --globalUse the installation script to set up ast-grep for your project:
# Clone or download the repository
git clone https://github.com/nextflow-io/tree-sitter-nextflow.git
cd tree-sitter-nextflow
# Run the installation script
./scripts/install-ast-grep.sh
# Or install globally
./scripts/install-ast-grep.sh --globalThe script will:
- Detect your platform (macOS, Linux)
- Verify the appropriate parser library exists
- Copy
sgconfig.ymlto your project or~/.config/ast-grep/
If you prefer manual setup or need a custom configuration:
# 1. Copy sgconfig.yml to your Nextflow project
cp path/to/tree-sitter-nextflow/sgconfig.yml .
# 2. Update libraryPath if needed (for global install)
# Edit sgconfig.yml and use absolute paths to lib/ directoryPre-built parser libraries are included for:
- ✅ macOS ARM64 (Apple Silicon) -
lib/macos-arm64/libnextflow.dylib - ✅ Linux x64 -
lib/linux-x64/libnextflow.so
For other platforms, you can build the library yourself:
tree-sitter build --output libnextflow.soOnce installed, ast-grep works seamlessly with Nextflow files:
# Search for process definitions
ast-grep -l nextflow -p 'process $NAME { $$$ }' .
# Run built-in rules
ast-grep scan
# Outline a file (ast-grep >= 0.44.0)
ast-grep outline --lang nextflow \
--outline-rules outline/nextflow.yml --no-default-outline-rules main.nf
# Find deprecated Channel.from() usage
ast-grep -l nextflow -p 'Channel.from($$$)' .The project includes sgconfig.yml with platform-specific parser libraries:
- Custom Language: Nextflow with platform detection
- File Extensions:
.nf,.config - expandoChar:
_— an internal detail so the parser can tokenize patterns (Nextflow uses$for string interpolation). You still write metavariables as$VAR/$$$; ast-grep maps$↔_for you.
The rules/ directory includes linting rules for:
- Process naming conventions: Enforce UPPERCASE or camelCase naming
- Channel operations: Detect deprecated patterns (Channel.from, into, separate)
- DSL2 best practices: Workflow structure, tuple inputs, named emits
- String interpolation: Single vs double quotes, GString usage
# Find all process definitions
ast-grep -l nextflow -p 'process $NAME { $$$ }'
# Find workflows with take/main/emit structure
ast-grep -l nextflow -p 'workflow $NAME { take: $$$ main: $$$ emit: $$$ }'
# Find deprecated Channel.from() (flagged by rules)
ast-grep -l nextflow -p 'Channel.from($$$)'
# Search for hardcoded paths
ast-grep -l nextflow -p 'path("/$$$")'See docs/ast-grep/ for the full setup guide, pattern
library, and ast-grep outline documentation.
Create YAML files in rules/ directory:
id: my-custom-rule
language: nextflow
message: Custom rule message
severity: warning
rule:
pattern: process $NAME { $$$ }See ast-grep rule documentation for details.
- Code Search: Fast semantic search across Nextflow codebases
- Refactoring: Automated migrations (e.g., DSL1 → DSL2)
- Linting: Enforce coding standards and best practices
- CI/CD: Integrate rules into continuous integration pipelines
Contributions are welcome. Grammar changes go in grammar.js; run
tree-sitter generate && tree-sitter test before opening a PR, and add corpus
tests under test/corpus/. See ROADMAP.md for priorities and
CLAUDE.md for the development workflow.
MIT © Edmund Miller