termimad

Rust library for rendering Markdown text, tables, and templates in terminal applications with fully customizable, skinnable styling.

Library
Cargo
v0.35.2
1,222stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
60/100Good
Development Activity68
Maintenance28
Community44
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
83/100Excellent
Architecture82
Code Quality78
Innovation80
Learning Curve90

Termimad is a Rust library for displaying Markdown-formatted text, tables, and templates in terminal applications. It parses a practical subset of Markdown — bold, italic, strikeout, inline code, code blocks, quotes, headers, and pipe-based tables — and renders it through a fully customizable MadSkin, keeping structure, content, and presentation separate.

Built on crossterm for styling and terminal events and crokey for key-combination handling, Termimad focuses on precise terminal control and performance rather than being a full TUI framework. It powers the interactive help screens, status views, and templated table output in several published Rust CLI tools, including broot, bacon, and dysk.

What You Get

  • A MadSkin type for defining per-element terminal styling (colors, bold/italic/underline) independent of content
  • Wrapped, width-aware text and table rendering with optional scrollbar support via MadView/TextView
  • Text and inline template macros (mad_print!, mad_print_inline!, TextTemplate) for safely filling placeholders into pre-parsed Markdown
  • A Question/ask! macro for simple keyed terminal prompts with a default answer
  • Serde support for loading skins from external files such as Hjson

Common Use Cases

  • Rendering —help output and in-app documentation for CLI tools
  • Displaying scrollable status or log panels in a TUI’s alternate screen
  • Filling and printing dynamic Markdown tables from runtime data
  • Prompting users with multiple-choice terminal questions

Under The Hood

Architecture Termimad is organized as a set of focused modules under src/ that map cleanly onto the rendering pipeline: parse/ turns skin-definition strings into style structs, minimad (an external crate) parses Markdown source into a Text/Composite tree, fit/ handles wrapping and width-fitting (wrap.rs, tbl_fit.rs, crop_writer.rs), and skin.rs (MadSkin) walks that tree applying a LineStyle/CompoundStyle per element to produce a FmtText/FmtLine ready for Display. Presentation surfaces live in views/ (MadView, TextView, ListView, InputField, ProgressBar), each borrowing an Area/Rect rather than owning the terminal. The crate re-exports crossterm and crokey directly (see lib.rs), so consumers get a single coherent dependency surface instead of juggling transitive versions themselves. Because rendering is pull-based (build a FmtText, then Display/write it) rather than driven by an active event loop, the core abstraction that would break the most on change is FmtComposite/FmtLine — nearly every module (fit, skin, tbl, views) consumes it directly.

Tech Stack The crate targets Rust edition 2021 with a minimum supported Rust version of 1.56 and resolver = “1”. Core dependencies are minimad (the underlying Markdown parser Termimad wraps), crossterm with the coolor crate for terminal styling and color handling, crokey for parsing key-combination strings, crossbeam for the EventSource/Ticker channel-based event system, serde for skin (de)serialization, thiserror for the crate’s Error enum, and unicode-width for correct wide-character wrapping. A special-renders feature flag (on by default) gates an experimental compound-replacement API. Dev-dependencies (anyhow, deser-hjson, pretty_assertions, serde_json, terminal-clipboard) support the test suite and the 19 runnable examples under examples/, which double as living documentation for nearly the whole public API.

Code Quality The crate has a dedicated tests/ directory (fit.rs, parse.rs, skin_serde.rs, tables.rs, wrap.rs, plus a regression test named after its GitHub issue number) exercising wrapping correctness, table fitting, and skin serialization round-trips — wrap.rs in particular asserts no line overflows or empty lines after hard-wrapping at multiple widths. Error handling is explicit and typed via a thiserror-derived Error enum (errors.rs) wrapping IO and InsufficientWidth failures rather than panicking or swallowing errors, and the crate is denied against known-bad dependencies via a checked-in deny.toml. Naming is consistent Rust convention throughout (FmtText, FmtLine, FmtComposite forming a clear pipeline), public types carry doc comments with runnable rustdoc examples (visible in lib.rs and skin.rs), and CI configuration lives under .github/. No coverage tooling or fuzzing setup is present, but the combination of typed errors, an explicit test suite, and doc-tested examples across every public entry point indicates a maintained, disciplined codebase.

API Design The public API is intentionally small at the entry point — termimad::print_inline, termimad::text, and termimad::term_text cover the common case with a single function call using a lazily-built default skin — while MadSkin exposes the full styling surface for applications that need control. Naming is consistent and predictable (inline/text/term_text mirror each other; FmtInline/FmtText/FmtLine mirror the same progression at the type level), and the crate re-exports crossterm and minimad so downstream code never needs to add or version-match those crates itself. Getting started requires near-zero boilerplate (a single print_inline(“bold”) call works out of the box), while the templating macros (mad_print_inline!, TextTemplate) are specifically designed to avoid a common footgun — accidentally interpreting dynamic content as Markdown syntax — which shows deliberate API-safety thinking beyond just convenience.

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