---
name: opentui-react
description: Expert assistance for OpenTUI with React. Use for React components, hooks (useKeyboard, useRenderer, useTimeline), JSX patterns, state management, forms, and testing.
---
# OpenTUI React Integration
Expert assistance for building terminal UIs with OpenTUI and React.
## Quick Start
```bash
# Install dependencies
bun install @opentui/core @opentui/react react
```
## Basic Setup
```tsx
import { createCliRenderer } from "@opentui/core"
import { createRoot } from "@opentui/react"
function App() {
return Hello, OpenTUI React!
}
async function main() {
const renderer = await createCliRenderer()
createRoot(renderer).render()
}
main()
```
## React Hooks
### useKeyboard
Handle keyboard events in React components.
```tsx
import { useKeyboard } from "@opentui/react"
function App() {
useKeyboard((key) => {
if (key.name === "c" && key.ctrl) {
process.exit(0)
}
if (key.name === "q") {
process.exit(0)
}
})
return Press Ctrl+C or q to exit
}
```
### useRenderer
Access the renderer instance.
```tsx
import { useRenderer } from "@opentui/react"
function Component() {
const renderer = useRenderer()
const handleClick = () => {
console.log("Renderer available:", !!renderer)
}
return Click me
}
```
### useTerminalDimensions
Get terminal size changes.
```tsx
import { useTerminalDimensions } from "@opentui/react"
function Responsive() {
const { width, height } = useTerminalDimensions()
return (
Terminal: {width}x{height}
)
}
```
### useTimeline
Create animations in React.
```tsx
import { useTimeline } from "@opentui/react"
import { useRef } from "react"
function AnimatedBox() {
const boxRef = useRef(null)
const timeline = useTimeline({
duration: 1000,
easing: (t) => t * (2 - t), // easeOutQuad
})
const animate = () => {
if (boxRef.current) {
timeline.to(boxRef.current, {
backgroundColor: { r: 255, g: 0, b: 0 },
})
timeline.play()
}
}
return (
Click to animate
)
}
```
## React Components
All OpenTUI components are available as JSX elements:
```tsx
import {
text,
box,
input,
select,
scrollbox,
code,
} from "@opentui/react"
function Form() {
return (
User Information
Submit
)
}
```
## Styling in React
Styles are passed as props to components:
```tsx
function StyledComponent() {
return (
Styled Text
)
}
```
**Color format:** `{ r: number, g: number, b: number, a?: number }`
## State Management
### Local State
```tsx
import { useState } from "react"
function Counter() {
const [count, setCount] = useState(0)
useKeyboard((key) => {
if (key.name === "up") setCount(c => c + 1)
if (key.name === "down") setCount(c => c - 1)
})
return (
Count: {count}
Use arrow keys
)
}
```
### Form State
```tsx
function LoginForm() {
const [email, setEmail] = useState("")
const [password, setPassword] = useState("")
const [errors, setErrors] = useState({})
const handleSubmit = () => {
const newErrors: any = {}
if (!email.includes("@")) {
newErrors.email = "Invalid email"
}
if (password.length < 8) {
newErrors.password = "Password too short"
}
if (Object.keys(newErrors).length > 0) {
setErrors(newErrors)
return
}
console.log("Login:", { email, password })
}
return (
Login
{errors.email && (
{errors.email}
)}
{errors.password && (
{errors.password}
)}
Submit
)
}
```
### External State Management
#### Redux Integration
```tsx
import { Provider, useSelector, useDispatch } from "react-redux"
function Counter() {
const count = useSelector((state: any) => state.count)
const dispatch = useDispatch()
useKeyboard((key) => {
if (key.name === "up") dispatch({ type: "INCREMENT" })
if (key.name === "down") dispatch({ type: "DECREMENT" })
})
return Count: {count}
}
```
#### Zustand Integration
```tsx
import { create } from "zustand"
const useStore = create((set) => ({
count: 0,
increment: () => set((state: any) => ({ count: state.count + 1 })),
decrement: () => set((state: any) => ({ count: state.count - 1 })),
}))
function Counter() {
const { count, increment, decrement } = useStore()
useKeyboard((key) => {
if (key.name === "up") increment()
if (key.name === "down") decrement()
})
return Count: {count}
}
```
## Common Patterns
### List with Selection
```tsx
function SelectList({ items }: { items: string[] }) {
const [selectedIndex, setSelectedIndex] = useState(0)
useKeyboard((key) => {
if (key.name === "down" || (key.name === "tab" && !key.shift)) {
setSelectedIndex(i => Math.min(i + 1, items.length - 1))
}
if (key.name === "up" || (key.name === "tab" && key.shift)) {
setSelectedIndex(i => Math.max(i - 1, 0))
}
if (key.name === "enter") {
console.log("Selected:", items[selectedIndex])
}
})
return (
{items.map((item, index) => (
{index === selectedIndex ? "> " : " "}{item}
))}
)
}
```
### Tabs
```tsx
function Tabs({ tabs }: { tabs: Array<{ id: string, label: string, content: any }> }) {
const [activeTab, setActiveTab] = useState(tabs[0].id)
return (
{/* Tab headers */}
{tabs.map(tab => (
setActiveTab(tab.id)}
borderStyle={activeTab === tab.id ? "single" : "none"}
backgroundColor={
activeTab === tab.id
? { r: 100, g: 149, b: 237 }
: { r: 50, g: 50, b: 50 }
}
padding={1}
>
{tab.label}
))}
{/* Tab content */}
{tabs.find(t => t.id === activeTab)?.content}
)
}
```
### Modal/Dialog
```tsx
function Modal({ isOpen, onClose, children }: any) {
if (!isOpen) return null
return (
e.stopPropagation()}
>
{children}
)
}
```
## When to Use This Skill
Use `/opentui-react` for:
- Building TUIs with React
- Using hooks (useKeyboard, useRenderer, etc.)
- JSX-style component development
- Integrating with React state management
- Testing React OpenTUI components
For vanilla TypeScript/JavaScript, use `/opentui`
For SolidJS development, use `/opentui-solid`
For project scaffolding, use `/opentui-projects`
## Resources
- [Hooks Reference](references/HOOKS.md) - Complete hook documentation
- [Component Props](references/PROPS.md) - React component props
- [Patterns](references/PATTERNS.md) - Common React patterns
- [State Management](references/STATE.md) - React state integration
- [Testing](references/TESTING.md) - Testing React components
## Key Knowledge Sources
- OpenTUI React GitHub: https://github.com/sst/opentui/tree/main/packages/react
- Context7: `/sst/opentui` - React integration queries
- Research: `.search-data/research/opentui/`