@sanity/lezer-groq
Lezer grammar for GROQ that gives CodeMirror 6 editors syntax highlighting, code folding, and auto-indentation for Sanity's query language.
Repository Health
Technical Analysis
@sanity/lezer-groq is a Lezer grammar for GROQ (Graph-Relational Object Queries), Sanity’s query language, built specifically to power CodeMirror 6 integrations. It ships an incremental LR parser generated from a declarative .grammar file, along with a pre-wired LRLanguage definition that adds syntax highlighting, code folding, and auto-indentation out of the box.
The package is one of six sibling grammars living in the sanity-io/groq-syntax monorepo, each targeting a different editor or highlighting engine (tree-sitter, TextMate, Prism, highlight.js, Ace). All six are validated against the same shared fixture suite, so the GROQ language features this grammar recognizes (filters, projections, pipes, dereferences, namespaced function calls like math::sum(), and full operator precedence) are guaranteed to stay consistent with the other engines as the language evolves.
What You Get
- An LR parser (
parser) generated from a hand-written.grammarfile covering the full GROQ expression language - A ready-to-use
groq()function returning a CodeMirror 6LanguageSupportinstance with highlighting, folding, and indentation pre-configured - The raw
groqLanguageLRLanguageexport for advanced/custom CodeMirror setups - Highlight tag mappings (via
@lezer/highlight) tuned to GROQ’s specific syntax: dereferences, namespaced function calls, pipes, ranges, and keyword-specialized operators
Common Use Cases
- Embedding a GROQ query editor with syntax highlighting inside a Sanity Studio plugin or custom admin tool built on CodeMirror 6
- Building a standalone GROQ playground or query-testing tool that needs folding and auto-indent, not just color
- Adding GROQ language support to any CodeMirror-based code editor product used internally at a company running Sanity
- Cross-checking GROQ syntax coverage against the repo’s other grammars (tree-sitter, TextMate) when extending the language
Under The Hood
Architecture
The package is a thin, clearly-layered wrapper around a declarative grammar: src/groq.grammar defines GROQ’s precedence table and expression rules, lezer-generator compiles it into parser.js/parser.terms.js, and index.ts composes the generated parser with CodeMirror’s LRLanguage, attaching indentNodeProp and foldNodeProp configurations for projections, array literals, and object literals. highlight.ts sits alongside as a separate concern, mapping named grammar nodes to @lezer/highlight tags. The coupling between the grammar’s node names and the highlight/indent configs is string-based, so changing a rule name in the grammar without updating the corresponding entries in highlight.ts or index.ts would silently break styling or folding for that construct.
Tech Stack
Built in TypeScript against the Lezer ecosystem (@lezer/common, @lezer/lr, @lezer/highlight, with @lezer/generator as a dev-time grammar compiler) and @codemirror/language for the LRLanguage/LanguageSupport integration. The build pipeline uses Rollup with rollup-plugin-esbuild and @rollup/plugin-node-resolve to produce an ESM-only bundle, and manually copies a hand-written index.d.ts into dist/ rather than generating declarations via tsc. The package lives inside a pnpm workspace using catalog: dependency versions shared across all six sibling grammar packages.
Code Quality
The package itself ships no tests directly; instead, correctness is validated at the monorepo level by the groq-highlight-test workspace package, which runs Vitest snapshot tests against a shared fixture suite (basics, functions, operators, pipes, edge-cases, real-world — 74 tests across 8 suites per the README) through a tokenize-lezer.ts harness. This cross-engine fixture strategy is a deliberate quality safeguard: the same GROQ inputs are tokenized by all six grammars and compared, catching divergence early. A GitHub Actions CI workflow builds the package, typechecks, and runs the full test suite on every push and pull request against main.
What Makes It Unique Rather than being a standalone GROQ highlighter, this package is one node in a shared-fixture, multi-engine grammar system: the same language semantics are independently expressed as a Lezer grammar here, a tree-sitter grammar, a TextMate grammar, and three other engine-specific definitions, all exercised against one fixture corpus and a visual comparison playground. That cross-validation discipline — rather than any single parsing technique — is what differentiates it from a typical one-off editor grammar package.
Used by 2 apps in this directory
Sanity
CMS
Open-source headless CMS with a fully customizable React Studio, real-time collaborative editing, structured content modeling, and GROQ query language
Sanity
CMS
Open-source headless CMS with a fully customizable React Studio, real-time collaborative editing, structured content modeling, and GROQ query language