wolf-tui Svelte Themes

Wolf Tui

Framework-agnostic Terminal UI library — React, Vue, Angular, SolidJS, Svelte. JSX/template syntax, Flexbox/Grid layouts (Taffy), CSS-like styling.

wolf-tui

Write CLI apps with your web framework — React, Vue, Angular, Solid, or Svelte

Quick Start · Packages · Components · Styling · Architecture · Development


[!IMPORTANT] What this installs:

  • Native .node bindings 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)

The Problem

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.


Quick Start

Pick your framework:

React

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 />)
Vue
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)
Angular
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)
SolidJS
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 })
Svelte
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.


Packages

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

Components

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.


Styling

// 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.

Units and colors

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:

  • 140+ named CSS colors mapped to ANSI
  • Hex: #fff, #ffffff
  • RGB/RGBA: rgb(255 0 0), rgba(255, 0, 0, 0.5)
  • OKLCH, HSL, LAB, LCH via colorjs.io
  • Tailwind arbitrary values: text-[cyan], bg-[#ff0]

Architecture

┌──────────────────┐
│  @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.

Layout engine: Taffy

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:

  • Native Node.js bindings via napi-rs (not WASM — no startup penalty)
  • Supports calc() values
  • Prebuilt for Linux (x64/arm64), macOS (Intel/Apple Silicon), Windows
Performance

Incremental 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+.


Development

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.


Acknowledgments

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.

License

MIT

Top categories

Loading Svelte Themes