gilt
Rich terminal formatting for Rust — a port of Python's rich library.
Beautiful terminal output for Rust: styles, tables, trees, syntax highlighting, progress bars, live displays, markdown rendering, and more — all rendered as ANSI escape sequences.
Quick start
[]
= "1.4"
use Console;
Upgrading from 0.13.x? See MIGRATION_v1.md — most code becomes shorter (lossy Style::parse, ergonomic Text::styled, Status::run, Live::from_renderable, Padding::wrap, …).
Features
Core widgets
Text · Table · Panel · Tree · Columns · Layout · Padding · Align · Group
Terminal features
Syntax (150+ languages) · Markdown · Json · Progress (multi-bar with ETA, speed, spinner) · Live (in-place updates) · Status
Rust-native extensions
Gradient · Sparkline · Canvas (Braille drawing) · Diff (unified + side-by-side) · Figlet · CsvTable · Stylize trait ("hi".bold().red()) · iterator .progress() · Inspect (any Debug value) · environment detection (NO_COLOR, FORCE_COLOR, CLICOLOR) · WCAG 2.1 contrast checking · extended underlines (curly, dotted, dashed, double) · bidirectional anstyle interop
Derive macros (feature-gated)
use ;
Auto-generate widget conversions from struct definitions. See crates/gilt-derive/README.md.
Optional integrations
miette · eyre · tracing · anstyle
Documentation
| Resource | Where |
|---|---|
| API docs | docs.rs/gilt |
| Release notes | CHANGELOG.md |
| v1.0 migration guide | MIGRATION_v1.md |
| Derive macros | crates/gilt-derive/ · docs.rs/gilt-derive |
| Examples | examples/ — run any with cargo run --example <name> |
| Feature flags & deps | docs.rs/crate/gilt/latest/features |
Examples
WebAssembly
gilt compiles for wasm32-unknown-unknown without modification — no
libc, crossterm, or terminal-syscall dependencies. The intended
browser path is record-mode + export:
let mut console = builder.width.record.build;
console.print;
let ansi = console.export_text; // pipe into xterm.js
let html = console.export_html; // inject into the DOM
Unicode handling
gilt computes visible cell width via unicode-width
and iterates by extended grapheme cluster (UAX #29) via
unicode-segmentation where
correctness matters.
Supported (correct visible width and intact iteration):
- ASCII, Latin-1, Latin Extended
- CJK fullwidth (Chinese, Japanese, Korean) — 2 cells
- Single-codepoint emoji — 2 cells
- ZWJ family clusters (
👨👩👧) — single 2-cell unit, never split mid-cluster - Flag emoji (
🇺🇸= 2 regional-indicator codepoints) — single 2-cell unit - Variation selector sequences (
❤️=❤+ VS-16) — emoji-presentation width - Combining mark sequences (
caféascafe + ́) — 0-width combining stays with its base
Not supported (out of scope, deferred):
- Bidi text direction (Arabic, Hebrew RTL).
Columns::right_to_leftreverses column order, not character bidi. - NFC/NFD normalisation — input is used as-is.
- Vertical text layout (Mongolian, classical Chinese).
Truncation and cropping (Console::truncate, Text::truncate,
Text::right_crop, anything routing through set_cell_size) snap to
grapheme-cluster boundaries — a 3-cell crop of "👨👩👧 family" will
not leave a dangling ZWJ joiner.
Performance
cargo bench runs the criterion suite (~80 benchmarks). See CHANGELOG.md for v0.10.x → v0.11.0 perf wins (T8 lock-free Live +21,000×, table render -46%, etc.).
Minimum Supported Rust Version
1.82.0 (for std::sync::LazyLock).
License
MIT — see LICENSE.