Problem
OpenCode's syntax highlighting is driven by tree-sitter parsers hardcoded in parsers-config.ts. There is no way to add a custom language parser via opencode.json config. This means anyone working on a new or niche language gets no syntax highlighting, even if they already have a fully working tree-sitter grammar and WASM binary.
Our Situation
We're building Valkyria, a Lisp dialect with .valk files. We already have:
- A custom LSP server — configured via
opencode.json under lsp, works great with diagnostics, hover, completion, go-to-definition, semantic tokens, etc.
- A tree-sitter grammar — full
grammar.js with highlights, locals, and indents queries
- A compiled WASM binary —
tree-sitter-valk.wasm (13KB), built and ready
The LSP integration is seamless thanks to the existing config. But there's no equivalent config path for syntax highlighting — we can't point OpenCode at our WASM + queries.
Proposed Solution
Add a syntax (or parsers) section to opencode.json that allows users to register custom tree-sitter parsers:
{
"$schema": "https://opencode.ai/config.json",
"syntax": {
"valk": {
"wasm": "./editors/tree-sitter-valk.wasm",
"extensions": [".valk"],
"highlights": "./editors/queries/valk/highlights.scm",
"locals": "./editors/queries/valk/locals.scm"
}
}
}
This mirrors the existing lsp config pattern — same shape, same idea: point at a binary + file extensions.
The wasm and highlights fields could accept either local paths (relative to project root) or URLs (for hosted grammars), consistent with how parsers-config.ts already works internally.
Why This Matters
Alternatives Considered
- PR to add valk to
parsers-config.ts: Works for us but doesn't help anyone else with a custom language. Every language needs a separate PR + release cycle.
- Aliasing extensions to existing parsers: Partial solution (e.g.,
.valk → clojure), but loses language-specific highlights. Would still be useful as a simpler option alongside full custom parser support.
Problem
OpenCode's syntax highlighting is driven by tree-sitter parsers hardcoded in
parsers-config.ts. There is no way to add a custom language parser viaopencode.jsonconfig. This means anyone working on a new or niche language gets no syntax highlighting, even if they already have a fully working tree-sitter grammar and WASM binary.Our Situation
We're building Valkyria, a Lisp dialect with
.valkfiles. We already have:opencode.jsonunderlsp, works great with diagnostics, hover, completion, go-to-definition, semantic tokens, etc.grammar.jswith highlights, locals, and indents queriestree-sitter-valk.wasm(13KB), built and readyThe LSP integration is seamless thanks to the existing config. But there's no equivalent config path for syntax highlighting — we can't point OpenCode at our WASM + queries.
Proposed Solution
Add a
syntax(orparsers) section toopencode.jsonthat allows users to register custom tree-sitter parsers:{ "$schema": "https://opencode.ai/config.json", "syntax": { "valk": { "wasm": "./editors/tree-sitter-valk.wasm", "extensions": [".valk"], "highlights": "./editors/queries/valk/highlights.scm", "locals": "./editors/queries/valk/locals.scm" } } }This mirrors the existing
lspconfig pattern — same shape, same idea: point at a binary + file extensions.The
wasmandhighlightsfields could accept either local paths (relative to project root) or URLs (for hosted grammars), consistent with howparsers-config.tsalready works internally.Why This Matters
parsers-config.tsand a new OpenCode releaseparsers-config.tslsp.valk.command+lsp.valk.extensionsis all it takes.valkto theclojureparser as a workaround without needing upstream changesAlternatives Considered
parsers-config.ts: Works for us but doesn't help anyone else with a custom language. Every language needs a separate PR + release cycle..valk→clojure), but loses language-specific highlights. Would still be useful as a simpler option alongside full custom parser support.