Tree-sitter
OpenTUI integrates Tree-sitter for fast, accurate syntax highlighting. You can register parsers globally or per client.
Add parsers globally
Use addDefaultParsers() before creating clients:
import { addDefaultParsers, getTreeSitterClient } from "@opentui/core"
addDefaultParsers([
{
filetype: "python",
wasm: "https://github.com/tree-sitter/tree-sitter-python/releases/download/v0.23.6/tree-sitter-python.wasm",
queries: {
highlights: ["https://raw.githubusercontent.com/tree-sitter/tree-sitter-python/master/queries/highlights.scm"],
},
},
])
const client = getTreeSitterClient()
await client.initialize()
Add parsers per client
import { TreeSitterClient } from "@opentui/core"
const client = new TreeSitterClient({ dataPath: "./cache" })
await client.initialize()
client.addFiletypeParser({
filetype: "rust",
wasm: "https://github.com/tree-sitter/tree-sitter-rust/releases/download/v0.23.2/tree-sitter-rust.wasm",
queries: {
highlights: ["https://raw.githubusercontent.com/tree-sitter/tree-sitter-rust/master/queries/highlights.scm"],
},
})
Parser configuration
interface FiletypeParserOptions {
filetype: string
aliases?: string[]
wasm: string
queries: {
highlights: string[]
injections?: string[]
}
injectionMapping?: {
nodeTypes?: Record<string, string>
infoStringMap?: Record<string, string>
}
}
aliases maps additional filetype ids to the same parser assets.
Language injections
Use queries.injections to highlight embedded languages.
injectionMapping.nodeTypesmaps injected node types to filetype ids.injectionMapping.infoStringMapmaps code fence language labels to filetype ids.
client.addFiletypeParser({
filetype: "markdown",
wasm: "https://github.com/tree-sitter-grammars/tree-sitter-markdown/releases/download/v0.5.1/tree-sitter-markdown.wasm",
queries: {
highlights: ["./assets/markdown/highlights.scm"],
injections: [
"https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/markdown/injections.scm",
],
},
injectionMapping: {
nodeTypes: {
inline: "markdown_inline",
pipe_table_cell: "markdown_inline",
},
infoStringMap: {
js: "javascript",
jsx: "javascriptreact",
ts: "typescript",
tsx: "typescriptreact",
},
},
})
If infoStringMap has no match, the fence language label is used as the filetype id.
Use local files
import pythonWasm from "./parsers/tree-sitter-python.wasm" with { type: "file" }
import pythonHighlights from "./queries/python/highlights.scm" with { type: "file" }
addDefaultParsers([
{
filetype: "python",
wasm: pythonWasm,
queries: {
highlights: [pythonHighlights],
},
},
])
Automated asset management
Use the updateAssets utility to download parsers and generate imports.
CLI usage
{
"scripts": {
"prebuild": "bun node_modules/@opentui/core/lib/tree-sitter/assets/update.ts --config ./parsers-config.json --assets ./src/parsers --output ./src/parsers.ts"
}
}
Programmatic usage
import { updateAssets } from "@opentui/core"
await updateAssets({
configPath: "./parsers-config.json",
assetsDir: "./src/parsers",
outputPath: "./src/parsers.ts",
})
Using with CodeRenderable
import { CodeRenderable, RGBA, SyntaxStyle, getTreeSitterClient } from "@opentui/core"
const client = getTreeSitterClient()
await client.initialize()
const syntaxStyle = SyntaxStyle.fromStyles({
default: { fg: RGBA.fromHex("#E6EDF3") },
})
const code = new CodeRenderable(renderer, {
id: "code",
content: "const x = 1",
filetype: "typescript",
syntaxStyle,
treeSitterClient: client,
})
Caching
Parser and query files are cached in the client dataPath. Set a custom cache directory:
const client = new TreeSitterClient({
dataPath: "./my-cache",
})
File type resolution
import { pathToFiletype, extToFiletype, infoStringToFiletype } from "@opentui/core"
const ft1 = pathToFiletype("src/main.rs")
const ft2 = extToFiletype("ts")
const ft3 = infoStringToFiletype("TSX title=Button.tsx")
infoStringToFiletype() is used for fenced markdown code blocks.
You can extend or override mappings at runtime:
import { extensionToFiletype, basenameToFiletype } from "@opentui/core"
extensionToFiletype.set("templ", "html")
basenameToFiletype.set("mytoolrc", "yaml")