GitHub - jake-stewart/tuie: A rich, performant TUI library for Rust. · GitHub
/" data-turbo-transient="true" />
Skip to content
Search or jump to...
Search code, repositories, users, issues, pull requests...
-->
Search
Clear
Search syntax tips
Provide feedback
--><br>We read every piece of feedback, and take your input very seriously.
Include my email address so I can be contacted
Cancel
Submit feedback
Saved searches
Use saved searches to filter your results more quickly
-->
Name
Query
To see all available qualifiers, see our documentation.
Cancel
Create saved search
Sign in
/;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up
Appearance settings
Resetting focus
You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.
Dismiss alert
{{ message }}
jake-stewart
tuie
Public
Notifications<br>You must be signed in to change notification settings
Fork
Star<br>10
main
BranchesTags
Go to file
CodeOpen more actions menu
Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit
History<br>3 Commits<br>3 Commits
chord_macro
chord_macro
src
src
.gitignore
.gitignore
Cargo.toml
Cargo.toml
LICENSE
LICENSE
readme.md
readme.md
View all files
Repository files navigation
tuie
A rich, performant TUI library for Rust.
demo.mp4
Features
Layout: Flexbox, grids, splits, and virtualized lists, all with min, max, and preferred-size constraints.
Images: Kitty with sixel and half-block fallbacks, all working over SSH and tmux passthrough.
Input: Iterator-based extensible text input with vi, emacs, modern, and custom bindings.
Harmonious: Generated 256-color palette, consistent with user's base16 theme, zero config.
Chords: Construct and match on human readable inputs: chord!(Ctrl + Arrow(Up | Down))
Async: Timers and async callbacks with support for any async runtime.
Performance: Per subtree/widget/cell dirty tracking, batched queries, shared memory graphics, packed structs.
GUI: Optionally run as a GUI with box-drawing, smooth scrolling.
Getting started
Install:
cargo add tuie --features=harmonious
Write your main:
std::io::Result {<br>let root = Pane::new()<br>.border(Border::SINGLE)<br>.child(Text::new().content("hello world"));<br>tuie::start_tui(root)<br>}">use tuie::prelude::*;<br>use std::process::ExitCode;
fn main() -> std::io::ResultExitCode> {<br>let root = Pane::new()<br>.border(Border::SINGLE)<br>.child(Text::new().content("hello world"));<br>tuie::start_tui(root)
Run:
cargo run
Constructing widgets
Chain builders to create a simple widget tree:
Box {<br>Pane::new()<br>.border(Border::SINGLE)<br>.child(Text::new().content(format!("hello {name}")))<br>}">fn greeting(name: String) -> BoxPane> {<br>Pane::new()<br>.border(Border::SINGLE)<br>.child(Text::new().content(format!("hello {name}")))
Or compose widgets together for something more complicated:
text_id: WidgetId,
impl Greeting {<br>fn new(name: &str) -> Box {<br>let mut text_id = WidgetId::EMPTY;<br>let root = Pane::new().border(Border::SINGLE).child(<br>Text::new().content(format!("hello {name}")).id(&mut text_id)<br>);<br>Box::new(Self { root, text_id })
fn set_name(&mut self, name: &str) {<br>if let Some(text) = self.root.get_widget_mut(self.text_id) {<br>text.set_content(format!("hello {name}"));
impl DelegateWidget for Greeting {<br>tuie::delegate_widget!(root);
fn override_on_input(&mut self, queue: &mut InputQueue) -> InputResult {<br>// you can override or react to your root widget's events and methods<br>// using after_* and override_*.<br>return self.root.on_input(queue);<br>}">struct Greeting {<br>root: BoxPane>,<br>text_id: WidgetIdText>,
impl Greeting {<br>fn new(name: &str) -> BoxSelf> {<br>let mut text_id = WidgetId::EMPTY;<br>let root = Pane::new().border(Border::SINGLE).child(<br>Text::new().content(format!("hello {name}")).id(&mut text_id)<br>);<br>Box::new(Self { root, text_id })
fn set_name(&mut self, name: &str) {<br>if let Some(text) = self.root.get_widget_mut(self.text_id) {<br>text.set_content(format!("hello {name}"));
impl DelegateWidget for Greeting {<br>tuie::delegate_widget!(root);
fn override_on_input(&mut self, queue: &mut InputQueue) -> InputResult {<br>// you can override or react to your root widget's events and methods<br>// using after_* and override_*.<br>return self.root.on_input(queue);
You can also impl Widget yourself, which is how all of the default widgets are implemented.
Examples
tuie-demo: discoverable, interactive reference covering most widgets and features.
fz: fuzzy finder built on tuie, a real-world example of a non-trivial application.
Feature flags
harmonious — enables Lab-space palette generation from the terminal's base16 colors.
images — enables the Image widget and ImageConfig/ImageProtocol/ImageSource types; pulls in the image crate.
gui — enables start_gui and the gui module; pulls in winit, wgpu, pollster, fontdb, and freetype-rs (plus objc2 on macOS). Implies...