Syntax highlighting grammars for GROQ (Graph-Relational Object Queries) targeting the major editor and platform ecosystems.
| Package | Format | Used by |
|---|---|---|
tree-sitter-groq |
Tree-sitter grammar (grammar.js) |
Neovim, Zed, Helix, Emacs 29+ |
@sanity/textmate-groq |
TextMate grammar (.tmLanguage.json) |
VS Code, Shiki, Sublime Text, GitHub/Linguist |
@sanity/lezer-groq |
Lezer grammar (.grammar) |
CodeMirror 6 |
@sanity/prism-groq |
Prism.js language definition | react-refractor, rehype-prism, MDX |
@sanity/highlightjs-groq |
highlight.js language definition | react-lowlight, lowlight, markdown renderers |
@sanity/ace-groq |
Ace editor mode | Ace-based editors |
A shared test suite catches divergences between engines early. When a language feature is added, we update fixtures once and verify all six grammars handle it. A visual playground makes it easy to spot differences.
pnpm install
# Run all tests (74 tests across 8 test suites)
pnpm test
# Typecheck
pnpm typecheck
# Format
pnpm format
# Run tree-sitter native tests
cd packages/tree-sitter-groq && npx tree-sitter test
# Start the visual comparison playground
pnpm devA local Vite + React app that renders six panels in a grid, each highlighting the same GROQ query through a different engine: TextMate (Shiki), Lezer (CodeMirror), tree-sitter (WASM), Prism (Refractor), highlight.js (Lowlight), and Ace. All panels share a single color palette for accurate comparison. Queries are auto-formatted with prettier-plugin-groq to fit the panel width.
Test fixtures live in packages/groq-highlight-test/fixtures/. Each .groq file contains a single valid GROQ expression. Add a file, run pnpm test to generate snapshots for all engines, and review the output.
The test harness maps each engine's native token types to a shared canonical token taxonomy, then compares them pairwise with tolerance for known engine limitations:
- TextMate can't distinguish
identifierfromidentifier.functionwithout parse context - Prism and highlight.js (regex-based) have similar limitations to TextMate
- Tree-sitter and Lezer (real parsers) can distinguish context-dependent tokens like keywords used as field names
The cross-engine tests compare TextMate against each other engine, flagging mismatches above a 5% tolerance threshold.
The TextMate package includes injection grammars for highlighting GROQ inside JavaScript/TypeScript (tagged template literals, defineQuery() calls) and markdown fenced code blocks. See the @sanity/textmate-groq README for VS Code extension wiring.
MIT - see LICENSE.