Quick Start · Packages · Components · Styling · Architecture · Development
[!IMPORTANT] What this installs:
- Native
.nodebindings for the Taffy layout engine (Rust → Node via napi-rs, not WASM)- Prebuilt for Linux (x64/arm64), macOS (Intel/Apple Silicon), Windows
- No network calls, no telemetry, no files written outside your project
Uninstall:
npm remove @wolf-tui/react @wolf-tui/plugin(substitute your adapter)
Building terminal UIs means choosing between raw ANSI escape codes or framework-specific tools locked to one ecosystem. If you know React, you can use Ink — but there's nothing for Vue, Angular, Solid, or Svelte. And Ink's layout engine (Yoga) only supports Flexbox.
wolf-tui started as a fork of Ink, then expanded: five framework adapters sharing one layout engine (Taffy — Flexbox + CSS Grid), one component library, and one styling pipeline (Tailwind, SCSS, CSS Modules). Write a component once, render it in any adapter.
Pick your framework:
npm install @wolf-tui/react && npm install -D @wolf-tui/plugin
import { render, Box, Text } from '@wolf-tui/react'
function App() {
return (
<Box style={{ flexDirection: 'column', padding: 1 }}>
<Text style={{ color: 'green' }}>Hello from wolf-tui!</Text>
</Box>
)
}
render(<App />)
npm install @wolf-tui/vue && npm install -D @wolf-tui/plugin
<script setup>
import { Box, Text } from '@wolf-tui/vue'
</script>
<template>
<Box :style="{ flexDirection: 'column', padding: 1 }">
<Text :style="{ color: 'green' }">Hello from wolf-tui!</Text>
</Box>
</template>
import { render } from '@wolf-tui/vue'
import App from './App.vue'
render(App)
npm install @wolf-tui/angular && npm install -D @wolf-tui/plugin
import { Component } from '@angular/core'
import { BoxComponent, TextComponent } from '@wolf-tui/angular'
@Component({
standalone: true,
imports: [BoxComponent, TextComponent],
template: `
<w-box [style]="{ flexDirection: 'column', padding: 1 }">
<w-text [style]="{ color: 'green' }">Hello from wolf-tui!</w-text>
</w-box>
`,
})
export class AppComponent {}
import { renderWolfie } from '@wolf-tui/angular'
import { AppComponent } from './app.component'
renderWolfie(AppComponent)
npm install @wolf-tui/solid && npm install -D @wolf-tui/plugin
import { render, Box, Text } from '@wolf-tui/solid'
function App() {
return (
<Box style={{ flexDirection: 'column' }}>
<Text style={{ color: 'green' }}>Hello from wolf-tui!</Text>
</Box>
)
}
render(App, { stdout: process.stdout, stdin: process.stdin })
npm install @wolf-tui/svelte && npm install -D @wolf-tui/plugin
<!-- App.svelte -->
<script>
import { Box, Text } from '@wolf-tui/svelte'
</script>
<Box style={{ flexDirection: 'column', padding: 1 }}>
<Text style={{ color: 'green', fontWeight: 'bold' }}>Hello from wolf-tui!</Text>
</Box>
import { render } from '@wolf-tui/svelte'
import App from './App.svelte'
render(App)
Svelte requires --conditions=browser at runtime and a build step. See the Svelte adapter README for full setup.
Each adapter has a detailed README with full API docs, Vite/esbuild/webpack configuration, and component reference.
| Package | Description | Docs |
|---|---|---|
| @wolf-tui/core | Layout engine, DOM, renderer | Core |
| @wolf-tui/react | React 19+ adapter | README |
| @wolf-tui/vue | Vue 3.5+ adapter | README |
| @wolf-tui/angular | Angular 17+ adapter | README |
| @wolf-tui/solid | SolidJS 1.9+ adapter | README |
| @wolf-tui/svelte | Svelte 5+ adapter | README |
| @wolf-tui/plugin | Build plugin (Vite/esbuild/webpack/Rollup) | README |
| @wolf-tui/typescript-plugin | TypeScript plugin for CSS module types | README |
| @wolf-tui/css-parser | CSS/SCSS/LESS/Stylus parser | Internal |
All adapters share the same component set:
| Category | Components |
|---|---|
| Layout | Box, Text, Spacer, Newline, Static, Transform |
| Display | Alert, Badge, Spinner, ProgressBar, StatusMessage, ErrorOverview |
| Input | TextInput, PasswordInput, EmailInput, ConfirmInput, Select, MultiSelect |
| Lists | OrderedList, UnorderedList |
Plus composables/hooks: useInput, useFocus, useFocusManager, stream access, screen reader detection.
See individual adapter READMEs for API details and prop reference.
// Inline styles
<Box style={{ flexDirection: 'column', padding: 1, gap: 1 }}>
<Text style={{ color: 'green', fontWeight: 'bold' }}>Styled text</Text>
</Box>
// Tailwind CSS (v3.4 / v4.1)
<Box className="flex-col p-4 gap-2">
<Text className="text-green-500 font-bold">Styled with Tailwind</Text>
</Box>
| Method | Setup |
|---|---|
| Inline styles | Works out of the box |
| Tailwind CSS | PostCSS + @wolf-tui/plugin |
| CSS Modules | *.module.css imports |
| SCSS/LESS/Stylus | Preprocessor + @wolf-tui/plugin |
All CSS approaches resolve to terminal styles at build time — no runtime CSS engine.
Relative units:
| Unit | Terminal conversion |
|---|---|
px |
value / 4 cells |
rem |
value × 4 cells (1rem = 16px = 4 cells) |
% |
Dynamic (parent-based) |
vw / vh |
Terminal columns / rows |
ch |
1 cell per ch |
Color support:
#fff, #ffffffrgb(255 0 0), rgba(255, 0, 0, 0.5)text-[cyan], bg-[#ff0]┌──────────────────┐
│ @wolf-tui/core │ Taffy layout, virtual DOM, ANSI renderer
│ (napi-rs) │ native .node bindings
└────────┬─────────┘
│
┌────────┴─────────┐
│ @wolf-tui/shared │ render scheduler, shared render functions,
│ │ input parsing, theme system
└────────┬─────────┘
│
┌─────┼─────┬─────────┬──────────┐
│ │ │ │ │
React Vue Angular SolidJS Svelte
Each adapter maps its framework's component model to the shared virtual DOM. Taffy computes layout, the core renderer produces ANSI output. A visual bug either affects all adapters (render function issue) or one adapter (integration issue) — two-step debug path.
wolf-tui uses Taffy for layout computation. Taffy supports both Flexbox and CSS Grid — Yoga (used by Ink and React Native) only supports Flexbox.
Integration details:
calc() valuesIncremental rendering: All adapters render only changed terminal lines per frame, not the full screen. Disable for headless testing:
render(<App />, { incrementalRendering: false })
React Compiler: @wolf-tui/react ships pre-compiled with the React Compiler — all library components skip re-renders when props haven't changed. To apply to your own components:
npm install -D babel-plugin-react-compiler
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { wolfie } from '@wolf-tui/plugin/vite'
export default defineConfig({
plugins: [
react({
babel: {
plugins: [['babel-plugin-react-compiler', {}]],
},
}),
wolfie('react'),
],
})
Requires React 19+.
git clone <repo-url>
cd wolf-tui
pnpm install
pnpm dev
| Command | Description |
|---|---|
pnpm dev |
Watch mode for all packages |
pnpm build |
Build all packages |
pnpm test |
Run all unit tests |
pnpm test:e2e |
E2E screenshot tests (20 tests, ~38s) |
pnpm lint |
ESLint check |
pnpm typecheck |
TypeScript type checking |
See CONTRIBUTING.md for development guidelines.
This project started as a fork of Ink by Vadim Demedes. The React package (@wolf-tui/react) builds upon Ink's foundation and includes components from the ink-* ecosystem.
MIT