Expand description
§Envision
A ratatui framework for building TUI applications with first-class support for both interactive terminal use and programmatic control (AI agents, automation, testing).
§Two Runtime Modes
Envision provides two distinct ways to run your application:
§Terminal Mode - For Interactive Use
ⓘ
// requires real terminal
#[tokio::main]
async fn main() -> envision::Result<()> {
let _final_state = Runtime::<MyApp>::new_terminal()?.run_terminal().await?;
Ok(())
}Or without your own tokio runtime:
ⓘ
// requires real terminal
fn main() -> envision::Result<()> {
let _final_state = Runtime::<MyApp>::new_terminal()?.run_terminal_blocking()?;
Ok(())
}§Virtual Terminal Mode - For Programmatic Control
// Create a virtual terminal
let mut vt = Runtime::<MyApp, _>::virtual_terminal(80, 24)?;
// Inject events programmatically
vt.send(Event::key(KeyCode::Char('j')));
vt.tick()?;
// Inspect the display
println!("{}", vt.display());The same application code works in both modes - your App implementation
doesn’t need to know which mode it’s running in.
§The Elm Architecture (TEA)
Envision uses The Elm Architecture pattern:
- State: Your application’s data model
- Message: Events that can update state
- Update: Pure function that produces new state from old state + message
- View: Pure function that renders state to the UI
use envision::prelude::*;
struct MyApp;
#[derive(Default, Clone)]
struct MyState;
#[derive(Clone)]
enum MyMsg {}
impl App for MyApp {
type State = MyState;
type Message = MyMsg;
fn init() -> (Self::State, Command<Self::Message>) {
(MyState, Command::none())
}
fn update(state: &mut Self::State, msg: Self::Message) -> Command<Self::Message> {
Command::none()
}
fn view(state: &Self::State, frame: &mut Frame) {
// Render UI
}
}§Features
- Capture rendered frames as inspectable text or structured data
- Track frame history and compute diffs between renders
- Annotate widgets with semantic information for accessibility and testing
- Inject events programmatically for automation and AI agents
- Async support with tokio integration for subscriptions and commands
- Component library with common UI elements (buttons, inputs, lists, etc.)
- Theming support for consistent styling
Re-exports§
pub use adapter::DualBackend;pub use adapter::DualBackendBuilder;pub use annotation::Annotate;pub use annotation::Annotation;pub use annotation::AnnotationRegistry;pub use annotation::WidgetType;pub use app::load_state;pub use app::batch;pub use app::interval_immediate;pub use app::terminal_events;pub use app::tick;pub use app::App;pub use app::BatchSubscription;pub use app::BoxedSubscription;pub use app::ChannelSubscription;pub use app::Command;pub use app::CommandHandler;pub use app::DebounceSubscription;pub use app::FilterSubscription;pub use app::FnUpdate;pub use app::IntervalImmediateBuilder;pub use app::IntervalImmediateSubscription;pub use app::MappedSubscription;pub use app::Runtime;pub use app::RuntimeConfig;pub use app::StateExt;pub use app::StreamSubscription;pub use app::Subscription;pub use app::SubscriptionExt;pub use app::TakeSubscription;pub use app::TerminalEventSubscription;pub use app::TerminalHook;pub use app::TerminalRuntime;pub use app::ThrottleSubscription;pub use app::TickSubscription;pub use app::TickSubscriptionBuilder;pub use app::TimerSubscription;pub use app::UnboundedChannelSubscription;pub use app::Update;pub use app::UpdateResult;pub use app::VirtualRuntime;pub use backend::CaptureBackend;pub use backend::EnhancedCell;pub use backend::FrameSnapshot;pub use component::Component;pub use component::Disableable;pub use component::FocusManager;pub use component::Focusable;pub use component::Toggleable;pub use component::Button;pub use component::ButtonMessage;pub use component::ButtonOutput;pub use component::ButtonState;pub use component::Checkbox;pub use component::CheckboxMessage;pub use component::CheckboxOutput;pub use component::CheckboxState;pub use component::Dropdown;pub use component::DropdownMessage;pub use component::DropdownOutput;pub use component::DropdownState;pub use component::InputField;pub use component::InputFieldMessage;pub use component::InputFieldOutput;pub use component::InputFieldState;pub use component::LineInput;pub use component::LineInputMessage;pub use component::LineInputOutput;pub use component::LineInputState;pub use component::RadioGroup;pub use component::RadioGroupMessage;pub use component::RadioGroupOutput;pub use component::RadioGroupState;pub use component::Select;pub use component::SelectMessage;pub use component::SelectOutput;pub use component::SelectState;pub use component::TextArea;pub use component::TextAreaMessage;pub use component::TextAreaOutput;pub use component::TextAreaState;pub use component::Column;pub use component::ItemState;pub use component::LoadingList;pub use component::LoadingListItem;pub use component::LoadingListMessage;pub use component::LoadingListOutput;pub use component::LoadingListState;pub use component::SelectableList;pub use component::SelectableListMessage;pub use component::SelectableListOutput;pub use component::SelectableListState;pub use component::SortDirection;pub use component::Table;pub use component::TableMessage;pub use component::TableOutput;pub use component::TableRow;pub use component::TableState;pub use component::Tree;pub use component::TreeMessage;pub use component::TreeNode;pub use component::TreeOutput;pub use component::TreeState;pub use component::format_eta;pub use component::KeyHint;pub use component::KeyHints;pub use component::KeyHintsLayout;pub use component::KeyHintsMessage;pub use component::KeyHintsState;pub use component::MultiProgress;pub use component::MultiProgressMessage;pub use component::MultiProgressOutput;pub use component::MultiProgressState;pub use component::ProgressBar;pub use component::ProgressBarMessage;pub use component::ProgressBarOutput;pub use component::ProgressBarState;pub use component::ProgressItem;pub use component::ProgressItemStatus;pub use component::ScrollableText;pub use component::ScrollableTextMessage;pub use component::ScrollableTextOutput;pub use component::ScrollableTextState;pub use component::Section;pub use component::Spinner;pub use component::SpinnerMessage;pub use component::SpinnerState;pub use component::SpinnerStyle;pub use component::StatusBar;pub use component::StatusBarItem;pub use component::StatusBarItemContent;pub use component::StatusBarMessage;pub use component::StatusBarState;pub use component::StatusBarStyle;pub use component::StatusLog;pub use component::StatusLogEntry;pub use component::StatusLogLevel;pub use component::StatusLogMessage;pub use component::StatusLogOutput;pub use component::StatusLogState;pub use component::StyledText;pub use component::StyledTextMessage;pub use component::StyledTextOutput;pub use component::StyledTextState;pub use component::TitleCard;pub use component::TitleCardMessage;pub use component::TitleCardState;pub use component::Toast;pub use component::ToastItem;pub use component::ToastLevel;pub use component::ToastMessage;pub use component::ToastOutput;pub use component::ToastState;pub use component::Accordion;pub use component::AccordionMessage;pub use component::AccordionOutput;pub use component::AccordionPanel;pub use component::AccordionState;pub use component::Breadcrumb;pub use component::BreadcrumbMessage;pub use component::BreadcrumbOutput;pub use component::BreadcrumbSegment;pub use component::BreadcrumbState;pub use component::Menu;pub use component::MenuItem;pub use component::MenuMessage;pub use component::MenuOutput;pub use component::MenuState;pub use component::Router;pub use component::RouterMessage;pub use component::RouterOutput;pub use component::RouterState;pub use component::StepIndicator;pub use component::StepIndicatorMessage;pub use component::StepIndicatorOutput;pub use component::StepIndicatorState;pub use component::Tabs;pub use component::TabsMessage;pub use component::TabsOutput;pub use component::TabsState;pub use component::ConfirmDialog;pub use component::ConfirmDialogMessage;pub use component::ConfirmDialogOutput;pub use component::ConfirmDialogResult;pub use component::ConfirmDialogState;pub use component::Dialog;pub use component::DialogButton;pub use component::DialogMessage;pub use component::DialogOutput;pub use component::DialogState;pub use component::Tooltip;pub use component::TooltipMessage;pub use component::TooltipOutput;pub use component::TooltipPosition;pub use component::TooltipState;pub use error::BoxedError;pub use error::EnvisionError;pub use error::Result;pub use harness::AppHarness;pub use harness::Assertion;pub use harness::Snapshot;pub use harness::TestHarness;pub use input::Event;pub use input::EventQueue;pub use overlay::Overlay;pub use overlay::OverlayAction;pub use overlay::OverlayStack;pub use theme::Theme;
Modules§
- adapter
- Dual adapter for simultaneous real and capture backends.
- annotation
- Widget annotation system for semantic UI understanding.
- app
- TEA (The Elm Architecture) application framework.
- backend
- Backend module providing the
CaptureBackendimplementation. - component
- Composable UI components for TUI applications.
- error
- Error types for the Envision framework.
- harness
- Test harness for headless TUI testing.
- input
- Input module for terminal events.
- layout
- Layout utilities and re-exports.
- overlay
- Overlay/modal abstraction for TUI applications.
- prelude
- Prelude module for convenient imports.
- style
- Style types and re-exports.
- theme
- Theming support for Envision components.
- util
- Utility functions for TUI rendering.