Lunatui

Moonlit terminal UIs in Rust

A Rust library for building terminal user interfaces.

Install with Cargo
$ cargo add lunatui

Widgets

Every preview on this page is terminal text in Lunatui's default dark theme, set in HTML at the size your terminal draws it. Open the code under any widget to see what draws it.

Browse all widgets on GitHub
cargo run --example release_console_app112 × 30 cells46 × 27 cells

Form

Labels, required markers, dim hints and fail-colored errors around your own inputs.

let form = Form::new([
    FormField::new("Name").required().hint("As it appears on invoices"),
    FormField::new("Email").required().error("Enter a full email address"),
    FormField::new("Plan"),
    FormField::new("Updates"),
])
.focus(Some(0));
form.render(area, &mut cx);
RadioGroup::new(["Free", "Pro", "Team"]).flow(RadioFlow::Horizontal).gap(3).render(plan, &mut cx);
Toggle::new(true).label("Product news").render(updates, &mut cx);

ProgressBar

Segmented bars with eighth-block ends, so ok, warn and fail share one track.

ProgressBar::new()
    .segment(0.86, ProgressTone::Ok)
    .segment(0.07, ProgressTone::Warn)
    .segment(0.03, ProgressTone::Fail)
    .render(area, &mut cx);

LogView

A ring buffer of entries, drawn newest first with level colors. It follows new output until you scroll.

let mut log = LogBuffer::new(500);
log.push(LogEntry::new(LogLevel::Warn, "probe", "/healthz slow, 412 ms").stamp("14:02:04"));
log.push(LogEntry::new(LogLevel::Error, "search", "search refused :9200").stamp("14:02:05"));

LogView::new(&log)
    .target_width(0)
    .follow(true)
    .render(area, &mut cx);

Monthly

One month in a 21-column Sunday grid, with event days marked from theme tokens.

Monthly::new(date(2026, 11, 1), events.as_slice())
    .state(WidgetState::Focused)
    .render(area, &mut cx);

Sparkline

One column per sample in eight block steps, one row or several.

Sparkline::new(&requests)
    .max(24)
    .render(Rect::new(x, y, 44, 3), &mut cx);
Sparkline::new(&errors).render(Rect::new(x, y + 5, 44, 1), &mut cx);

BarChart

Vertical or horizontal bars with eighth-block tops, value labels and group gaps.

let bars = [
    Bar::new(34).label("Mon"), Bar::new(41).label("Tue"), Bar::new(38).label("Wed"),
    Bar::new(52).label("Thu"), Bar::new(61).label("Fri"), Bar::new(18).label("Sat"),
    Bar::new(12).label("Sun"),
];
BarChart::from_bars(&bars)
    .bar_width(4)
    .bar_gap(2)
    .render(area, &mut cx);

Accordion

Collapsible sections with a caret, a title and a dim badge. Your content goes in each open body.

Accordion::new(vec![
    AccordionSection::new("Build", 2).open(true).badge("2 steps"),
    AccordionSection::new("Package", 2).badge("2 steps"),
    AccordionSection::new("Publish", 1).open(true).badge("1 step"),
    AccordionSection::new("Notify", 0).badge("off"),
])
.focus(Some(2))
.render(area, &mut cx);

BigText

Large letters from an 8 by 8 pixel face, in full, half-height, quadrant or finer blocks.

BigText::new("14:02")
    .pixel_size(PixelSize::HalfHeight)
    .alignment(Alignment::Center)
    .render(area, &mut cx);

Speed

Median time to paint, diff and encode one frame. Lower is faster.

Median time per frame, release build
80 × 2460 µs
200 × 60249 µs

Each result is the median of five runs of 240 frames. Timing covers widget paint, diffing, ANSI encoding, and a counting sink write; terminal rendering and model updates are outside the measurement. Method and full results

5 runsper screen size

Technical details

Rendering, input, widgets, performance and build requirements, each with its source.

Input & runtime

  • Keyboard, mouse, and bracketed‑paste input
  • Focus management and hit testing
  • Event-driven frame scheduling with animation
Source: project overview

Widgets & themes

  • Calendar, BigText, and Sparkline widgets
  • Theme tokens and terminal color capabilities
  • Unicode grapheme and width handling
Source: widget crate

Performance method

  • Apple M5 Max · macOS arm64 · release build
  • 240 frames per run; median of five runs
  • Headless counting sink; no terminal latency included
Source: full report

Testing & CI

  • Built and tested on Linux, macOS, and Windows
  • Allocation tests guard the render hot paths
  • Clippy runs with warnings treated as errors
Source: CI workflow

Start with the quickstart

Install, run a template in your browser, then copy it into your project.

Open the quickstart

Independent systems / The maker

Moonbase2090

Moonbase2090 builds Lunatui. The source is available under the MIT License, copyright Moonbase 2090 LLC.

Visit Moonbase 2090 ↗