A linter for GROQ queries that detects performance issues and anti-patterns.
cargo install --path .# Lint a query
groq-lint '*[_type == "post"][author->name == "John"]'
# Show context lines around issues
groq-lint -C 2 '*[_type == "post"][author->name == "John"]'Add to your Cargo.toml:
[dependencies]
groq-lint = { path = "path/to/groq-lint" }use groq_lint::Linter;
fn main() {
let linter = Linter::new();
let query = r#"*[_type == "post"][author->name == "John"]"#;
let findings = linter.lint(query);
for finding in findings {
println!("{}: {}", finding.rule_id, finding.message);
}
}See the eslint-plugin-groq-lint for instructions on using groq-lint as an ESLint plugin to lint GROQ queries inside JavaScript/TypeScript files.
The linter checks for:
- join_in_filter - Joins inside filter predicates prevent optimization
- deep_pagination - Using large offsets in slices is inefficient
- many_joins - Queries with many joins may have poor performance
- very_large_query / extremely_large_query - Oversized queries
- And more.
The linting rules are specified in rules.yaml. This is considered the source of truth for the linter, not the code. Instead, we rely on an LLM (Claude Opus 4.5 at the moment of writing) to update rules from this source. Consider this an experiment in agent-driven development.
MIT License - see LICENSE