A true Svelte 5 renderer for terminal user interfaces, inspired by Ink for React.
SvelTUI allows you to build beautiful terminal user interfaces using Svelte 5 components. Unlike wrapper libraries, SvelTUI implements a custom Svelte compiler plugin that renders Svelte components directly to the terminal, bringing the full power of Svelte to terminal applications.
- Direct Svelte 5 Integration - Uses Svelte 5's mount/unmount APIs for true integration
- Write Regular Svelte - Use standard Svelte 5 components with familiar syntax and runes
- Reactive Terminal UIs - Svelte 5's reactivity system makes terminal UIs dynamic
- Efficient Updates - Batched operations and reconciliation for minimal terminal redraws
- Complete Feature Support - Full Svelte 5 feature set including state, effects, and lifecycle
- TypeScript Support - Fully typed for better development experience
# Install dependencies
bun install
# Run the example application
bun run example
- Write Once, Render Anywhere - Same components work in browser and terminal
- Full Svelte 5 Support - Complete Svelte 5 feature set in the terminal
- Custom Components - Create your own terminal UI components with Svelte
- Reactive Updates - Efficient reactivity in the terminal
- Layout Engine - Flexbox-like layout in the terminal with Yoga integration
- Keyboard & Mouse Navigation - Built-in event handling support
- Theming System - Comprehensive theming capabilities
- Focus Management - Intelligent focus handling for interactive components
- Bidirectional DOM Binding - Clean DOM-to-terminal element binding
<!-- App.svelte -->
<script>
// Svelte 5 runes for reactivity
let count = $state(0);
let items = $state(["Item 1", "Item 2", "Item 3"]);
let selected = $state(0);
// Reactivity with $derived
$derived selectedItem = items[selected];
$derived hasItems = items.length > 0;
function increment() {
count++;
}
function handleSelect(event) {
selected = event.detail.index;
}
// Effects for side effects
$effect(() => {
console.log(`Selection changed: ${selectedItem}`);
});
</script>
<box border label="SvelTUI Demo">
<text>Count: {count}</text>
<button on:press={increment}>Increment</button>
<list
items={items}
selected={selected}
on:select={handleSelect}
/>
<text>Selected: {selectedItem}</text>
</box>
// main.ts
import { render } from 'sveltui';
import App from './App.svelte';
render(App, {
// Optional configuration
title: 'My Terminal App',
fullscreen: true,
debug: false,
theme: 'dark'
});
SvelTUI implements a custom Svelte 5 renderer for the terminal, with direct integration via Svelte 5's mount/unmount APIs.
The architecture consists of:
- Custom Compiler Plugin - Transforms Svelte components for terminal rendering
- Terminal Renderer - Renders components to the terminal using Svelte 5's mount/unmount APIs
- Virtual Terminal DOM - Maintains a virtual representation of the terminal UI with bidirectional binding
- Reconciler - Efficiently batch-processes updates to the terminal
- Layout Engine - Calculates component positions and dimensions with Yoga support
- Runtime DOM Connector - Bridges Svelte 5's runtime to our terminal DOM
For more details, see the Architecture Documentation.
SvelTUI components are built using Svelte 5's component model and runes system:
<script>
// Import theme
import { getTheme } from '../theme/currentTheme.svelte';
// Props with defaults
let {
value = '',
width = 20,
height = 1,
border = true,
} = $props();
// Local state
let focused = $state(false);
// Get theme
const theme = getTheme();
// Event handlers
function handleFocus() {
focused = true;
}
function handleBlur() {
focused = false;
}
</script>
<input
value={value}
width={width}
height={height}
border={border}
style={{
bg: focused ? theme.colors.focusBg : theme.colors.bg,
fg: theme.colors.fg,
border: {
fg: focused ? theme.colors.focusBorder : theme.colors.border
}
}}
on:focus={handleFocus}
on:blur={handleBlur}
/>
For more details, see the Component Implementation Strategy.
SvelTUI includes a set of built-in components for common terminal UI elements:
Component | Description |
---|---|
<box> |
Container component with borders and title support |
<text> |
Text display with styling options |
<list> |
Interactive, selectable list |
<input> |
Text input field |
<checkbox> |
Checkbox for boolean selection |
<button> |
Pressable button |
<progress> |
Progress bar |
SvelTUI supports a flexible theming system:
// Apply a theme
import { setTheme } from 'sveltui';
setTheme('dark');
// Use theme in components
import { getTheme } from 'sveltui';
const theme = getTheme();
<text style={{ fg: theme.colors.primary }}>Themed Text</text>
SvelTUI is under active development. Contributions are welcome!
# Run development server
bun run dev
# Build the library
bun run build
# Run tests
bun run test
- Complete Yoga layout engine integration
- Enhanced animation and transition system
- More built-in UI components
- State persistence
- Improved testing infrastructure
- Interactive component inspector
- Performance optimizations
- Accessibility enhancements
MIT © RLabs Inc.