photon-ui
A blazing fast, minimal terminal UI framework for Rust.
Photon UI is a lightweight, high-performance TUI library built on crossterm. It features a custom differential renderer that only redraws what changed, ANSI-aware text wrapping, OSC 8 hyperlink support, terminal image rendering (Kitty and iTerm2 protocols), and a component-based architecture.
Features
- Differential renderer — Only updates cells that changed between frames, minimizing terminal output and improving performance.
- Component-based architecture — Build UIs by composing simple, reusable
Componenttrait implementations. - Built-in components — Text, truncated text, boxes, spacers, input fields, multi-line editors, select lists, settings toggles, loaders, markdown, and image widgets.
- Dual editing modes — Both Emacs and vim keybindings for
InputandEditorcomponents, switchable at runtime. - Terminal image support — Render images inline using the Kitty graphics protocol or iTerm2 inline images.
- ANSI-aware text handling — Properly measures and wraps text containing ANSI escape sequences, Unicode, and grapheme clusters.
- Overlays — Position floating content with anchor-based constraints (center, top-left, bottom-right, etc.).
- Focus management — The
TUIruntime handles focus cycling and routes input events to the focused component. - Zero unnecessary dependencies — Core functionality relies only on
crossterm,unicode-width,unicode-segmentation,pulldown-cmark,base64, andthiserror.
Quick start
Add photon-ui to your Cargo.toml:
[]
= "0.1"
Build a simple app:
use ;
use Text;
let mut tui = TUInew;
tui.mount;
tui.render_frame.unwrap;
For a real application, use ProcessTerminal to drive the actual terminal:
use ;
use ProcessTerminal;
use ;
use Duration;
Components
| Component | Description |
|---|---|
Text |
Static text with optional horizontal and vertical padding. |
TruncatedText |
Text that truncates with an ellipsis when wider than the container. |
Box |
A container with configurable vertical padding and optional background styling. |
Spacer |
Empty vertical space. |
Input |
Single-line text input with Emacs and vim modes, kill-ring, and undo. |
Editor |
Multi-line text editor with Emacs and vim modes, kill-ring, and undo. |
SelectList |
Scrollable list with keyboard navigation and selection. |
SettingsList |
Toggle list for boolean settings. |
Loader |
Animated spinner with optional colored message. |
CancellableLoader |
Spinner that can be cancelled via Ctrl+C. |
Markdown |
Renders CommonMark markdown (headings, bold, italic, inline code). |
ImageWidget |
Displays images inline via Kitty or iTerm2 graphics protocols. |
Architecture
Component trait
Every visible element implements the Component trait:
renderproduces the lines of text (and optional cursor or image commands) for the current frame.handle_inputreceives events when the component has focus.Focusablecomponents participate in the tab order managed byTUI.
Renderer
The Renderer tracks the previous frame and computes a minimal set of cursor movements and writes needed to update the terminal. This avoids clearing the screen or redrawing unchanged content.
TUI runtime
TUI owns the terminal backend, manages a stack of components, handles focus cycling (Tab / Shift+Tab), and supports overlays positioned with Anchor and OverlayConstraints.
Input modes
Both Input and Editor support Emacs and vim editing styles:
| Emacs | Vim | Action |
|---|---|---|
Ctrl+A |
0 or ^ |
Move to start of line |
Ctrl+E |
$ |
Move to end of line |
Ctrl+K |
D |
Kill to end of line |
Ctrl+Y |
p |
Yank (paste) |
Ctrl+W |
daw |
Kill word |
Ctrl+F / Ctrl+B |
l / h |
Move forward / backward |
| — | i / Esc |
Enter / exit insert mode |
Enable vim mode at construction time or toggle it at runtime with set_vim_mode_enabled.
Running the demo
The included demo showcases every component across four pages:
Controls:
| Key | Action |
|---|---|
1–4 |
Switch demo page |
Tab / Shift+Tab |
Cycle focus |
q or Ctrl+C |
Quit |