Components Guide
A walkthrough of OpenTUIās built-in components with practical examples. All examples use the imperative (construct) API; the same components work identically in SolidJS (<box>) and React (<box>).
Box
The container component. Everything that needs border, background, or child layout uses Box.
import { Box, Text } from "@opentui/core"
// Basic bordered box
Box(
{ border: true, borderStyle: "rounded", padding: 1 },
Text({ content: "Inside a box" }),
)
// Available border styles: "single", "double", "rounded", "bold", "ascii"
// Custom border characters are also supported via customBorderChars
Key props:
border: boolean- enable borderborderStyle: string- border character styleborderColor: string- border color (hex)backgroundColor: string- fill colortitle: string- text shown in the borderfocusedBorderColor: string- border color when focused- All flexbox layout props (flexDirection, padding, gap, etc.)
Text
Read-only styled text display.
import { Text } from "@opentui/core"
import { StyledText } from "@opentui/core"
// Simple text
Text({ content: "Hello world", fg: "#00FF00" })
// Styled text with mixed formatting
const styled = StyledText.fromAnsi("\x1b[1mBold\x1b[0m and \x1b[3mitalic\x1b[0m")
Text({ content: styled })
// Text wrapping
Text({ content: "Long text that wraps...", wrap: "word" })
Key props:
content: string | StyledText- the text to displayfg: string- foreground colorbg: string- background colorbold: boolean,italic: boolean,underline: boolean,strikethrough: booleanwrap: "word" | "char" | "none"- wrapping modetruncation: "end" | "start" | "middle"- how to truncate when space is limited
Input
Single-line text input with cursor.
import { Input } from "@opentui/core"
const input = Input({
placeholder: "Enter your name...",
width: 30,
onChange: (value) => {
console.log("Current value:", value)
},
onSubmit: (value) => {
console.log("Submitted:", value)
},
})
input.focus() // give it keyboard focus
Key props:
placeholder: string- shown when emptyvalue: string- current text valuepassword: boolean- mask inputonChange: (value: string) => void- fires on every keystrokeonSubmit: (value: string) => void- fires on Enter
Select
Dropdown/list selection.
import { Select } from "@opentui/core"
Select({
options: [
{ label: "Option A", value: "a" },
{ label: "Option B", value: "b" },
{ label: "Option C", value: "c" },
],
onSelect: (option) => {
console.log("Selected:", option.value)
},
})
TabSelect
Horizontal tab selector.
import { TabSelect } from "@opentui/core"
TabSelect({
options: [
{ label: "Files", value: "files" },
{ label: "Search", value: "search" },
{ label: "Settings", value: "settings" },
],
onSelect: (option) => {
console.log("Tab:", option.value)
},
})
ScrollBox
Scrollable container for content that exceeds its bounds.
import { ScrollBox, Text } from "@opentui/core"
ScrollBox(
{ width: 40, height: 10 },
// Content taller than 10 rows will scroll
...Array.from({ length: 50 }, (_, i) =>
Text({ content: `Line ${i + 1}` })
),
)
Supports mouse scroll and programmatic scrolling via scrollTo(), scrollBy().
Code
Syntax-highlighted code display using tree-sitter.
import { Code, SyntaxStyle, RGBA } from "@opentui/core"
const syntaxStyle = SyntaxStyle.fromStyles({
default: { fg: RGBA.fromHex("#D4D4D4") },
keyword: { fg: RGBA.fromHex("#C586C0") },
string: { fg: RGBA.fromHex("#CE9178") },
comment: { fg: RGBA.fromHex("#6A9955") },
function: { fg: RGBA.fromHex("#DCDCAA") },
})
Code({
content: `function greet(name: string) {\n return "Hello, " + name\n}`,
filetype: "typescript",
syntaxStyle,
})
Gotcha: Tree-sitter is a peer dependency (
web-tree-sitter). You need to install it separately and ensure the language WASM files are available.
Markdown
Renders markdown content with styling.
import { MarkdownRenderable } from "@opentui/core"
const md = new MarkdownRenderable(renderer, {
id: "docs",
content: "# Hello\n\nThis is **bold** and *italic*.\n\n- List item 1\n- List item 2",
})
Uses the marked library internally. Supports headers, bold, italic, lists, code blocks, and links.
Diff
Unified or split diff viewer.
import { DiffRenderable } from "@opentui/core"
const diff = new DiffRenderable(renderer, {
id: "diff",
oldContent: "line 1\nline 2\nline 3",
newContent: "line 1\nline 2 modified\nline 3\nline 4",
})
FrameBuffer
Raw pixel-level drawing for custom graphics, animations, or effects.
import { FrameBuffer, RGBA } from "@opentui/core"
const fb = FrameBuffer({ width: 40, height: 20 })
// Draw directly to the buffer in renderAfter callback
This is what enables the 3D demos and shader examples in the repo.
ASCIIFont
Large ASCII art text using various font styles.
import { ASCIIFont } from "@opentui/core"
ASCIIFont({
text: "HELLO",
font: "tiny", // available: "tiny", "block", "slick", "shade", "grid", "huge", "pallet"
fg: "#FF6600",
})
Composing Components
Build reusable components as functions:
function StatusBar(props: { left: string; right: string }) {
return Box(
{
flexDirection: "row",
justifyContent: "space-between",
width: "100%",
backgroundColor: "#333333",
padding: 0,
paddingLeft: 1,
paddingRight: 1,
},
Text({ content: props.left, fg: "#FFFFFF" }),
Text({ content: props.right, fg: "#888888" }),
)
}
function AppLayout(props: { title: string }, ...children: any[]) {
return Box(
{ flexDirection: "column", width: "100%", height: "100%" },
StatusBar({ left: props.title, right: "v1.0" }),
Box({ flexGrow: 1, padding: 1, flexDirection: "column" }, ...children),
)
}
// Use it
renderer.root.add(
AppLayout(
{ title: "My App" },
Text({ content: "Welcome!" }),
Input({ placeholder: "Search..." }),
),
)
Colors
OpenTUI supports true color (24-bit). Use hex strings anywhere a color is accepted:
Text({ content: "Red text", fg: "#FF0000" })
Box({ backgroundColor: "#1E1E2E" })
// With alpha (RGBA)
Box({ backgroundColor: "#FF000080" }) // 50% transparent red
The RGBA class provides programmatic color manipulation:
import { RGBA } from "@opentui/core"
const color = RGBA.fromHex("#FF6600")
const transparent = color.withAlpha(128)
Next Steps
- Architecture - How these components are rendered
- Testing - Write tests for your component compositions
- Native Core - What happens under the hood