Rust Dependencies for pi-mono Feature Parity
Overview
This document maps the features from pi-mono’s TypeScript implementation to equivalent Rust crates for our TUI application.
Core TUI Framework
pi-mono: pi-tui (custom TypeScript)
Features:
- Differential rendering (only updates changed lines)
- Component-based architecture
- Viewport management with scrollback
- ANSI escape sequence safety
- Overlay system for modals/popups
Rust Equivalent:
ratatui = "0.30"
crossterm = "0.29" # Backend for ratatui
Notes:
- ✅ ratatui has built-in differential rendering
- ✅ Component system via Widget trait
- ✅ Viewport management included
- ✅ ANSI safety handled by crossterm
Text Editor / Input
pi-mono: Custom editor in pi-tui
Features:
- Multi-line text input
- Cursor movement
- Syntax highlighting integration
- Vim-style or Emacs keybindings
- Text selection
Rust Options:
Option 1: Basic input (built-in)
ratatui = "0.30" # Has TextArea widget
Option 2: Enhanced editor
# Vim-like editor
edtui = "0.11"
# OR
tui-textarea = "0.4"
# OR
ratatui-code-editor = "0.0.1" # Tree-sitter powered
Recommendation: Start with ratatui’s built-in TextArea, upgrade to edtui or ratatui-code-editor if we need vim bindings or advanced editing.
Markdown Rendering
pi-mono: marked (TypeScript library)
Features:
- Parse markdown to styled terminal output
- Support for headings, lists, code blocks, links
- Custom rendering for AI responses
Rust Equivalent:
tui-markdown = "0.3"
pulldown-cmark = "0.13" # Underlying parser
Alternative (more comprehensive):
md-tui = "0.9" # Full markdown viewer with navigation
Notes:
- tui-markdown converts markdown to ratatui Text values
- Supports all standard markdown features
- Can customize styling for AI output
Syntax Highlighting
pi-mono: Custom integration with highlighting
Features:
- Code block syntax highlighting
- Multiple language support
- Theme support
Rust Equivalent:
syntect = "5.3" # Core syntax highlighting
syntect-tui = "3.0" # Bridge to ratatui styles
Alternative (tree-sitter based):
tui-syntax = "0.4" # Tree-sitter based
tree-sitter = "0.24" # Parser framework
Notes:
- syntect uses Sublime Text syntax definitions (high quality)
- 100+ languages supported out of the box
- syntect-tui converts syntect styles to ratatui Styles
File Tree / Navigation
pi-mono: Tree selector for sessions and files
Features:
- Hierarchical tree view
- Collapsible/expandable nodes
- Keyboard navigation
- File icons/indicators
Rust Equivalent:
tui-tree-widget = "0.24"
# OR
ratatui-explorer = "0.2"
Notes:
- tui-tree-widget: Pure tree widget for any tree data
- ratatui-explorer: File explorer specifically (like ranger)
Diff Viewing
pi-mono: File diff display for code changes
Features:
- Side-by-side or unified diff
- Syntax highlighting in diffs
- Color-coded additions/deletions
- Line numbers
Rust Equivalent:
# Option 1: Use syntect with custom diff logic
syntect = "5.3"
# Option 2: Leverage delta (pager)
# Shell out to delta or integrate as library
Implementation approach:
#![allow(unused)]
fn main() {
// Parse diff output
// Use syntect to highlight each line
// Apply ratatui styles for additions (green) / deletions (red)
}
Clipboard Integration
pi-mono: Clipboard access for copy/paste
Features:
- Copy text to system clipboard
- Paste from clipboard
- Cross-platform support
Rust Equivalent:
arboard = "3.6"
Notes:
- Cross-platform (Linux X11/Wayland, macOS, Windows)
- Supports both text and images
- 1Password maintains this crate (high quality)
Async / Streaming
pi-mono: Event-driven with async/await
Features:
- Handle multiple async events
- Stream LLM responses
- Non-blocking UI updates
- Event queue/channels
Rust Equivalent:
tokio = { version = "1", features = ["full"] }
tokio-stream = "0.1"
futures = "0.3"
async-trait = "0.1"
Pattern:
#![allow(unused)]
fn main() {
// Event loop with tokio
let (tx, mut rx) = tokio::sync::mpsc::unbounded_channel();
// Spawn async task for events
tokio::spawn(async move {
while let Some(event) = rx.recv().await {
// Handle event
}
});
}
Configuration Management
pi-mono: YAML/JSON config files
Features:
- User config in ~/.config/pi/
- Project-level config
- Environment variable overrides
- Theme configuration
Rust Equivalent:
config = "0.15" # Layered config (file, env, etc.)
toml = "0.9" # TOML parsing
serde = { version = "1.0", features = ["derive"] }
directories = "5" # XDG dirs (cross-platform)
Alternative (more powerful):
figment = "0.10" # Used by Rocket, very flexible
Notes:
- config crate: Supports TOML, YAML, JSON, INI
- directories: Gets platform-appropriate config dirs
- XDG on Linux, ~/Library/Application Support on macOS, %APPDATA% on Windows
HTTP / LLM API
pi-mono: pi-ai (unified LLM API)
Features:
- Multiple provider support (OpenAI, Anthropic, etc.)
- Streaming responses
- Retry logic
- Authentication
Rust Equivalent:
reqwest = { version = "0.12", features = ["json", "stream"] }
tokio = "1"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
For specific providers:
async-openai = "0.26" # If using OpenAI specifically
Custom trait approach (recommended):
#![allow(unused)]
fn main() {
#[async_trait]
trait LlmProvider {
async fn complete(&self, request: Request) -> Result<Response>;
async fn stream(&self, request: Request) -> Result<Stream<Item=Token>>;
}
}
Themes
pi-mono: Theme system with JSON themes
Features:
- Custom color schemes
- User-defined themes
- Syntax highlighting themes
- Terminal color detection
Rust Equivalent:
ratatui = "0.30" # Has Style system
syntect = "5.3" # Has theme support for syntax
For theme loading:
serde = { version = "1.0", features = ["derive"] }
toml = "0.9" # Or json, yaml
Implementation:
#![allow(unused)]
fn main() {
#[derive(Deserialize)]
struct Theme {
background: Color,
foreground: Color,
accent: Color,
// ...
}
}
Key Bindings / Input
pi-mono: Custom keyboard protocol
Features:
- Vim-style keybindings
- Command palette (/ commands)
- Configurable shortcuts
- Key sequences (chords)
Rust Equivalent:
crossterm = "0.29" # Has key event handling
For complex keybindings:
#![allow(unused)]
fn main() {
// crossterm provides KeyEvent, KeyCode, KeyModifiers
// Build a keymap system on top
enum Action {
SendMessage,
NewConversation,
Quit,
// ...
}
struct KeyMap {
bindings: HashMap<(KeyCode, KeyModifiers), Action>,
}
}
State Management
pi-mono: Agent state management
Features:
- Conversation history
- Context management
- Tool state
- Session persistence
Rust Equivalent:
# In-memory: Standard Rust
# Persistence:
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
# Database (optional):
sqlx = { version = "0.8", features = ["runtime-tokio", "sqlite"] }
# OR for simpler use:
redb = "2.0" # Pure Rust embedded DB
Complete Cargo.toml
[package]
name = "harness-tui"
version = "0.1.0"
edition = "2021"
[dependencies]
# Core TUI
ratatui = { version = "0.30", features = ["crossterm"] }
crossterm = "0.29"
# Editor
edtui = "0.11" # Optional: for vim bindings
# Markdown
tui-markdown = "0.3"
pulldown-cmark = "0.13"
# Syntax highlighting
syntect = "5.3"
syntect-tui = "3.0"
# File tree
tui-tree-widget = "0.24"
# Clipboard
arboard = "3.6"
# Async
tokio = { version = "1", features = ["full"] }
tokio-stream = "0.1"
futures = "0.3"
async-trait = "0.1"
# HTTP
reqwest = { version = "0.12", features = ["json", "stream", "rustls-tls"] }
# Config
config = "0.15"
toml = "0.9"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
directories = "5"
# Persistence (optional)
redb = "2.0"
# Error handling
color-eyre = "0.6" # Better error reporting
thiserror = "1.0"
# Logging
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
# CLI
clap = { version = "4.5", features = ["derive"] }
# Utilities
unicode-width = "0.2"
textwrap = "0.16"
chrono = { version = "0.4", features = ["serde"] }
[dev-dependencies]
tokio-test = "0.4"
Feature Comparison Summary
| Feature | pi-mono | robit (Rust) |
|---|---|---|
| TUI Framework | Custom pi-tui | ratatui |
| Differential Rendering | ✅ Custom | ✅ Built-in |
| Text Editor | Custom | edtui / ratatui-code-editor |
| Markdown | marked | tui-markdown |
| Syntax Highlighting | Custom | syntect + syntect-tui |
| File Tree | Custom | tui-tree-widget |
| Diff Viewing | Custom | syntect + custom |
| Clipboard | Native | arboard |
| Async | Node.js async | tokio |
| Config | YAML/JSON | toml + config |
| HTTP | Node fetch | reqwest |
| Themes | JSON | toml + serde |
| State | In-memory | redb / sqlite |
Advantages of Rust Stack
- Type Safety: Compile-time guarantees for all UI state
- Performance: Zero-cost abstractions, no GC pauses
- Single Binary: No Node.js runtime dependency
- Memory Safety: No null pointer exceptions or undefined behavior
- Ecosystem: Cross-platform native performance
Development Workflow
# Add dependencies
cargo add ratatui crossterm tokio serde reqwest
# Development
cargo run # Run TUI
cargo test # Run tests
cargo clippy # Lint
cargo build --release # Optimized build
# Single binary output: target/release/harness-tui
No npm install. No node_modules. No webpack.
Just Rust.