Layout in cells
Row, Column, Flex, Stack, Wrap, overlays, borders, and scrolling use integer terminal geometry.
Learn the layout modelNoir gives a terminal program a widget tree, retained state, and layout measured in cells.
Build your first appRun an example
dart pub add noirRequires Dart 3.10 or later.
class _CounterAppState extends State<CounterApp> {
int _count = 0;
void _increment() => setState(() => _count++);
@override
Widget build(BuildContext context) => Container(
padding: const EdgeInsets.all(1),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 1,
children: [
Text('Count: $_count'),
Button(autofocus: true, label: '+ Add one', onPressed: _increment),
],
),
);
}
Count: 1
+ Add one
Compose the screen from public widgets instead of writing escape sequences around raw terminal output.
Row, Column, Flex, Stack, Wrap, overlays, borders, and scrolling use integer terminal geometry.
Learn the layout modelFocus traversal, shortcuts, editable text, pointer hit testing, and wheel input share one ordered pipeline.
Route input correctlyButtons, fields, selects, tabs, sliders, lists, and data tables keep values explicit and keyboard behavior predictable.
Browse the widget catalogCodeView, DiffView, MarkdownView, rich tables, hyperlinks, and terminal images live on the same retained render path.
Find document widgets