Technology Philosophy: Rust + WebAssembly Only
Core Principle
robit is a Rust project. Full stop.
We will not use:
- ❌ TypeScript/JavaScript frontend frameworks (React, Vue, Angular, Lit)
- ❌ Node.js/npm ecosystem for UI
- ❌ Separate language for web vs terminal
- ❌ JavaScript bundlers (webpack, vite, rollup)
We will use:
- ✅ Rust for all logic and UI
- ✅ WebAssembly for browser deployment
- ✅ ratatui for terminal UI
- ✅ ratzilla for web UI (terminal aesthetic in browser)
- ✅ Leptos (optional future) for rich web UI if needed
- ✅ trunk for WASM builds
- ✅ Cargo for everything
Why This Matters
Type Safety
Rust’s type system catches errors at compile time:
#![allow(unused)]
fn main() {
// This won't compile - the compiler catches it
let conversation: Conversation = load_conversation(id)?;
// conversation is guaranteed to be valid here
}
Compare to TypeScript:
// This might fail at runtime despite types
const conversation = await loadConversation(id);
// conversation might be null, undefined, or malformed
Single Toolchain
Rust approach:
cargo build # Build everything
cargo test # Test everything
cargo clippy # Lint everything
cargo doc # Document everything
TypeScript approach (pi-mono):
npm install # Node dependencies
npm run build # Compile TypeScript
npm run check # Lint + format
tsc --noEmit # Type check
Performance
- Zero-cost abstractions: What you write is what runs
- No garbage collection: Predictable performance
- WASM is fast: Near-native speed in browser
- Small bundles: Rust WASM is typically smaller than JS bundles
The WebAssembly Path
Phase 1: Terminal-First (Current)
┌─────────────────────────────────────┐
│ robit (ratatui + crossterm) │
│ │
│ Native terminal, full experience │
└─────────────────────────────────────┘
Deploy: cargo install robit
Phase 2: Web Convenience
┌─────────────────────────────────────┐
│ robit-web (ratatui + ratzilla)│
│ │
│ Same UI code, renders to DOM │
│ Terminal aesthetic in browser │
└─────────────────────────────────────┘
Deploy: Static hosting (GitHub Pages, Netlify, etc.)
Phase 3: Rich Web (If Needed)
┌─────────────────────────────────────┐
│ robit-web-rich (Leptos) │
│ │
│ Full web framework (still Rust!) │
│ Rich interactions, modern UX │
└─────────────────────────────────────┘
Deploy: Static hosting or serverless functions
Why Leptos?
- Full-stack Rust framework
- Compiles to WASM
- Reactive like React, but Rust-native
- No JavaScript required
- Can reuse robit-core crate
#![allow(unused)]
fn main() {
// Leptos example - still Rust!
#[component]
fn ConversationView() -> impl IntoView {
let (messages, set_messages) = create_signal(vec![]);
view! {
<div class="conversation">
<For
each=messages
key=|msg| msg.id
children=|msg| view! { <Message msg=msg /> }
/>
</div>
}
}
}
Common Objections
“But JavaScript has better web ecosystem!”
Reality: The WASM ecosystem has matured:
- trunk: Like webpack but for Rust WASM
- web-sys: Complete browser API bindings
- gloo: Ergonomic wrappers for web APIs
- Leptos/Dioxus/Yew: Full React-like frameworks in Rust
“TypeScript has good types too!”
Reality: TypeScript’s type system is unsound:
// Valid TypeScript that crashes at runtime
const x: number = "hello" as any;
console.log(x + 1); // NaN or "hello1"
Rust’s type system is sound and enforced at compile time.
“JavaScript is easier to hire for!”
Reality: This is a passion project, not enterprise software. We optimize for:
- Developer experience (ourselves)
- Code quality
- Long-term maintainability
Not hiring metrics.
“But pi-mono is successful with TypeScript!”
Reality: Different projects, different goals. pi-mono optimizes for:
- Ease of contribution (11k stars, 117 contributors)
- Familiar stack (JavaScript/TypeScript is popular)
- Rich web features (they need them)
We optimize for:
- Type safety
- Performance
- Single ecosystem
- Terminal-first experience
Both can be successful.
The Escape Hatch
If we discover that the terminal aesthetic in browser is too limiting, and ratzilla can’t be extended enough:
Option A: Build a Leptos app
- Still Rust
- Still WASM
- Rich web UI
- Reuse robit-core
Option B: Enhance ratzilla
- Add custom DOM elements for rich features
- Keep terminal aesthetic for chat
- Add file previews, drag-drop as needed
Option C (not happening): Use React/Vue
- ❌ Not in this codebase
- ❌ Different language
- ❌ Different toolchain
- ❌ Different mental model
Examples in the Wild
Other projects successfully using Rust + WASM for web:
- Figma: Rust core, WASM in browser
- Ruffle: Flash emulator in Rust/WASM
- WordPress Playground: PHP in WASM (Rust toolchain)
- Ratzilla demos: Terminal UIs in browser
- Leptos apps: Full web apps in Rust
The approach is proven.
Our Stack
Language: Rust (100%)
Terminal UI: ratatui + crossterm
Web UI: ratatui + ratzilla (WASM)
Future web: Leptos (if needed, still Rust)
Build tool: Cargo + trunk
Package mgr: Cargo
Testing: Built-in (cargo test)
Linting: Clippy
Formatting: rustfmt
No npm. No node_modules. No package.json. No webpack config.
Just Rust.
Conclusion
This isn’t about hating JavaScript or TypeScript. They’re fine tools for many projects.
This is about choosing the right tool for our specific project:
- A terminal-first LLM tool
- Where type safety matters (AI interactions)
- Where performance matters (streaming responses)
- Where we want a single, cohesive codebase
Rust + WebAssembly is that tool.