eye-declare #

A declarative, React-like TUI rendering library for Rust, built on Ratatui.

eye-declare provides a component model for building terminal UIs that render inline — content grows into the terminal's native scrollback rather than taking over the full screen. Designed for CLI tools, AI assistants, and interactive prompts where output accumulates and earlier results should remain visible.

use eye_declare::{element, Application, Elements, Spinner, TextBlock};
struct AppState {
messages: Vec<String>,
thinking: bool,
}
fn chat_view(state: &AppState) -> Elements {
element! {
#(for msg in &state.messages {
TextBlock {
Line { Span(text: msg.clone()) }
}
})
#(if state.thinking {
Spinner(key: "thinking", label: "Thinking...")
})
}
}
#[tokio::main]
async fn main() -> std::io::Result<()> {
let (mut app, handle) = Application::builder()
.state(AppState { messages: vec![], thinking: false })
.view(chat_view)
.build()?;
tokio::spawn(async move {
handle.update(|s| s.messages.push("Hello from eye-declare!".into()));
});
app.run().await
}

Key features #

  • Inline rendering — content grows downward into terminal scrollback, like normal CLI output
  • React-like component model — props, state, reconciliation, and lifecycle hooks
  • element! macro — JSX-like syntax for composing component trees
  • Automatic dirty tracking — only changed components re-render
  • Frame diffing — minimal ANSI output, no tearing
  • Async-firstHandle sends updates from any thread or async task

Get started #

Learn #

Reference #

Status #

eye-declare is in early development — expect breaking changes before 1.0.

License #

MIT