5.5 KiB
5.5 KiB
Solid Configuration
Project Setup
Quick Start
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)
Manual Setup
mkdir my-tui && cd my-tui
bun init
bun install @opentui/solid @opentui/core solid-js
TypeScript Configuration
tsconfig.json
{
"compilerOptions": {
"lib": ["ESNext"],
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"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 Solid
Bun Configuration
bunfig.toml
Required for the Solid compiler:
preload = ["@opentui/solid/preload"]
This loads the Solid JSX transform before your code runs.
Package Configuration
package.json
{
"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"
}
}
Project Structure
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
Entry Point (src/index.tsx)
import { render } from "@opentui/solid"
import { App } from "./App"
render(() => <App />)
App Component (src/App.tsx)
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>
)
}
Renderer Configuration
render() Options
import { render } from "@opentui/solid"
import { ConsolePosition } from "@opentui/core"
render(() => <App />, {
// Rendering
targetFPS: 60,
// Behavior
exitOnCtrlC: true,
// Debug console
consoleOptions: {
position: ConsolePosition.BOTTOM,
sizePercent: 30,
startInDebugMode: false,
},
// Cleanup
onDestroy: () => {
// Cleanup code
},
})
Using Existing Renderer
import { render } from "@opentui/solid"
import { createCliRenderer } from "@opentui/core"
const renderer = await createCliRenderer({
exitOnCtrlC: false,
})
render(() => <App />, renderer)
Building for Distribution
Build Script (build.ts)
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
Creating Executables
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 x64
Environment Variables
Create .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
Testing Configuration
Test Setup
// 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)
}
Test Example
// 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")
})
Common Configuration Issues
Missing bunfig.toml
Symptom: JSX not transformed, syntax errors
Fix: Create bunfig.toml with preload:
preload = ["@opentui/solid/preload"]
Wrong JSX Settings
Symptom: JSX compiles to React calls
Fix: Ensure tsconfig has:
{
"compilerOptions": {
"jsx": "preserve",
"jsxImportSource": "@opentui/solid"
}
}
Build Missing Plugin
Symptom: Built output has untransformed JSX
Fix: Add Solid plugin to build:
import solidPlugin from "@opentui/solid/bun-plugin"
await Bun.build({
// ...
plugins: [solidPlugin],
})