Skip to main content

Overview

The CodeRenderable component displays syntax-highlighted code using Tree-sitter for accurate parsing. It supports multiple languages, custom syntax themes, text selection, and streaming mode for incremental rendering.

Basic Usage

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

const syntaxStyle = SyntaxStyle.fromStyles({
  keyword: { fg: parseColor("#FF7B72"), bold: true },
  string: { fg: parseColor("#A5D6FF") },
  comment: { fg: parseColor("#8B949E"), italic: true },
  default: { fg: parseColor("#E6EDF3") },
})

const code = new CodeRenderable(renderer, {
  content: 'const message = "Hello World"\nconsole.log(message)',
  filetype: "typescript",
  syntaxStyle,
})

Props

content
string
default:"''"
Code content to display.
filetype
string
Language/filetype for syntax highlighting (e.g., "typescript", "python", "rust").
syntaxStyle
SyntaxStyle
required
Syntax styling configuration defining colors and attributes for language tokens.
treeSitterClient
TreeSitterClient
Tree-sitter client for syntax parsing. Uses default client if not provided.
conceal
boolean
default:"true"
Enable concealment of hidden syntax elements (used for markdown code blocks with fence markers).
drawUnstyledText
boolean
default:"true"
Display unstyled text before syntax highlighting completes.
streaming
boolean
default:"false"
Enable streaming mode for incremental content updates.
onHighlight
(highlights: SimpleHighlight[], context: HighlightContext) => SimpleHighlight[] | undefined
Callback to modify or replace syntax highlights before rendering.
wrapMode
'none' | 'char' | 'word'
default:"'none'"
Text wrapping behavior.
selectable
boolean
default:"false"
Enable text selection with mouse or keyboard.
selectionBg
string | RGBA
Background color for selected text.
selectionFg
string | RGBA
Foreground color for selected text.

Supported Languages

CodeRenderable supports syntax highlighting for many languages through Tree-sitter:
  • JavaScript / TypeScript
  • Python
  • Rust
  • Go
  • C / C++
  • Java
  • Ruby
  • PHP
  • Markdown
  • JSON
  • YAML
  • And many more…

Examples

TypeScript with GitHub Dark Theme

const syntaxStyle = SyntaxStyle.fromStyles({
  keyword: { fg: parseColor("#FF7B72"), bold: true },
  "keyword.import": { fg: parseColor("#FF7B72"), bold: true },
  string: { fg: parseColor("#A5D6FF") },
  comment: { fg: parseColor("#8B949E"), italic: true },
  number: { fg: parseColor("#79C0FF") },
  function: { fg: parseColor("#D2A8FF") },
  "function.call": { fg: parseColor("#D2A8FF") },
  type: { fg: parseColor("#FFA657") },
  operator: { fg: parseColor("#FF7B72") },
  variable: { fg: parseColor("#E6EDF3") },
  property: { fg: parseColor("#79C0FF") },
  default: { fg: parseColor("#E6EDF3") },
})

const code = new CodeRenderable(renderer, {
  content: `interface User {
  name: string;
  age: number;
}

function greet(user: User): string {
  return \`Hello, \${user.name}!\`;
}`,
  filetype: "typescript",
  syntaxStyle,
  width: "100%",
})

Python Code

const pythonCode = `def calculate_fibonacci(n):
    """Calculate the nth Fibonacci number."""
    if n <= 1:
        return n
    return calculate_fibonacci(n - 1) + calculate_fibonacci(n - 2)

result = calculate_fibonacci(10)
print(f"Fibonacci(10) = {result}")`

const code = new CodeRenderable(renderer, {
  content: pythonCode,
  filetype: "python",
  syntaxStyle,
})

With Line Numbers

import { LineNumberRenderable } from "@opentui/core"

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

const codeWithLines = new LineNumberRenderable(renderer, {
  target: code,
  fg: "#6b7280",
  bg: "#161b22",
  width: "100%",
})

Selectable Code

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

Streaming Code Updates

const code = new CodeRenderable(renderer, {
  content: "",
  filetype: "typescript",
  syntaxStyle,
  streaming: true,
  drawUnstyledText: false, // Don't show unstyled text during streaming
})

let position = 0
const fullCode = 'function hello() {\n  console.log("Hello");\n}'

const interval = setInterval(() => {
  code.content = fullCode.slice(0, position)
  position += 5
  
  if (position >= fullCode.length) {
    code.streaming = false
    clearInterval(interval)
  }
}, 50)

Custom Highlight Callback

const code = new CodeRenderable(renderer, {
  content: codeContent,
  filetype: "typescript",
  syntaxStyle,
  onHighlight: (highlights, context) => {
    // Filter or modify highlights
    return highlights.map(h => {
      if (h.name === "error") {
        // Custom styling for errors
        return { ...h, name: "error.custom" }
      }
      return h
    })
  },
})

Word Wrapping

const code = new CodeRenderable(renderer, {
  content: longCodeLine,
  filetype: "typescript",
  syntaxStyle,
  wrapMode: "word",
  width: 60,
})

Switching Languages Dynamically

const code = new CodeRenderable(renderer, {
  content: tsCode,
  filetype: "typescript",
  syntaxStyle,
})

// Switch to JavaScript
code.filetype = "javascript"
code.content = jsCode

Common Syntax Style Groups

Different languages use different token names, but common ones include:
  • keyword, keyword.import, keyword.operator, keyword.coroutine
  • string, string.escape
  • comment, comment.line, comment.block
  • number, boolean
  • function, function.call, function.method, function.method.call
  • type, type.builtin
  • variable, variable.builtin, variable.parameter, variable.member
  • property
  • operator
  • punctuation, punctuation.bracket, punctuation.delimiter
  • constructor
  • constant, constant.builtin

Methods

getLineHighlights()

Get syntax highlights for a specific line.
const highlights = code.getLineHighlights(lineIndex)

Properties

content

Get or set the code content.
code.content = "new code"
const current = code.content

filetype

Get or set the language/filetype.
code.filetype = "python"

syntaxStyle

Get or set the syntax style.
code.syntaxStyle = newSyntaxStyle

conceal

Get or set conceal mode.
code.conceal = false

streaming

Get or set streaming mode.
code.streaming = true

drawUnstyledText

Get or set whether to draw unstyled text.
code.drawUnstyledText = false

isHighlighting

Check if syntax highlighting is in progress.
if (code.isHighlighting) {
  console.log("Highlighting in progress...")
}

Performance

  • Uses Tree-sitter for accurate, fast syntax parsing
  • Asynchronous highlighting to avoid blocking the UI
  • Caches highlights for unchanged content
  • Efficient incremental updates in streaming mode
  • Supports large code files with good performance
  • Text - Plain text display
  • Markdown - Markdown rendering (uses Code internally)
  • Diff - Side-by-side or unified diff views (uses Code internally)
  • LineNumberRenderable - Add line numbers to code

Build docs developers (and LLMs) love