muse 0.1.0-dev.1
muse: ^0.1.0-dev.1 copied to clipboard
A Flutter-like reactive terminal UI framework for Dart, powered by OpenTUI.
Muse #
Muse is a Flutter-like terminal UI framework built on OpenTUI via Dart FFI, providing declarative widgets, terminal-first layout, focus management, animations, and native buffer APIs familiar to Flutter developers.
- A declarative widget framework with
StatelessWidget,StatefulWidget,BuildContext, andsetState. - Terminal-first layout primitives such as
Row,Column,Container,Padding,SizedBox,Align,Flexible, andExpanded. - Shared framework services including focus, pointer routing, inherited dependencies, diagnostics, and animations.
- Native OpenTUI bindings, packaged binaries, and low-level buffer/renderer APIs for direct use when needed.
The repo is the development home for the framework and is preparing its first
development release on pub.dev as muse.
Current Status #
Core framework work is in place:
runTuiAppis the primary application entry point and returns aTuiBindinglifecycle handle- Layout, styling, focus/input routing, inherited state, diagnostics, and animation scaffolding are implemented
- Analyzer and test coverage are in active use for framework changes
- Packaged native binaries are checked in under
native/ - Local Go parity exists for primitive scenes; widget parity is the next active lane
Quick Start #
Clone the repo and install Dart dependencies:
dart pub get
Run a few representative examples:
dart run example/hello.dart
dart run example/layout_demo.dart
dart run example/focus_form.dart
dart run example/pulse_animation.dart
Run the baseline validation commands:
dart analyze
dart test
Example Apps #
Static rendering and animation:
example/hello.dart— minimal renderingexample/counter.dart— stateful rebuildsexample/layout_basics.dart— core layout tourexample/layout_demo.dart— richer flex/alignment/decorationsexample/inherited_example.dart— inherited dependencies and rebuild propagationexample/bindings_validation.dart— low-level FFI smoke testexample/pulse_animation.dart—AnimationControllerand ticker usage
Interactive widgets (use these to verify keyboard/mouse work in your terminal):
example/focus_form.dart— focus manager andTextInputroutingexample/select_demo.dart—Select<T>with arrows /j/k/ Enterexample/scrollbox_demo.dart—ScrollBoxwith arrows / PgUp / PgDn / Home / Endexample/textarea_demo.dart— multi-lineTextArea, Ctrl+Enter to submitexample/widgets_tour.dart— combined tour, Tab cycles focus
Supported Keyboard and Mouse Input #
The stdin parser (lib/src/core/stdin_input_driver.dart) decodes:
| Input | Result |
|---|---|
| Printable ASCII / UTF-8 | KeyEvent(key: '<char>') |
| Backspace (BS / DEL) | KeyEvent(key: 'Backspace') |
| Tab | KeyEvent(key: 'Tab') |
| Enter (CR / LF) | KeyEvent(key: 'Enter') |
| Escape | KeyEvent(key: 'Escape') |
| Ctrl + letter | KeyEvent(key: '<letter>', modifiers: KeyModifiers.ctrl) |
| Arrow keys | ArrowUp / ArrowDown / ArrowLeft / ArrowRight |
| Home / End | Home / End |
| Delete / PageUp / PageDown | Delete / PageUp / PageDown |
| Function keys | F1–F12 (both ESC O P/Q/R/S and ESC [N~) |
| Mouse SGR | MouseEvent { type, button, x, y, modifiers, scrollDelta } |
| Bracketed paste | one PasteEvent per block — subscribe via binding.inputManager.onPaste |
| Kitty CSI-u | KeyEvent with full Kitty modifiers when binding.enableKittyKeyboard() |
Signal handling: SIGINT, SIGTERM, and SIGHUP restore terminal modes and exit cleanly (POSIX). SIGWINCH triggers a buffer resize and re-layout.
Basic Framework Usage #
import 'package:muse/muse.dart';
class CounterApp extends StatefulWidget {
const CounterApp({super.key});
@override
State<CounterApp> createState() => _CounterAppState();
}
class _CounterAppState extends State<CounterApp> {
int count = 0;
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
child: Text('Count: $count'),
);
}
}
void main() {
runTuiApp(const CounterApp());
}
For inspection-heavy tests and diagnostics, runTuiApp(..., headless: true)
avoids drawing while still exercising the widget and render pipelines.
Native Libraries #
Native OpenTUI binaries are packaged as Dart native assets. The build hook
(hook/build.dart) verifies native_manifest.json, bundles the current
platform library for dart run, dart test, and dart build cli, and falls
back to a manifest download or Zig source build when the checked-in binary is
missing.
- Standard development flow uses the bundled native asset automatically
OPENTUI_LIBRARY_PATHis the exact development override for a custom builddart run scripts/fetch_opentui_binaries.dart --verify-onlyverifies thatnative_manifest.jsonmatches the checked-in binariesdart build cli -t bin/health_check.dartproduces a CLI bundle with the executable underbundle/bin/andlibopentuiunderbundle/lib/
Examples:
dart run scripts/fetch_opentui_binaries.dart --verify-only
dart build cli -t bin/health_check.dart
If you need to point at a custom library build:
export OPENTUI_LIBRARY_PATH=/path/to/libopentui.dylib
dart run example/hello.dart
Testing and Goldens #
Detailed testing notes live in test/README.md. The short version:
dart analyze
dart test
Regenerate goldens only when the visual change is intentional:
UPDATE_GOLDENS=1 dart test test/golden
UPDATE_GOLDENS=1 dart test test/example/layout_basics_golden_test.dart
Failure artifacts are written to test/failures/ during failed golden runs and are intentionally ignored by git.
Local Go Parity #
Primitive parity compares Dart-rendered snapshots against a repo-owned Go snapshot tool that uses the external/opentui git submodule bindings.
Initialize the OpenTUI submodule first if your checkout did not fetch submodules:
git submodule update --init external/opentui
Run the wrapper directly:
./scripts/run_go_snapshot.sh --scene S1 --width 20 --height 5
Run the comparator:
GO_SNAPSHOT_CMD=./scripts/run_go_snapshot.sh \
dart run bin/parity_compare.dart --scenes S1,S2,S3 --width 20 --height 5
Run the parity tests:
GO_SNAPSHOT_CMD=./scripts/run_go_snapshot.sh \
dart test test/parity
Repo References #
- tasks/plan.md — canonical roadmap
- example/README.md: example catalog
- test/README.md: testing workflow
- FFIGEN.md: binding regeneration notes
For OpenTUI behavior validation, compare against:
external/opentui/packages/coreexternal/opentui/packages/goexternal/opentui/packages/react
Notes #
- Alternate-screen rendering and debug logging are controlled by
TuiBindingandTERMINAL_TUI_DEBUG_LOG=1. - The current roadmap intentionally prioritizes correctness, parity, and cleanup over backward compatibility or deprecation work.