artisanal 0.6.0 copy "artisanal: ^0.6.0" to clipboard
artisanal: ^0.6.0 copied to clipboard

A full-stack terminal toolkit for Dart featuring Lip Gloss styling, Bubble Tea TUI architecture, and Ultraviolet rendering.

Artisanal #

License: MIT Documentation Buy Me A Coffee

Build polished command-line tools and interactive terminal applications in Dart with one consistent toolkit.

Artisanal brings together high-level CLI output, Lip Gloss-inspired styling, a Bubble Tea-style runtime, reusable Bubbles, a widget framework, and the Ultraviolet cell-buffer renderer.

Table of contents #

Overview #

Feature Description
CLI I/O High-level Console helpers for status lines, tables, tasks, prompts, and styled output
Styling Fluent, immutable Style API with colors, borders, padding, margins, and themes
TUI Runtime Elm Architecture (Model/Msg/Cmd) with a full-featured Program event loop
Bubbles 20+ reusable widgets: inputs, lists, tables, spinners, progress bars, file pickers, etc.
Ultraviolet (UV) High-performance cell-buffer renderer with diff-based updates and graphics support
Terminal + Renderer Unified terminal abstraction, ANSI helpers, and renderer backends
Markdown ANSI Markdown renderer plus Glamour high-fidelity output
Charting Sparklines, line/ribbon charts, histograms, heatmaps, and pie charts

Installation #

Add Artisanal to your project:

dart pub add artisanal

Or add it to pubspec.yaml:

dependencies:
  artisanal: ^0.6.0

For widget-only applications, depend on artisanal_widgets directly. Use artisanal when you want the broader CLI, style, runtime, and rendering stack.

Quick start #

CLI output #

Minimal example

import 'package:artisanal/artisanal.dart';

void main() {
  final io = Console();

  io.title('Minimal Artisanal CLI');
  io.info('Starting up...');
  io.success('Ready to ship.');
}

Run the included example from the repository root:

dart run pkgs/artisanal/example/minimal_cli.dart

Minimal Artisanal CLI

Complete CLI flow

import 'package:artisanal/artisanal.dart';

Future<void> main() async {
  final io = Console();

  io.title('My App');
  io.section('Setup');
  io.info('Checking configuration...');

  await io.task('Running migrations', run: () async {
    await Future.delayed(const Duration(milliseconds: 200));
    return TaskResult.success;
  });

  io.table(
    headers: ['ID', 'Name', 'Status'],
    rows: [
      [1, 'users', io.style.success('DONE')],
      [2, 'posts', io.style.warning('PENDING')],
    ],
  );

  final proceed = io.confirm('Continue?', defaultValue: true);
  if (!proceed) return;

  io.success('All good.');
}

CLI Output

Styling #

import 'package:artisanal/style.dart';

final style = Style()
    .bold()
    .foreground(Colors.purple)
    .padding(1, 2)
    .border(Border.rounded);

print(style.render('Hello, Artisanal!'));

Hello artisanal

Style capabilities

  • Text effects: bold(), italic(), underline(), strikethrough(), dim(), inverse(), blink()
  • Colors: ANSI 16, ANSI 256, TrueColor (RGB), AdaptiveColor (light/dark aware)
  • Spacing: padding(), margin()
  • Borders: rounded, thick, double, hidden, custom
  • Alignment: align(), alignVertical()
  • Dimensions: width(), height(), maxWidth(), maxHeight()
  • Themes: ThemePalette with presets (dark, light, ocean, nord, dracula, monokai, solarized)

Interactive TUI #

import 'package:artisanal/tui.dart';

class CounterModel implements Model {
  final int count;
  const CounterModel([this.count = 0]);

  @override
  Cmd? init() => null;

  @override
  (Model, Cmd?) update(Msg msg) {
    return switch (msg) {
      KeyMsg(key: Key(type: KeyType.up)) => (CounterModel(count + 1), null),
      KeyMsg(key: Key(type: KeyType.down)) => (CounterModel(count - 1), null),
      KeyMsg(key: Key(type: KeyType.runes, runes: [0x71])) => (this, Cmd.quit()),
      _ => (this, null),
    };
  }

  @override
  String view() => 'Count: $count\n\nUse ↑/↓ to change, q to quit';
}

Future<void> main() async {
  await runProgram(CounterModel());
}

Toolkit #

Console helpers #

Category Methods
Output writeln(), write(), title(), section()
Messages line(), info(), comment(), question(), warn(), error(), note(), caution(), alert(), verbose(), debug()
Layout table(), tree(), listing(), twoColumnDetail(), text()
Interactive ask(), confirm(), choice(), secret(), selectChoice(), multiSelectChoice(), menu(), search()
Progress task(), spin(), progress(), progressIterate()

Command runner #

Build CLI tools with styled help and nested commands:

import 'package:artisanal/args.dart';

class HelloCommand extends Command {
  @override
  String get name => 'hello';

  @override
  String get description => 'Say hello';

  @override
  void run() {
    io.success('Hello, world!');
  }
}

void main(List<String> args) async {
  final runner = CommandRunner('my-cli', 'A great CLI');
  runner.addCommand(HelloCommand());
  await runner.run(args);
}

Command Runner

Bubbles #

Widget Description
TextInputModel Single-line text input
TextAreaModel Multi-line text editing
ListModel Filterable list selection
TableModel Interactive tables
ViewportModel Scrollable content pane
ProgressModel Progress bars with ETA
SpinnerModel Animated loading spinners
FilePickerModel File/directory browser
AnticipateModel Autocomplete with suggestions
WizardModel Multi-step form wizard
SelectModel<T> Single-choice selection prompt
MultiSelectModel<T> Multiple-choice selection
PasswordModel Masked password input
TimerModel Countdown timer
StopwatchModel Elapsed time tracking
PaginatorModel Pagination controls
HelpModel Key binding help views

Ultraviolet renderer #

High-performance rendering with diff-based updates for flicker-free TUI applications:

await runProgram(
  MyModel(),
  options: const ProgramOptions(
    useUltravioletRenderer: true,
    useUltravioletInputDecoder: true,
    altScreen: true,
    mouse: true,
  ),
);

UV features

  • 2D cell buffer with styled cells
  • Diff-based terminal updates (minimal redraws)
  • Layer composition and hit-testing
  • Reusable color, CRT, scanline, distortion, and persistence effects through BufferRenderSink
  • Mouse support and focus events
  • Graphics: Kitty, Sixel, iTerm2, half-block drawing

Replay and trace debugging #

The TUI runtime supports deterministic replay (ProgramReplay) and built-in file tracing (TuiTrace) for debugging and profiling.

Enable tracing for any TUI app:

ARTISANAL_TUI_TRACE=1 ARTISANAL_TUI_TRACE_CAPTURE=1 \
ARTISANAL_TUI_TRACE_PATH=traces/my-run.log \
dart run your_app.dart

Structured app/domain events can be emitted via TuiTrace.event(...) and are preserved in replay conversion when they use stable typed type names.

See the TUI documentation for replay and tracing details.

Library entrypoints #

Choose the smallest public library that covers your use case:

Import Purpose
package:artisanal/artisanal.dart Umbrella API for CLI output, styling, charting, Markdown, hosts, and common terminal types
package:artisanal/args.dart Command runner utilities (CommandRunner, Command)
package:artisanal/bubbles.dart Reusable TEA widgets
package:artisanal/catalog.dart Public metadata registry for Bubbles and display components
package:artisanal/style.dart Styles, colors, borders, layout, and themes
package:artisanal/tui.dart TEA runtime (Model, Msg, Cmd, Program) plus replay and tracing
package:artisanal/runtime.dart Platform-safe TEA runtime for reusable and browser-capable packages
package:artisanal/terminal.dart Terminal abstraction, ANSI helpers, keys, backends, and bridges
package:artisanal/editor_core.dart Low-level text document, editor state, and viewport primitives
package:artisanal/text_editing.dart Focused cursor, text input, text area, and editor-core surface
package:artisanal/markdown.dart Markdown-to-ANSI renderer and options
package:artisanal/git_diff.dart Git diff model, styles, and review data types
package:artisanal/charting.dart Terminal chart painters and data primitives
package:artisanal/layout.dart String layout, wrapping, and responsive utilities
package:artisanal/scoring.dart Bayesian matching and conformal ranking utilities
package:artisanal/glamour.dart High-fidelity Markdown rendering
package:artisanal/uv.dart Compatibility re-export of Ultraviolet types
package:artisanal/compat.dart Backward-compatible API shims

Widget-first applications depend on and import package:artisanal_widgets/... directly; widget APIs are not re-exported from this core package. Renderer-level applications can import package:ultraviolet/ultraviolet.dart directly.

See the example/ directory for comprehensive demos:

  • main.dart – Full feature showcase
  • minimal_cli.dart – Minimal CLI output example
  • widget_catalog.dart – Searchable component catalog and theme showcase
  • fluent_style_example.dart – Style API patterns
  • spinner_demo.dart – Various spinner types
  • lipgloss_table.dart – Styled tables
  • log_viewer_demo.dart – Monitoring dashboard
  • command_center_demo.dart – Multi-panel layouts
  • tui/examples/uv-effects/main.dart – Applying UV effects to a canvas buffer
  • Additional engine-specific demos live in pkgs/ultraviolet/example/

Commands in this gallery assume the repository root as the working directory.

CLI walkthroughs #

The small CLI tapes focus on one interaction at a time and keep the matching command immediately beside its recording.

Tables (example/.vhs/cli_table.tape):

dart run pkgs/artisanal/example/main.dart ui:table --ansi

CLI table

Prompts (example/.vhs/cli_prompts.tape):

dart run pkgs/artisanal/example/main.dart ui:prompts --defaults --no-interaction --ansi

CLI prompts

Display components (example/.vhs/cli_components.tape):

dart run pkgs/artisanal/example/main.dart ui:components --ansi

CLI components

Progress (example/.vhs/cli_progress.tape):

dart run pkgs/artisanal/example/main.dart ui:progress --count 40 --ansi

CLI progress

Full demo captures #

Recordings of the more consequential examples, regenerated from the VHS tapes in example/.vhs/ with task artisanal-demos:

Markdown renderer (example/markdown_demo.dart):

Markdown demo

Glamour themes (example/glamour_demo.dart):

Glamour demo

CLI runner showcase (example/main.dart):

Main demo

Lip Gloss TUI (example/lipgloss_tui.dart):

Lip Gloss TUI

Spinners (example/spinner_demo.dart):

Spinner demo

Log viewer (example/log_viewer_demo.dart):

Log viewer demo

Split dashboard (example/split_dashboard_demo.dart):

Split dashboard demo

Command center (example/command_center_demo.dart):

Command center demo

Data table (example/data_table_demo.dart):

Data table demo

Sequence diagram (example/sequence_diagram_demo.dart):

Sequence diagram demo

Styled tables (example/lipgloss_table.dart):

Lip Gloss tables

Styled lists (example/lipgloss_list.dart):

Lip Gloss lists

Styled trees (example/lipgloss_tree.dart):

Lip Gloss trees

Charting (example/charting_demo.dart):

Charting demo

Markdown showcase (example/markdown_showcase.dart):

Markdown showcase

Theme integration (example/theme_integration_demo.dart):

Theme integration demo

Compositor images (example/compositor_image_demo.dart):

Compositor image demo

Editor core (example/editor_core_demo.dart):

Editor core demo

Fluent style API (example/fluent_style_example.dart):

Fluent style demo

Kitty images (example/kitty_image_demo.dart):

Kitty image demo

Console tags (example/lipgloss_console_tags.dart):

Console tags demo

Lip Gloss layout (example/lipgloss_layout.dart):

Lip Gloss layout demo

Render recorder (example/render_recorder_demo.dart):

Render recorder demo

Scanner spinner (example/scanner_demo.dart):

Scanner demo

Inline animation (example/inline_animation_demo.dart):

Inline animation demo

DevTools counter (example/devtools_demo.dart):

DevTools demo

Multi search (example/multi_search_demo.dart):

Multi search demo

Artisanal Nexus (example/uv_tui_demo.dart):

Nexus demo

Static screenshots #

Log viewer

Log Viewer

Console tags

Console Tags

Layout

Layout

Documentation and support #

Artisanal is a Dart port of Charm's Lip Gloss, Bubble Tea, and Bubbles. The project aims for broad parity, but some behavior may still differ from the Go originals. Reports with small reproductions are especially helpful.

4
likes
160
points
4.96k
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A full-stack terminal toolkit for Dart featuring Lip Gloss styling, Bubble Tea TUI architecture, and Ultraviolet rendering.

Repository (GitHub)
View/report issues

Topics

#cli #tui #terminal

Funding

Consider supporting this project:

www.buymeacoffee.com

License

MIT (license)

Dependencies

acanthis, args, characters, completion, highlight, hotreloader, html, html_unescape, image, liquify, markdown, meta, mime, path, petitparser, pure_svg, ultraviolet, web

More

Packages that depend on artisanal