termino

Code

Displays syntax-highlighted code using Tree-sitter. Supports many languages with accurate, fast highlighting.

~/components/code
live
$ termino code-demo — tree-sitter highlighting
──────────────────────────────────────────────────
import { Box, Select, createCliRenderer } from "@opentui/core"
const renderer = await createCliRenderer()
const menu = Select({
width: 30,
height: 8,
options: [
{ name: "New File", description: "Create a new file" },
{ name: "Open File", description: "Open an existing file" },
{ name: "Exit", description: "Quit application" },
],
})
menu.on("itemSelected", (index, option) => {
console.log("Selected:", option.name)
})
menu.focus()
renderer.root.add(menu)
──────────────────────────────────────────────────
tree-sitter typescript grammar · built-in language map

##Renderable API

tsrenderable
1import { CodeRenderable, createCliRenderer, SyntaxStyle, RGBA } from "@opentui/core"
2
3const renderer = await createCliRenderer()
4
5const syntaxStyle = SyntaxStyle.fromStyles({
6keyword: { fg: RGBA.fromHex("#FF7B72"), bold: true },
7string: { fg: RGBA.fromHex("#A5D6FF") },
8comment: { fg: RGBA.fromHex("#8B949E"), italic: true },
9number: { fg: RGBA.fromHex("#79C0FF") },
10function: { fg: RGBA.fromHex("#D2A8FF") },
11default: { fg: RGBA.fromHex("#E6EDF3") },
12})
13
14const code = new CodeRenderable(renderer, {
15id: "code",
16content: `function hello() {
17// This is a comment
18const message = "Hello, world!"
19return message
20}`,
21filetype: "javascript",
22syntaxStyle,
23width: 50,
24height: 10,
25})
26
27renderer.root.add(code)

##Construct API

tsconstruct
1import { Code, Box, createCliRenderer, SyntaxStyle, RGBA } from "@opentui/core"
2
3const renderer = await createCliRenderer()
4
5const syntaxStyle = SyntaxStyle.fromStyles({
6keyword: { fg: RGBA.fromHex("#FF7B72"), bold: true },
7string: { fg: RGBA.fromHex("#A5D6FF") },
8default: { fg: RGBA.fromHex("#E6EDF3") },
9})
10
11renderer.root.add(
12Box(
13 { border: true, width: 50, height: 10 },
14 Code({
15 content: 'const x = "hello"',
16 filetype: "javascript",
17 syntaxStyle,
18 }),
19),
20)

##Custom syntax styles

Use SyntaxStyle.fromStyles() to define colors and attributes per token, with dot-prefixed scope names for granularity:

ts
1const syntaxStyle = SyntaxStyle.fromStyles({
2keyword: { fg: RGBA.fromHex("#FF7B72"), bold: true },
3"keyword.import": { fg: RGBA.fromHex("#FF7B72"), bold: true },
4
5string: { fg: RGBA.fromHex("#A5D6FF") },
6comment: { fg: RGBA.fromHex("#8B949E"), italic: true },
7number: { fg: RGBA.fromHex("#79C0FF") },
8boolean: { fg: RGBA.fromHex("#79C0FF") },
9
10function: { fg: RGBA.fromHex("#D2A8FF") },
11"function.call": { fg: RGBA.fromHex("#D2A8FF") },
12type: { fg: RGBA.fromHex("#FFA657") },
13constructor: { fg: RGBA.fromHex("#FFA657") },
14
15variable: { fg: RGBA.fromHex("#E6EDF3") },
16property: { fg: RGBA.fromHex("#79C0FF") },
17operator: { fg: RGBA.fromHex("#FF7B72") },
18punctuation: { fg: RGBA.fromHex("#F0F6FC") },
19
20default: { fg: RGBA.fromHex("#E6EDF3") },
21})

Each style definition supports fg, bg, bold, italic, underline, and dim.

##Supported languages

  • TypeScript / JavaScript — built-in grammar
  • Markdown — built-in grammar (with markup.* style scopes)
  • Zig — built-in grammar
  • Any language with a Tree-sitter grammar — pass a custom treeSitterClient

##Streaming mode

Enable for incremental content like LLM output:

ts
1const code = new CodeRenderable(renderer, {
2id: "streaming-code",
3content: "",
4filetype: "typescript",
5syntaxStyle,
6streaming: true,
7})
8
9code.content += "const x = 1\n"
10code.content += "const y = 2\n"

Streaming mode keeps the previous rendered buffer visible while a new highlight completes; each highlight still processes the complete current content.

##Line numbers

Pair with LineNumberRenderable inside a ScrollBox:

ts
1const lineNumbers = new LineNumberRenderable(renderer, {
2id: "code-with-lines",
3target: code,
4minWidth: 3,
5paddingRight: 1,
6fg: "#6b7280",
7bg: "#161b22",
8width: "100%",
9})
10
11const scrollbox = new ScrollBoxRenderable(renderer, {
12id: "scrollbox",
13width: 60,
14height: 20,
15})
16scrollbox.add(lineNumbers)
17renderer.root.add(scrollbox)

##Properties

properties
proptypedefaultdescription
contentstring""Source code to display
filetypestring-Language for syntax highlighting
syntaxStyleSyntaxStylerequiredSyntax highlighting theme
streamingbooleanfalsePreserve intermediate rendering during updates
concealbooleantrueHide concealed syntax elements (e.g. markdown formatting)
drawUnstyledTextbooleantrueShow unstyled text while highlighting
treeSitterClientTreeSitterClient-Custom Tree-sitter client instance
selectablebooleantrueWhether text selection is enabled
selectionBg / selectionFgstring | RGBA-Selection colors
wrapMode"none" | "char" | "word""word"Text wrapping