scriba
Typed CLI output, prompts, and terminal rendering for Rust.
scriba helps you build clean, structured command-line interfaces with composable output primitives, interactive prompts, styled logging, and optional ASCII banners.
Features
- 📄 Multi-format rendering: Plain, Text, Markdown, JSON, JSONL
- 🧱 Typed output blocks and builders
- 💬 Interactive prompts (feature:
prompt) - 🎨 Styled logging (feature:
logger) - 🔤 ASCII banners / figlet rendering (feature:
figlet) - 📊 Structured diff viewer with format support
- ⚙️ Feature-gated integrations
- 🦀 Ergonomic Rust-first APIs
Installation
[]
= "0.5"
# optional features
= { = "0.5", = ["prompt", "logger", "figlet"] }
Feature Flags
| Feature | Enables |
|---|---|
prompt |
Interactive terminal prompts via inquire |
logger |
Styled stderr logging |
figlet |
ASCII banner rendering |
full |
All optional features (prompt, logger, figlet) |
Quick Start
use ;
Output:
Clean CLI rendering.
Output Formats
Supported render targets:
Format::PlainFormat::TextFormat::MarkdownFormat::JsonFormat::Jsonl
let ui = new.with_format;
Core Output Primitives
All output is composed with Output::new().
Titles and Headings
let output = new
.title
.subtitle
.heading
.paragraph;
Paragraphs, Lines, Lists
let output = new
.paragraph
.line
.list;
Ordered list:
.list
Separators
let output = new
.paragraph
.separator
.paragraph;
Code Blocks
let output = new
.code;
Plain Output
Use when your command should emit one scalar value for scripts or shell pipelines.
use ;
let ui = new.with_format;
let output = new.plain;
ui.print?;
Output:
hello
Supported scalar values:
- string
- number
- boolean
- null
Structured Data
Key / Value Data Map
Use top-level structured fields with .data(...).
let output = new
.data
.data;
Useful for JSON, Markdown summaries, and metadata.
JSON Block
let output = new
.json;
JSON Lines (JSONL)
Use jsonl_record(...) for streaming records or line-delimited events.
use ;
let ui = new.with_format;
let output = new
.jsonl_record
.jsonl_record;
ui.print?;
Output:
If no explicit records are provided, blocks can be emitted as JSONL entries.
Key / Value Blocks
Use for compact metadata sections.
let output = new
.key_value
.key_value;
Markdown:
- -
Text:
project: scriba
env: prod
Sequential calls are grouped automatically.
Definition Lists
Use for glossary-style output or descriptive labels.
let output = new
.definition
.definition;
Text:
Project:
scriba
Environment:
production
Status Messages
Use semantic states for results and summaries.
use ;
let output = new
.status
.status;
Available kinds:
StatusKind::InfoStatusKind::OkStatusKind::WarningStatusKind::Error
Tables
use ;
let table = new;
let output = new
.table;
Indexed Tables
Add row numbers automatically.
let table = new.with_index;
Custom header:
let table = new
.with_index_header;
Table Layouts
Control spacing, borders, and overall presentation with TableLayout:
TableLayout::Full(default): Bordered tables with full width and paddingTableLayout::Compact: Minimal spacing, no borders — dense displayTableLayout::Stacked: Key-value format per row — ideal for narrow terminals
use ;
let table = new
.with_layout;
let output = new.table;
Shorthand builders:
let table = new.with_layout_compact;
let table = new.with_layout_stacked;
let table = new.with_layout_full; // default
Stacked layout output:
Name: alpha
Value: 1
---
Name: beta
Value: 2
See cargo run --example table_layouts for all variants with and without index.
Text Styling
Apply semantic styles to text content: bold, italic, underline, strikethrough, and dim. Styles render format-appropriately (ANSI codes for Text, Markdown syntax, etc.).
use ;
let output = new
.styled_paragraph
.styled_paragraph
.styled_paragraph;
Available styles:
TextStyle::Bold— Strong emphasisTextStyle::Italic— EmphasisTextStyle::BoldItalic— CombinedTextStyle::Underline— UnderlinedTextStyle::Strikethrough—Crossed outTextStyle::Dim— Faded/dimmed
Direct rendering:
let styled = new;
// ANSI codes for Text format
println!;
// Markdown syntax
println!;
See cargo run --example styling for comprehensive examples.
Prompts (prompt feature)
use Ui;
Confirm
let proceed = ui.confirm?;
Select
use ;
let env = ui.select?;
Multi Select
use ;
let values = ui.multiselect?;
Pagination
Both SelectRequest and MultiSelectRequest support an optional page size for long option lists:
let env = ui.select?;
let targets = ui.multiselect?;
Theming
Customize prompt colors and styles with PromptTheme:
use ;
// Built-in themes
let ui_dark = new.with_prompt_theme;
let ui_light = new.with_prompt_theme;
let ui_mono = new.with_prompt_theme;
// Custom theme
let custom = default
.with_question_color
.with_selected_color
.with_input_color;
let ui = new.with_prompt_theme;
Available themes:
| Theme | Best For |
|---|---|
PromptTheme::default() |
Standard terminal colors |
PromptTheme::dark() |
Dark terminal backgrounds |
PromptTheme::light() |
Light terminal backgrounds |
PromptTheme::monochrome() |
Accessibility (no colors) |
Theme fields (all customizable):
question_color— Prompt textinput_color— User inputselected_color— Highlighted itemsunselected_color— Non-highlighted itemshint_color— Help textsuccess_color— Success messageserror_color— Error messages
Access the active theme:
let ui = new.with_prompt_theme;
let theme = ui.prompt_theme;
println!;
See cargo run --example prompt_theming --features prompt for all themes.
Envelope
Wrap any output in a JSON envelope with a configurable layout and optional
execution metadata. Enabled by setting EnvelopeMode::Json on the Ui.
Flat layout (default)
use ;
Output:
Nested layout
ok, format, and all metadata fields are merged under the meta key.
let ui = new
.with_format
.with_envelope;
ui.print_with_meta?;
Output:
Custom field names
use ;
let ui = new
.with_format
.with_envelope;
Meta
Meta carries optional structured context about the command invocation.
use Meta;
let meta = default
.with_command
.with_version
.with_scope
.with_duration_ms
.with_timestamp
.with_dry_run
.with_extra
.with_extra
.with_extra_map;
All fields are optional and omitted from the JSON output when not set.
Runnable examples
Logger (logger feature)
use Ui;
let ui = new;
ui.logger.info;
ui.logger.ok;
ui.logger.warn;
ui.logger.error;
ui.logger.detail;
ui.logger.debug;
ui.logger.trace;
ui.logger.kv;
Figlet (figlet feature)
use figlet;
let banner = render?;
println!;
Custom font:
let banner = render_with_font?;
Built-in fonts include:
standardsmallbigslantsmblockmono12futurewidetermmono9
Design Goals
scriba is built around:
- simple APIs first
- standard types where possible
- composable builders
- feature-gated integrations
- no macros required
Recommended Primitive by Use Case
| Need | Use |
|---|---|
| Single shell value | plain() |
| Human-readable report | headings + paragraphs |
| Metadata | key_value() |
| Glossary / labels | definition() |
| State / result | status() |
| Structured object | data() / json() |
| Event stream | jsonl_record() |
| Tabular data | table() |
| Numbered rows | with_index() |
| Table presentation | TableLayout |
| Text formatting | TextStyle + Styled |
| Prompt appearance | PromptTheme |
| JSON envelope | EnvelopeConfig |
| Execution metadata | Meta |
Roadmap
Backlog
- output streaming
- optional derive macros
License
MIT OR Apache-2.0