| name | opentui |
| description | OpenTUI — Zig-native terminal UI framework. Covers installation, renderer, components (Text/Box/Input/Select/Code/ScrollBox), Constructs declarative API, Flexbox layout, React/Solid bindings. |
OpenTUI — Native Terminal UI Framework
Zig-native TUI core with TypeScript bindings and Yoga Flexbox layout. Powers OpenCode in production.
Use Cases
Use when building terminal TUI applications.
Installation
bun init -y && bun add @opentui/core
Renderer
const r = await createCliRenderer({
screenMode: "alternate-screen"|"main-screen"|"split-footer",
targetFps: 30, exitOnCtrlC: true, useMouse: true, autoFocus: true,
backgroundColor: "transparent", consoleMode: "console-overlay"|"disabled",
})
r.root.add(Text({ content:"Hello", fg:"#0F0" }))
r.start()/stop()/pause()/suspend()/resume()/destroy()
r.on("resize",(w,h)=>{}); r.on("focus"|"blur"|"destroy",()=>{})
r.on("theme_mode",m=>{}); r.on("selection",s=>s.getSelectedText())
r.setTerminalTitle("t"); r.setBackgroundColor("#0D1117")
r.writeToScrollback(ctx=>({root,width:ctx.width,height:1,startOnNewLine:true}))
const sf = r.createScrollbackSurface({}); sf.root.add(code); sf.settle(); sf.destroy()
Components
Text({content:"hello",fg:"#F00",bg:"#222",attributes:BOLD|UNDERLINE,selectable:true,position:"absolute",left:10,top:5})
Box({width:30,height:10,borderStyle:"rounded"|"single"|"double"|"heavy",borderColor:"#FFF",
title:"Settings",titleAlignment:"left"|"center"|"right",padding:1,gap:1,
onMouseDown:()=>{},onMouseOver:()=>{},onMouseOut:()=>{}})
Input({width:25,placeholder:,:,:,
:,:})
input.(); input.=;
({:,:,:[{:,:,:}],
:,:,:})
style = .({:{:.(),:},:{:.()}})
({:,:,:style,:,:,:})
({:,:,:,:,:|,
:,:{:,:{:}}})
Others: TextArea TabSelect ASCIIFont({text:"T",font:"tiny"}) LineNumberRenderable({target:code})
Constructs (Declarative API)
Box({width:40,borderStyle:"rounded",padding:1}, Text({content:"Hi"}), Input({placeholder:"..."}))
function LabeledInput({id,label,pl}) {
return delegate({focus:`${id}-in`},
Box({flexDirection:"row"}, Text({content:label}),
Input({id:`${id}-in`,placeholder:pl,width:20})))
}
function Card({title},...children) {
return Box({border:true,padding:1,flexDirection:"column"},
Text({content:title,fg:"#FF0"}), Box({flexDirection:"column"},...children))
}
Flexbox Layout (Yoga)
Box({flexDirection:"row"|"column"|"row-reverse"|"column-reverse",
justifyContent:"center"|"space-between"|"space-around"|"space-evenly",
alignItems:"center"|"stretch"|"baseline",
flexGrow:1,flexShrink:0,flexBasis:100,
width:"100%"|30,height:"50%"|10,
position:"absolute",left:10,top:5,right:10,bottom:5,
padding:2,paddingX:4,paddingTop:1,margin:1,gap:1})
React Bindings
import {createRoot} from "@opentui/react"
createRoot(await createCliRenderer()).render(<App />)
Solid Bindings
import {render} from "@opentui/solid"
render(()=><App />)