Skip to content

leonus96/dartatui

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Dartatui

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.


✨ Features

  • Declarative — describe your UI as widgets, the framework handles rendering
  • Composable — small widgets combine into complex layouts
  • StatefulsetState() 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

📦 Install

Add to your pubspec.yaml:

dependencies:
  dartatui:
    path: /path/to/dartatui
dart pub get

Coming to pub.dev soon.

🚀 Quick Start

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),
    );
  }
}

→ Full getting started guide

📚 Learn More

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

🧱 Architecture

  Widget Tree          Element Tree        RenderObject Tree
  ┌─────────┐          ┌─────────┐          ┌─────────┐
  │  Column │          │  Element│          │  Render │
  ├─────────┤          ├─────────┤          ├─────────┤
  │  Row    │    →     │  Element│    →     │  Render │
  ├─────────┤          ├─────────┤          ├─────────┤
  │  Button │          │  Element│          │  Render │
  └─────────┘          └─────────┘          └─────────┘
                                                    │
                                            ┌───────┴───────┐
                                            │   Layout /    │
                                            │    Paint      │
                                            │       ↓       │
                                            │   Buffer      │
                                            │  ┌───────┐    │
                                            │  │ Diff  │    │
                                            │  └───┬───┘    │
                                            │      ↓        │
                                            │  ┌───────┐    │
                                            │  │ ANSI  │    │
                                            │  │ stdout│    │
                                            │  └───────┘    │
                                            └───────────────┘

🧰 Widgets

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

🧪 Project Status

Metric Value
Dart SDK ^3.6.0
Tests 101
Analysis 0 issues
Dependencies zero (pure Dart)
License MIT

🗺 Roadmap

  • 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

🤝 Contributing

This project is in early development. Contributions, issues, and ideas are welcome.

📄 License

MIT — see LICENSE.

About

A declarative TUI framework for Dart — inspired by Ratatui (Rust) and Flutter.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages