Expand description
Scrin is a Rust terminal UI toolkit for building polished command-line interfaces without depending on Ratatui.
It provides a Scrin-native rendering model with buffers, colors, rectangles,
layout constraints, styled text, widgets, panes, overlays, command palettes,
status bars, input routing, terminal lifecycle helpers, and animation glue.
The effects layer is powered by aisling
and adapts Aisling frames into Scrin buffers, so loaders and text effects can
be composed with normal Scrin widgets.
§Install
[dependencies]
scrin = "0.1.81"§Draw A Widget
use scrin::core::buffer::Buffer;
use scrin::core::color::Color;
use scrin::core::rect::Rect;
use scrin::style::Style;
use scrin::widgets::block::Block;
use scrin::widgets::Widget;
let mut buffer = Buffer::new(40, 8);
buffer.fill(Rect::new(0, 0, 40, 8), ' ', Color::WHITE, None);
let block = Block::bordered()
.title("scrin")
.border_style(Style::new().fg(Color::CYAN));
block.render(&mut buffer, Rect::new(0, 0, 40, 8));§Render An Aisling Effect Into A Scrin Buffer
use scrin::core::{buffer::Buffer, rect::Rect};
use scrin::effects::{EffectKind, EffectPlayer};
let mut buffer = Buffer::new(60, 6);
let mut effect = EffectPlayer::new(EffectKind::Matrix, "Scrin + Aisling")
.with_size(60, 6)
.with_duration(24);
effect.render_to_buffer(&mut buffer, Rect::new(0, 0, 60, 6));
effect.advance();§Render An Aisling Loader
use scrin::core::{buffer::Buffer, rect::Rect};
use scrin::effects::{LoaderKind, LoaderPlayer};
let mut buffer = Buffer::new(48, 4);
let loader = LoaderPlayer::new(LoaderKind::Bar)
.with_size(48, 4)
.with_label("indexing".to_string());
let progress = LoaderPlayer::progress_from_fraction(0.42);
loader.render(3, progress, &mut buffer, Rect::new(0, 0, 48, 4));§Terminal Rendering
Terminal::draw uses Scrin’s diff presenter and updates only changed
cells. Terminal::draw_full is available when an application wants a full
buffer repaint every frame, for example during dense animation.
§Re-Exports
Common Aisling selector/config types are re-exported from effects so a
Scrin application can choose effects and loaders through one crate path.
§Performance APIs
Larger Scrin applications can use widgets::ScrollableText for retained
styled-text wrapping, widgets::RetainedMarkdownOutput for cached Markdown
rows, retained Aisling widgets through effects::RetainedEffectWidget and
effects::RetainedLoaderWidget, dirty-rectangle presentation through
Terminal::present_areas, strategy-based drawing through
Terminal::draw_with_present_strategy, cursor-preserving area draws through
Terminal::draw_area_preserve_cursor_timed, frame diagnostics through
FrameTiming / FrameDiagnostic / NamedFrameTiming, and shared widget
roles through ThemeTokens. Retained Aisling hot paths can use
effects::RetainedEffectWidget::render_frame_into and
effects::RetainedEffectWidget::render_cached_only to avoid mutating widget
state or doing unexpected cache rebuild work.
§Application Validation
Full-screen applications should pair Scrin’s crate-level tests with app-level pseudo-terminal captures for frame output, prompt input, overlays, provider setup, and terminal restore paths. A real-terminal visual pass is still useful for subjective clipping, spacing, contrast, and animation pacing.
Re-exports§
pub use animation::Timeline;pub use command_palette::CommandPalette;pub use core::buffer::Buffer;pub use core::color::Color;pub use core::rect::Rect;pub use effects::EffectPlayer;pub use effects::RetainedEffectCacheKey;pub use effects::RetainedEffectWidget;pub use effects::RetainedLoaderWidget;pub use flow_manager::FlowManager;pub use input::EventRouter;pub use layout::Layout;pub use overlays::Modal;pub use overlays::Toast;pub use panes::Pane;pub use panes::PaneManager;pub use scroll_state::ScrollState;pub use scroll_state::StickyScroll;pub use status_bar::StatusBar;pub use style::Style;pub use terminal::Frame;pub use terminal::FrameDiagnostic;pub use terminal::FrameTiming;pub use terminal::NamedFrameTiming;pub use terminal::PresentStrategy;pub use terminal::Terminal;pub use terminal::TerminalOptions;pub use text_expander::TextExpander;pub use theme::Theme;pub use theme::ThemeTokens;