sdk/apps/cli/.agents/skills/opentui/references/solid/configuration.md
bunx create-tui@latest -t solid my-app
cd my-app && bun install
The CLI creates the my-app directory for you - it must not already exist.
Options: --no-git (skip git init), --no-install (skip bun install)
mkdir my-tui && cd my-tui
bun init
bun install @opentui/solid @opentui/core solid-js
{
"compilerOptions": {
"lib": ["ESNext"],
"target": "ESNext",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"jsx": "preserve",
"jsxImportSource": "@opentui/solid",
"strict": true,
"skipLibCheck": true,
"noEmit": true,
"types": ["bun-types"]
},
"include": ["src/**/*"]
}
Critical settings:
jsx: "preserve" - Let Solid's compiler handle JSXjsxImportSource: "@opentui/solid" - Import JSX runtime from OpenTUI Solidmodule / moduleResolution: "NodeNext" - Recommended for OpenTUI compatibilityRequired for the Solid compiler:
preload = ["@opentui/solid/preload"]
This loads the Solid JSX transform before your code runs.
{
"name": "my-tui-app",
"type": "module",
"scripts": {
"start": "bun run src/index.tsx",
"dev": "bun --watch run src/index.tsx",
"test": "bun test",
"build": "bun run build.ts"
},
"dependencies": {
"@opentui/core": "latest",
"@opentui/solid": "latest",
"solid-js": "latest"
},
"devDependencies": {
"@types/bun": "latest",
"typescript": "latest"
}
}
Recommended structure:
my-tui-app/
├── src/
│ ├── components/
│ │ ├── Header.tsx
│ │ ├── Sidebar.tsx
│ │ └── MainContent.tsx
│ ├── stores/
│ │ └── appStore.ts
│ ├── App.tsx
│ └── index.tsx
├── bunfig.toml # Required!
├── package.json
└── tsconfig.json
import { render } from "@opentui/solid"
import { App } from "./App"
render(() => <App />)
import { Header } from "./components/Header"
import { Sidebar } from "./components/Sidebar"
import { MainContent } from "./components/MainContent"
export function App() {
return (
<box flexDirection="column" width="100%" height="100%">
<Header />
<box flexDirection="row" flexGrow={1}>
<Sidebar />
<MainContent />
</box>
</box>
)
}
import { render } from "@opentui/solid"
import { ConsolePosition } from "@opentui/core"
render(() => <App />, {
// Rendering
targetFPS: 60,
// Behavior
exitOnCtrlC: true,
autoFocus: true, // Auto-focus elements on click (default: true)
useMouse: true, // Enable mouse support (default: true)
// Debug console
consoleOptions: {
position: ConsolePosition.BOTTOM,
sizePercent: 30,
startInDebugMode: false,
},
// Cleanup
onDestroy: () => {
// Cleanup code
},
})
import { render } from "@opentui/solid"
import { createCliRenderer } from "@opentui/core"
const renderer = await createCliRenderer({
exitOnCtrlC: false,
})
render(() => <App />, renderer)
import solidPlugin from "@opentui/solid/bun-plugin"
await Bun.build({
entrypoints: ["./src/index.tsx"],
outdir: "./dist",
target: "bun",
minify: true,
plugins: [solidPlugin],
})
console.log("Build complete!")
Run: bun run build.ts
import solidPlugin from "@opentui/solid/bun-plugin"
await Bun.build({
entrypoints: ["./src/index.tsx"],
target: "bun",
plugins: [solidPlugin],
compile: {
target: "bun-darwin-arm64", // or bun-linux-x64, etc.
outfile: "my-app",
},
})
Available targets:
bun-darwin-arm64 - macOS Apple Siliconbun-darwin-x64 - macOS Intelbun-linux-x64 - Linux x64bun-linux-arm64 - Linux ARM64bun-windows-x64 - Windows x64Create .env for development:
# Debug settings
OTUI_SHOW_STATS=false
SHOW_CONSOLE=false
# App settings
API_URL=https://api.example.com
Bun auto-loads .env files:
const apiUrl = process.env.API_URL
// src/test-utils.tsx
import { testRender } from "@opentui/solid"
export async function renderForTest(
Component: () => JSX.Element,
options = { width: 80, height: 24 }
) {
return await testRender(Component, options)
}
// src/components/Counter.test.tsx
import { test, expect } from "bun:test"
import { renderForTest } from "../test-utils"
import { Counter } from "./Counter"
test("Counter renders initial value", async () => {
const { snapshot } = await renderForTest(() => <Counter initialValue={5} />)
expect(snapshot()).toContain("Count: 5")
})
Symptom: JSX not transformed, syntax errors
Fix: Create bunfig.toml with preload:
preload = ["@opentui/solid/preload"]
Symptom: JSX compiles to React calls
Fix: Ensure tsconfig has:
{
"compilerOptions": {
"jsx": "preserve",
"jsxImportSource": "@opentui/solid"
}
}
Symptom: Built output has untransformed JSX
Fix: Add Solid plugin to build:
import solidPlugin from "@opentui/solid/bun-plugin"
await Bun.build({
// ...
plugins: [solidPlugin],
})