All skills
msmps avatar

/opentui

@0d61d6d
by Matt Simpsonmsmps/opentui-skill225 stars
9

OpenTUI skill for building terminal user interfaces with the Core, React, or Solid APIs. Use for any TUI task including components, layout, keyboard and keymap handling, animations, and testing.

Use this Skill: https://skilld.dev/gh/msmps/opentui-skill/opentui

This session only. Nothing lands on disk.

referencescoreconfiguration.md

≈1.6k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Core Configuration

Renderer Configuration

createCliRenderer Options

import { createCliRenderer, ConsolePosition } from "@opentui/core"

const renderer = await createCliRenderer({
  // Rendering
  targetFps: 30,                    // Continuous rendering target (default: 30)
  maxFps: 60,                       // Immediate render cap (default: 60)
  
  // Behavior
  exitOnCtrlC: true,                // Exit on Ctrl+C (default: true)
  useMouse: true,                   // Enable mouse input (default: true)
  autoFocus: true,                  // Focus nearest focusable node on click
  screenMode: "alternate-screen",  // "alternate-screen" | "main-screen" | "split-footer"
  externalOutputMode: "passthrough", // Or "capture-stdout" in split-footer mode
  
  // Console overlay
  consoleOptions: {
    position: ConsolePosition.BOTTOM,  // BOTTOM | TOP | LEFT | RIGHT
    sizePercent: 30,                   // Percentage of screen
    colorInfo: "#00FFFF",
    colorWarn: "#FFFF00",
    colorError: "#FF0000",
    colorDebug: "#888888",
    startInDebugMode: false,
  },
  
  // Lifecycle
  onDestroy: () => {
    // Cleanup callback
  },
})

Environment Variables

OpenTUI respects several environment variables for configuration and debugging.

Debug & Development

Variable Type Default Description
OTUI_DEBUG boolean false Enable debug mode, capture raw input
OTUI_DEBUG_FFI boolean false Debug logging for FFI bindings
OTUI_TRACE_FFI boolean false Tracing for FFI bindings
OTUI_SHOW_STATS boolean false Show debug overlay at startup
OTUI_DUMP_CAPTURES boolean false Dump captured output on exit
OTUI_STDIN_LOG string "" Write raw stdin bytes to a file (may contain secrets)
OTUI_GHOSTTY_LOG_LEVEL string "" Ghostty logs: error, warn, info, or debug

Console

Variable Type Default Description
OTUI_USE_CONSOLE boolean true Enable global console.* capture and activation
SHOW_CONSOLE boolean false Show console at startup

Rendering

Variable Type Default Description
OTUI_NO_NATIVE_RENDER boolean false Disable ANSI output (for debugging)
OTUI_USE_ALTERNATE_SCREEN boolean true Use alternate screen buffer
OTUI_OVERRIDE_STDOUT boolean true Override stdout stream

Terminal Capabilities

Variable Type Default Description
OPENTUI_GRAPHICS string automatic false/0 disables Kitty and Sixel detection; true/1 keeps auto-detection
OPENTUI_IMAGE_PROTOCOL string auto auto, kitty, sixel, or blocks
OPENTUI_FORCE_UNICODE boolean false Force Mode 2026 Unicode support
OPENTUI_FORCE_WCWIDTH boolean false Use wcwidth for character width
OPENTUI_FORCE_NOZWJ boolean false Disable ZWJ emoji joining
OPENTUI_FORCE_EXPLICIT_WIDTH string - Force explicit width ("true"/"false")

Tree-sitter (Syntax Highlighting)

Variable Type Default Description
OTUI_TS_STYLE_WARN boolean false Warn on missing syntax styles
OTUI_TREE_SITTER_WORKER_PATH string "" Custom tree-sitter worker path

Runtime Assets

Variable Type Default Description
OPENTUI_LIBC string glibc Select glibc or musl on Linux before the first Core import
OTUI_ASSET_ROOT string "" Absolute root for relocated native, worker, grammar, and WASM assets

XDG Paths

Variable Type Default Description
XDG_CONFIG_HOME string "" User config directory
XDG_DATA_HOME string "" User data directory

Usage Examples

Development Mode

# Show debug overlay and console
OTUI_SHOW_STATS=true SHOW_CONSOLE=true bun run src/index.ts

# Debug FFI issues
OTUI_DEBUG_FFI=true OTUI_TRACE_FFI=true bun run src/index.ts

# Disable native rendering for testing
OTUI_NO_NATIVE_RENDER=true bun run src/index.ts

Terminal Compatibility

# Force wcwidth for problematic terminals
OPENTUI_FORCE_WCWIDTH=true bun run src/index.ts

# Disable Kitty and Sixel detection for a remote session
OPENTUI_GRAPHICS=false bun run src/index.ts

Project Setup

package.json

{
  "name": "my-tui-app",
  "type": "module",
  "scripts": {
    "start": "bun run src/index.ts",
    "dev": "bun --watch run src/index.ts",
    "test": "bun test"
  },
  "dependencies": {
    "@opentui/core": "latest"
  },
  "devDependencies": {
    "@types/bun": "latest",
    "typescript": "latest"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "lib": ["ESNext"],
    "target": "ESNext",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "strict": true,
    "skipLibCheck": true,
    "noEmit": true,
    "types": ["bun-types"]
  },
  "include": ["src/**/*"]
}

Note: OpenTUI uses NodeNext module resolution. All internal imports use .js extensions. If you use bundler resolution, imports still work but NodeNext is recommended for compatibility.

Building Native Code

Native code changes require rebuilding:

# From repo root (if developing OpenTUI itself)
bun run build

# Zig is required for native compilation
# Install: https://ziglang.org/learn/getting-started/

Note: TypeScript changes do NOT require building. Bun runs TypeScript directly.

Standalone Executables

Bun embeds OpenTUI runtime assets directly:

bun build --compile ./src/index.ts --outfile app

For a Linux musl target, define process.env.OPENTUI_LIBC as "musl" at build time so Bun retains only that native-package branch.

Node SEA builds require Node.js 26.4.0+, ESM, and --experimental-ffi. At build time import getNodeAssets() from @opentui/core/node-assets, embed every returned { key, source }, extract those exact keys at startup, and set the absolute OTUI_ASSET_ROOT before bundled Core code executes. Do not call getNodeAssets() from the finished executable. The root export resolveBundledFilePath() resolves runtime assets for custom packaging.

Source: SKILL.md on GitHub

No alerts17d5 checks · Risk SAFE
  • Gen Agent Trust Hub17d

    This skill contains documentation and usage patterns for the OpenTUI framework, designed for building terminal user interfaces across Core, React, and SolidJS. The analysis confirmed that the skill provides legitimate development guidance; no malicious code, persistence mechanisms, or obfuscation were detected. Findings are limited to standard platform capabilities and recommended scaffolding tools.

  • Socket17d

    No alerts

  • Snyk17d

    Risk: LOW · No issues

  • Runlayer7mo

    1/26 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 0d61d6d. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last month.

Steadyupdated last month
Other metadata
metadata
{
  "references": "core, react, solid, components, layout, keyboard, keymap, animation, testing"
}
  • React
  • Testing
  • terminal-ui
  • tui
  • solid
  • components
  • keyboard-input
  • animations
  • layout

README badge

README badge for msmps/opentui-skill

Builds terminal user interfaces with OpenTUI using an imperative core API or React/Solid reconcilers. Covers layout, keyboard handling, animations, components, and testing for full-featured TUI applications.

Generated from the current SKILL.md.

Does this skill cover all three OpenTUI frameworks?
Yes. The skill consolidates the core imperative API, React reconciler, and Solid reconciler. Use the decision tree in the skill to pick the right framework for your task.
How do I start a new OpenTUI project?
Use `create-tui` with options before arguments: `bunx create-tui -t react my-app` (not `bunx create-tui my-app -t react`). Then read the REFERENCE.md for your chosen framework.
What runtime does OpenTUI require?
OpenTUI runs on Bun and uses Zig for native builds. See `./references/core/gotchas.md` for runtime requirements and build guidance.
Can I use `process.exit()` to shut down my TUI?
No. Always use `renderer.destroy()` instead. Calling `process.exit()` directly is a common pitfall covered in `core/gotchas.md`.
How do I apply text styling in React or Solid?
Use nested modifier elements, not props. See `components/text-display.md` for the correct pattern.

Generated from the current SKILL.md. These answers refresh after source changes.