Code

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

Basic usage

Renderable API

import { CodeRenderable, createCliRenderer, SyntaxStyle, RGBA } from "@opentui/core"

const renderer = await createCliRenderer()

const syntaxStyle = SyntaxStyle.fromStyles({
  keyword: { fg: RGBA.fromHex("#FF7B72"), bold: true },
  string: { fg: RGBA.fromHex("#A5D6FF") },
  comment: { fg: RGBA.fromHex("#8B949E"), italic: true },
  number: { fg: RGBA.fromHex("#79C0FF") },
  function: { fg: RGBA.fromHex("#D2A8FF") },
  default: { fg: RGBA.fromHex("#E6EDF3") },
})

const code = new CodeRenderable(renderer, {
  id: "code",
  content: `function hello() {
  // This is a comment
  const message = "Hello, world!"
  return message
}`,
  filetype: "javascript",
  syntaxStyle,
  width: 50,
  height: 10,
})

renderer.root.add(code)

Construct API

Note: Not available yet.

import { Code, Box, createCliRenderer, SyntaxStyle, RGBA } from "@opentui/core"

const renderer = await createCliRenderer()

const syntaxStyle = SyntaxStyle.fromStyles({
  keyword: { fg: RGBA.fromHex("#FF7B72"), bold: true },
  string: { fg: RGBA.fromHex("#A5D6FF") },
  default: { fg: RGBA.fromHex("#E6EDF3") },
})

renderer.root.add(
  Box(
    { border: true, width: 50, height: 10 },
    Code({
      content: 'const x = "hello"',
      filetype: "javascript",
      syntaxStyle,
    }),
  ),
)

Creating syntax styles

Use SyntaxStyle.fromStyles() to define colors and attributes for syntax tokens:

import { SyntaxStyle, RGBA, parseColor } from "@opentui/core"

const syntaxStyle = SyntaxStyle.fromStyles({
  // Basic tokens
  keyword: { fg: RGBA.fromHex("#FF7B72"), bold: true },
  "keyword.import": { fg: RGBA.fromHex("#FF7B72"), bold: true },
  "keyword.operator": { fg: RGBA.fromHex("#FF7B72") },

  string: { fg: RGBA.fromHex("#A5D6FF") },
  comment: { fg: RGBA.fromHex("#8B949E"), italic: true },
  number: { fg: RGBA.fromHex("#79C0FF") },
  boolean: { fg: RGBA.fromHex("#79C0FF") },
  constant: { fg: RGBA.fromHex("#79C0FF") },

  // Functions and types
  function: { fg: RGBA.fromHex("#D2A8FF") },
  "function.call": { fg: RGBA.fromHex("#D2A8FF") },
  "function.method.call": { fg: RGBA.fromHex("#D2A8FF") },
  type: { fg: RGBA.fromHex("#FFA657") },
  constructor: { fg: RGBA.fromHex("#FFA657") },

  // Variables and properties
  variable: { fg: RGBA.fromHex("#E6EDF3") },
  "variable.member": { fg: RGBA.fromHex("#79C0FF") },
  property: { fg: RGBA.fromHex("#79C0FF") },

  // Operators and punctuation
  operator: { fg: RGBA.fromHex("#FF7B72") },
  punctuation: { fg: RGBA.fromHex("#F0F6FC") },
  "punctuation.bracket": { fg: RGBA.fromHex("#F0F6FC") },
  "punctuation.delimiter": { fg: RGBA.fromHex("#C9D1D9") },

  // Default fallback
  default: { fg: RGBA.fromHex("#E6EDF3") },
})

Style properties

Each style definition can include:

PropertyTypeDescription
fgRGBAForeground (text) color
bgRGBABackground color
boldbooleanBold text
italicbooleanItalic text
underlinebooleanUnderlined text
dimbooleanDimmed text

Supported languages

Code uses Tree-sitter for parsing. Tree-sitter supports these languages:

  • TypeScript / JavaScript
  • Markdown
  • Zig
  • And any language with a Tree-sitter grammar

Streaming mode

Enable streaming mode when content arrives incrementally, like LLM output:

const code = new CodeRenderable(renderer, {
  id: "streaming-code",
  content: "",
  filetype: "typescript",
  syntaxStyle,
  streaming: true, // Enable streaming mode
})

// Later, append content
code.content += "const x = 1\n"
code.content += "const y = 2\n"

Streaming mode optimizes highlighting for incremental updates.

Text selection

Enable text selection for copy operations:

const code = new CodeRenderable(renderer, {
  id: "code",
  content: sourceCode,
  filetype: "typescript",
  syntaxStyle,
  selectable: true,
  selectionBg: "#264F78",
  selectionFg: "#FFFFFF",
})

Concealment

The conceal option controls whether certain syntax elements (like markdown formatting characters) are hidden:

const code = new CodeRenderable(renderer, {
  id: "markdown",
  content: "# Heading\n**bold** text",
  filetype: "markdown",
  syntaxStyle,
  conceal: true, // Hide formatting characters
})

With line numbers

Use LineNumberRenderable to add line numbers:

import { CodeRenderable, LineNumberRenderable, ScrollBoxRenderable } from "@opentui/core"

const code = new CodeRenderable(renderer, {
  id: "code",
  content: sourceCode,
  filetype: "typescript",
  syntaxStyle,
  width: "100%",
})

const lineNumbers = new LineNumberRenderable(renderer, {
  id: "code-with-lines",
  target: code,
  minWidth: 3,
  paddingRight: 1,
  fg: "#6b7280",
  bg: "#161b22",
  width: "100%",
})

// Wrap in ScrollBox for scrolling
const scrollbox = new ScrollBoxRenderable(renderer, {
  id: "scrollbox",
  width: 60,
  height: 20,
})
scrollbox.add(lineNumbers)

Properties

PropertyTypeDefaultDescription
contentstring""Source code to display
filetypestring-Language for syntax highlighting
syntaxStyleSyntaxStylerequiredSyntax highlighting theme
streamingbooleanfalseOptimize for incremental content updates
concealbooleantrueHide concealed syntax elements
drawUnstyledTextbooleantrueShow text before highlighting completes
treeSitterClientTreeSitterClient-Custom Tree-sitter client instance

Inherited from TextBufferRenderable

PropertyTypeDefaultDescription
fgstring | RGBA-Default foreground color
bgstring | RGBA-Background color
selectablebooleanfalseEnable text selection
selectionBgstring | RGBA-Selection background color
selectionFgstring | RGBA-Selection foreground color
wrapModestring"word"Text wrapping: "none", "char", "word"
tabIndicatorstring | number-Tab display character or width

Additional properties

PropertyTypeDescription
lineCountnumberNumber of lines in content
scrollYnumberCurrent vertical scroll position (get/set)
scrollXnumberCurrent horizontal scroll position (get/set)
scrollWidthnumberTotal scrollable width (read-only)
scrollHeightnumberTotal scrollable height (read-only)
isHighlightingbooleanWhether highlighting is in progress
plainTextstringRaw text content

Markdown styles

For markdown highlighting, use markup-prefixed style names:

const markdownStyle = SyntaxStyle.fromStyles({
  "markup.heading": { fg: RGBA.fromHex("#58A6FF"), bold: true },
  "markup.heading.1": { fg: RGBA.fromHex("#00FF88"), bold: true, underline: true },
  "markup.heading.2": { fg: RGBA.fromHex("#00D7FF"), bold: true },
  "markup.bold": { fg: RGBA.fromHex("#F0F6FC"), bold: true },
  "markup.strong": { fg: RGBA.fromHex("#F0F6FC"), bold: true },
  "markup.italic": { fg: RGBA.fromHex("#F0F6FC"), italic: true },
  "markup.list": { fg: RGBA.fromHex("#FF7B72") },
  "markup.quote": { fg: RGBA.fromHex("#8B949E"), italic: true },
  "markup.raw": { fg: RGBA.fromHex("#A5D6FF") },
  "markup.raw.block": { fg: RGBA.fromHex("#A5D6FF") },
  "markup.link": { fg: RGBA.fromHex("#58A6FF"), underline: true },
  "markup.link.url": { fg: RGBA.fromHex("#58A6FF"), underline: true },
  default: { fg: RGBA.fromHex("#E6EDF3") },
})