One codebase. TUI today. GUI and Web tomorrow.
FreeSynergy.UI is a Rust UI abstraction library that separates what a UI looks like from how it is rendered. Write your form logic once using fsy-tui (a ratatui/rat-widget backend), and — when the additional backends land — get desktop GUI and web rendering for free.
Currently: TUI backend (ratatui + rat-widget) — full, production-ready. Planned:
fsy-dioxusbackend for Desktop + Web (WASM) via Dioxus.
fsy-core/ Pure-Rust, zero-dependency types
FormAction — typed event vocabulary
SelectionResult — popup result type
fsy-tui/ TUI backend (ratatui + rat-widget)
Lang + TranslateFn — i18n without global state
RenderCtx — Facade over rat-salsa (carries lang + translator)
Anim — tick-driven animations (spinner, pulse, TTL bar)
FormNode — self-contained UI component trait
nodes/ — TextInput, TextArea, Select, MultiSelect,
Section, EnvTable, SelectionPopup
widgets/ — node_block, popup_area, truncate, button_line, …
docs/
ARCHITECTURE.md — design patterns and internal decisions
USAGE.md — how to integrate into your project
Add to your Cargo.toml:
[dependencies]
fsy-core = { git = "https://github.com/FreeSynergy/UI" }
fsy-tui = { git = "https://github.com/FreeSynergy/UI" }Build a form:
use fsy_tui::{nodes::{TextInputNode, SelectInputNode}, FormNode, RenderCtx, Lang};
use fsy_tui::lang::passthrough_translator;
// 1. Create nodes
let mut name = TextInputNode::new("name", "form.name", 0, true)
.hint("form.name.hint");
let mut stage = SelectInputNode::new(
"stage", "form.stage", 0, true,
vec!["dev".into(), "staging".into(), "prod".into()],
);
// 2. Create render context (in your rat-salsa render callback)
let mut f = RenderCtx::new(area, buf, Lang::En, my_translate_fn);
// 3. Render
name.render(&mut f, name_area, focused);
stage.render(&mut f, stage_area, focused);
// 4. Handle events
let action = name.handle_key(key_event);See docs/USAGE.md for a complete example including overlays, mouse handling and form submission.
- OOP everywhere — behaviour lives on the type, not in
matchblocks - Bridge pattern —
SelectInputdelegates all rendering toSelectionPopup(Strategy) - Facade —
RenderCtxhides rat-salsa's(Rect, &mut Buffer)API behind a Frame-like surface - Zero globals —
LangandTranslateFnare passed explicitly viaRenderCtx
| Crate | Renderer | Status |
|---|---|---|
fsy-tui |
ratatui + rat-widget | ✅ Ready |
fsy-dioxus |
Dioxus (Desktop + Web/WASM) | 🔜 Planned |
MIT — see LICENSE. by KalEl / FreeSynergy.Net