ansi-to-tui

Convert ANSI SGR escape codes in raw bytes into styled Ratatui Text, ready to render in your TUI.

Library
Cargo
v8.0.1
99stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
45/100Fair
Development Activity28
Maintenance20
Community52
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
85/100Excellent
Architecture83
Code Quality85
Innovation88
Learning Curve82

ansi-to-tui is a Rust crate that parses bytes containing ANSI SGR escape sequences (like \x1b[31m) and produces a Ratatui Text value with equivalent foreground/background colors and style modifiers. It exists so terminal-colored output captured from subprocesses, log files, or CI tooling can be dropped straight into a Ratatui-based TUI without hand-rolling an ANSI parser or pre-cleaning the input first.

The crate supports named 3/4-bit colors, 8-bit indexed colors, and 24-bit truecolor, plus common SGR modifiers (bold, italic, underline, strikethrough, blink, reverse, conceal). Unknown or malformed escape sequences are ignored rather than causing a hard failure, so real-world terminal output that doesn’t perfectly conform to the spec still parses cleanly.

What You Get

  • A single IntoText trait, blanket-implemented for any AsRef<[u8]> type (String, &str, Vec<u8>, &[u8]), exposing .into_text() for an owned Text<'static>
  • An optional .to_text() zero-copy method (behind the default-on zero-copy feature) that borrows spans from the input instead of allocating
  • Support for named/indexed/truecolor ANSI color codes and SGR style modifiers (bold, italic, underline, strikethrough, blink, reverse, conceal), mapped onto Ratatui’s Color, Style, and Modifier types
  • Optional SIMD-accelerated UTF-8 validation via the simd feature (using the simdutf8 crate), with a safe fallback to String::from_utf8 when disabled
  • Lenient parsing that silently ignores unrecognized or malformed escape sequences instead of erroring out on real-world terminal output

Common Use Cases

  • Rendering cargo build, docker, or other CLI subprocess output with its original ANSI coloring inside a Ratatui TUI panel
  • Displaying colorized log files or CI output logs in a terminal dashboard without losing their original styling
  • Building terminal pagers, log viewers, or tail -f-style widgets that need to preserve upstream color codes

Under The Hood

Architecture — The public surface is a single IntoText trait defined in src/lib.rs, blanket-implemented for any T: AsRef<[u8]>. into_text() delegates to parser::text() for an owned, always-available Text<'static>; the feature-gated to_text() delegates to parser::text_fast() for a zero-copy Text<'_> borrowing from the input. All real parsing work lives in src/parser.rs (~400 lines), built on the nom parser-combinator crate: it walks the byte stream recognizing CSI/SGR escape sequences, converts each into an AnsiCode variant (defined in src/code.rs, carrying an optional Color), and folds a smallvec-backed sequence of these AnsiItems into a ratatui_core::style::Style via an AnsiStates -> Style conversion that walks each code (bold, faint, colors, resets, etc.) and applies or removes the corresponding Modifier/Color. All error paths funnel into one Error enum (src/error.rs) via thiserror, unifying nom parse failures and UTF-8 decode failures. Tech Stack — Rust 2024 edition, MSRV 1.86. Core dependencies are minimal and purposeful: nom 8 for the parser combinators, ratatui-core 0.1 with default-features = false (kept lean for embedding), smallvec 1 with const generics to avoid heap allocation for the common few-item style sequence, and thiserror 2 for the error enum. simdutf8 is optional (simd feature, on by default) for faster UTF-8 validation. Dev-dependencies (anyhow, eyre, criterion, pretty_assertions) support testing and a Criterion benchmark (benches/parsing); a Nix flake pins the dev environment, and CI runs via GitHub Actions with Codecov coverage reporting. Code Qualitysrc/tests.rs (548 lines, larger than the parser it tests) exercises plain text, individual and combined SGR codes, all three color modes, and edge cases such as empty escape sequences (\x1b[m) treated as a reset, referencing the upstream GitHub issue that motivated the fix directly in a code comment. Tests use pretty_assertions for readable diff output and a shared test_both helper to assert into_text/to_text parity. No unsafe code appears anywhere in src/. The crate enables #![warn(missing_docs)], enforcing doc comments on every public item. API Design — The public API is intentionally tiny: one trait, two methods, both callable with zero setup on any byte-like type via the blanket AsRef<[u8]> impl (bytes.into_text()?). Every public item carries a doc comment, and src/lib.rs embeds runnable doctests that double as the crate’s own usage examples. Feature flags (simd, zero-copy) are additive performance opt-outs, not prerequisites — the crate works with zero configuration out of the box.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search