TUI-First Architecture
Philosophy
Unlike traditional web-first LLM tools (ChatGPT, Claude web interface), robit embraces a terminal-native workflow. The interface should feel like a natural extension of the command line—fast, keyboard-driven, and composable with existing Unix tooling.
Why TUI-First?
Developer Experience:
- Speed: No browser overhead, instant startup
- Keyboard-centric: Vim-like bindings, no mouse required
- Composability: Pipe to/from other CLI tools
- Context preservation: Stay in your terminal environment
Inspiration:
opencode: Excellent TUI workflow for AI interactionlazygit: Git operations without leaving the terminalk9s: Kubernetes management via TUIranger: File management with vim bindings
Dual-Target Strategy
The architecture supports two deployment targets from a single codebase:
1. Native Terminal Application
Runs directly in any terminal emulator:
- Direct terminal control via crossterm
- Full clipboard integration
- Native file system access
- Can spawn subprocesses
- SSH-friendly (works over remote connections)
2. WebAssembly Browser Application
Compiles to WASM and runs in browser:
- Compiled to WASM via ratzilla
- Terminal aesthetic in the browser
- Accessible from any device
- Easy sharing of conversations
- Sandboxed execution (for code)
Shared Core Architecture
The application logic is target-agnostic:
#![allow(unused)]
fn main() {
// Shared core crate - platform agnostic
pub mod core {
pub struct Conversation { ... }
pub struct Message { ... }
pub trait LlmProvider { ... }
// Business logic knows nothing about rendering
pub async fn process_message(
conversation: &mut Conversation,
message: &str,
llm: &dyn LlmProvider,
) -> Result<Message, Error> { ... }
}
}
Component Breakdown
Core Components (Shared)
-
Conversation Engine
- Message history management
- Context window optimization
- Token counting
- Conversation branching
-
LLM Provider Abstraction
- Trait-based providers
- OpenAI, Anthropic, local models
- Streaming response handling
- Retry and circuit breaker logic
-
Tool System
- Tool definition registry
- Schema validation
- Execution coordination
- Result formatting
TUI Components (Native)
-
Main Interface
- Conversation list sidebar
- Message view (markdown rendering)
- Input area with multiline support
- Status bar
-
Input Handling
- Vim-style navigation
- Command palette (
:commands) - Keyboard shortcuts
- Copy/paste integration
Web Components (WASM)
-
Browser Integration
- LocalStorage for settings
- IndexedDB for conversation history
- Clipboard API
- File download/upload
-
UI Adaptations
- Responsive layout
- Touch support
- URL routing (conversation IDs)
- Browser history integration
Data Synchronization
When both native and web versions are used:
Sync strategies:
- File-based: Export/import JSON
- Git-based: Store conversations in git repo
- Cloud sync: Self-hosted or third-party
- Local network: Peer discovery and sync
Comparison with Zellij
What Zellij Offers
Zellij is a terminal multiplexer with a WASM plugin system:
- Plugins run inside Zellij’s WASM runtime
- Can draw UI within a pane
- Access to Zellij APIs (panes, tabs, etc.)
- Written in any WASM-compatible language
Should robit be a Zellij Plugin?
Pros:
- Instant integration with existing Zellij users
- Fits naturally in terminal workflow
- Can control terminal environment
- No separate binary to install
Cons:
- Dependency on Zellij (not standalone)
- Plugin API limitations
- Can’t be used outside Zellij
- Web deployment would be separate codebase
Verdict: Build standalone first, consider Zellij plugin later
The standalone TUI provides:
- Broader compatibility (any terminal)
- Web deployment via WASM
- Simpler distribution
- Can still detect and integrate with Zellij if present
Implementation Strategy
Phase 1: Core + Native TUI
Focus on the terminal experience:
crates/
├── robit-core/ # Shared logic
├── robit-tui/ # Native terminal app
└── robit-cli/ # Command-line interface
Target: Excellent terminal experience that rivals opencode
Phase 2: WebAssembly Port
Add web target:
crates/
├── robit-core/ # Shared logic
├── robit-tui/ # Native terminal app
├── robit-web/ # WASM browser app (ratzilla)
└── robit-cli/ # Command-line interface
Target: Same features in browser, conversation sync
Phase 3: Advanced Features
- Collaborative editing
- Rich media support
- Plugin system
- Zellij integration (optional plugin)
Technology Choices
TUI Framework: Ratatui
Why Ratatui:
- Mature, actively maintained
- Excellent performance
- Rich widget ecosystem
- Works with both native and WASM (via ratzilla)
- Strong community (part of ratatui-rs organization)
Backend Strategy:
- Native:
crosstermbackend - Web:
ratzillabackend (uses DOM elements)
WASM Stack
Web Application
├── ratzilla (TUI rendering to DOM)
├── ratatui (widgets, layout, style)
├── wasm-bindgen (JS interop)
└── compiled Rust (WASM)
Build tools:
trunk: WASM build and dev serverwasm-bindgen: Rust/JS bindingswasm-pack: Package for npm distribution
Alternative: Native + Web Server
Instead of WASM, another approach is TUI connecting to a local server:
Pros:
- Single codebase (no WASM complications)
- Server can run remotely
- Better for multi-user scenarios
Cons:
- Requires server to be running
- More complex deployment
- Latency for local usage
Decision: Start with WASM approach for personal use cases, consider server architecture for team/enterprise features later.
User Experience Flow
Terminal Usage
# Start interactive TUI
$ robit
# Or with specific conversation
$ robit --conversation last
# Pipe content to LLM
$ cat error.log | robit --ask "What's wrong?"
# Quick query (non-interactive)
$ robit --query "Explain this code" --file src/main.rs
Web Usage
# Build and serve locally
$ cargo xtask serve-web
# Serving at http://localhost:8080
# Or deploy to static hosting
$ cargo xtask build-web --release
# Upload dist/ to Netlify/Vercel/etc
Conclusion
The TUI-first, dual-target architecture provides:
- Native performance for daily terminal use
- Web accessibility for sharing and remote access
- Code reuse between platforms via shared core
- Future flexibility to add server mode or Zellij plugin
This approach honors the terminal-native workflow while not sacrificing the convenience of web-based access when needed.