A declarative TUI framework for Dart — inspired by Ratatui (Rust) and Flutter.
Build beautiful terminal user interfaces using the same mental model as Flutter: widgets, state, layout, and themes. Powered by a Rust-grade diff engine that only redraws what changed.
import 'package:dartatui/dartatui.dart';
void main() {
runTerminalApp(const CounterApp(), theme: ThemeData.dark);
}
class CounterApp extends StatefulWidget {
@override
State createState() => _CounterState();
}
class _CounterState extends State<CounterApp> {
int _count = 0;
@override
Widget build(BuildContext context) {
return Column(children: [
Border(child: TextWidget('Count: $_count')),
Padding(
padding: const EdgeInsets.only(top: 1),
child: Row(children: [
Button(label: '- Decrement', onPressed: () => setState(() => _count--)),
const SizedBox(sWidth: 1),
Button(label: '+ Increment', onPressed: () => setState(() => _count++)),
]),
),
]);
}
}Press Tab to focus, Enter or Space to press buttons, q to quit.
- Declarative — describe your UI as widgets, the framework handles rendering
- Composable — small widgets combine into complex layouts
- Stateful —
setState()triggers efficient re-renders - Efficient — diff engine only writes changed cells to the terminal
- Themable — dark/light themes with custom colors and styles
- Navigable — Tab/Shift+Tab focus traversal, keyboard event system
- Zero deps — pure Dart, no external runtime required
Add to your pubspec.yaml:
dependencies:
dartatui:
path: /path/to/dartatuidart pub getComing to pub.dev soon.
import 'package:dartatui/dartatui.dart';
void main() {
runTerminalApp(const GreeterApp());
}
class GreeterApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Border(
style: theme.borderStyle,
child: TextWidget('Hello, Terminal!', style: theme.headingStyle),
);
}
}| Guide | What you'll learn |
|---|---|
| Getting Started | Your first TUI in 5 minutes |
| Architecture | Widget tree, render pipeline, lifecycle |
| Widgets | All available widgets with examples |
| Layout | Row, Column, Expanded, BoxConstraints |
| Styling | Style, Color, Modifier, Themes |
| Focus & Events | Keyboard navigation and input |
| Rendering | Buffer, diff engine, how it works |
| Custom Widgets | Build your own |
| Examples | Real-world patterns |
Widget Tree Element Tree RenderObject Tree
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Column │ │ Element│ │ Render │
├─────────┤ ├─────────┤ ├─────────┤
│ Row │ → │ Element│ → │ Render │
├─────────┤ ├─────────┤ ├─────────┤
│ Button │ │ Element│ │ Render │
└─────────┘ └─────────┘ └─────────┘
│
┌───────┴───────┐
│ Layout / │
│ Paint │
│ ↓ │
│ Buffer │
│ ┌───────┐ │
│ │ Diff │ │
│ └───┬───┘ │
│ ↓ │
│ ┌───────┐ │
│ │ ANSI │ │
│ │ stdout│ │
│ └───────┘ │
└───────────────┘
| Widget | Description |
|---|---|
TextWidget |
Renders styled text (single or multi-line) |
Row / Column |
Flexbox horizontal / vertical layout |
Expanded |
Fills remaining space in a flex parent |
Padding |
Adds margin around a child |
Border |
Box-drawing border with focus-aware styling |
Container |
Background color + padding wrapper |
SizedBox |
Forces a fixed width / height |
Align |
Positions child at 9 anchor points |
Focus |
Makes any widget keyboard-focusable |
Button |
Clickable button with focus/hover state |
TextField |
Editable text input with cursor |
ScrollView |
Vertical / horizontal content scrolling |
| Metric | Value |
|---|---|
| Dart SDK | ^3.6.0 |
| Tests | 101 |
| Analysis | 0 issues |
| Dependencies | zero (pure Dart) |
| License | MIT |
- Core rendering engine (Buffer, Cell, diff)
- Widget system (Widget, StatefulWidget, Element, RenderObject)
- Layout (Row, Column, Expanded, BoxConstraints)
- Focus system (Tab traversal, FocusNode, FocusManager)
- Theme system (ThemeData, Theme widget, dark/light)
- Input widgets (TextField, Button)
- Scroll support (ScrollView, ScrollableColumn)
- Frame scheduling (AppScheduler ~30fps)
- Resize handling (SIGWINCH)
- Mouse support
- pub.dev release
This project is in early development. Contributions, issues, and ideas are welcome.
MIT — see LICENSE.