Expand description
§WaterUI
A modern, cross-platform UI framework for Rust that renders to native platform widgets (UIKit/AppKit on Apple, Android View on Android) rather than drawing its own pixels. Build reactive, declarative UIs with Rust’s type safety and performance.
§Overview
WaterUI combines declarative, component-based architecture with fine-grained reactivity to deliver truly native user interfaces across platforms. Unlike traditional Rust UI frameworks that implement custom rendering, WaterUI translates your Rust view tree into platform-native UI components through an FFI bridge, ensuring your apps look and feel native on every platform.
The framework is built on three core principles:
- Native-first rendering: Your UI components compile to UIKit/AppKit views on iOS/macOS and Android View on Android, delivering authentic native behavior and performance.
- Fine-grained reactivity: Powered by the
namicrate, UI updates are surgical and automatic—only affected components re-render when state changes. - Hot reload: Changes to your Rust code reload instantly in running apps via dynamic library swapping, providing a development experience similar to web frameworks.
WaterUI is ideal for building production mobile apps, cross-platform tools, and native desktop applications where performance and platform integration matter.
§Installation
Add WaterUI to your Cargo.toml:
[dependencies]
waterui = "0.2"
waterui-ffi = "0.2" # Required for FFI exportEnable the graphics feature for GPU rendering capabilities:
[dependencies]
waterui = { version = "0.2", features = ["graphics"] }§Quick Start
The fastest way to experience WaterUI is through the CLI’s playground mode, which handles native backend setup automatically:
§1. Install the CLI
cargo install waterui-cli§2. Create and Run a Playground
water create --playground --name my-app
cd my-app
water runYour app launches with hot reload enabled. Edit src/lib.rs and watch changes appear instantly.
§3. Write Your First View
use waterui::prelude::*;
use waterui::app::App;
#[hot_reload]
fn main() -> impl View {
vstack((
text("Hello, WaterUI!").size(24.0).bold(),
text("Build native UIs with Rust"),
))
.spacing(12.0)
.padding()
}
pub fn app(env: Environment) -> App {
App::new(main, env)
}
waterui_ffi::export!();§Core Concepts
§The View Trait
Every UI component implements the View trait, which defines how it renders:
use waterui_core::Environment;
pub trait View: 'static {
fn body(self, env: &Environment) -> impl View;
}Views compose recursively—complex interfaces are built from simple building blocks. The framework handles type erasure, rendering, and updates automatically.
§Reactive State
WaterUI uses Binding<T> for mutable state and Computed<T> for derived values. Views automatically update when reactive values change:
use waterui::prelude::*;
#[hot_reload]
fn counter() -> impl View {
let count = Binding::int(0);
vstack((
waterui::text!("Count: {}", count),
button("Increment")
.action({
let count = count.clone();
move || count.set(count.get() + 1)
}),
))
}§Environment
The Environment provides dependency injection for themes, fonts, and custom services. Values propagate down the view tree without explicit passing:
use waterui::app::App;
use waterui::prelude::*;
use waterui_core::Environment;
use waterui_text::font::{ResolvedFont, FontWeight};
pub fn app(mut env: Environment) -> App {
let theme = Theme::new()
.color_scheme(ColorScheme::Dark)
.fonts(FontSettings::new().body(ResolvedFont::new(16.0, FontWeight::Normal)));
env.install(theme);
App::new(main, env)
}§View Modifiers
WaterUI provides a fluent API for styling and layout through the ViewExt trait:
use waterui::prelude::*;
use waterui_color::Color;
text("Styled Text")
.size(18.0)
.bold()
.foreground(Color::srgb(100, 150, 255))
.padding()
.background(Color::srgb_hex("#f0f0f0"))
.on_tap(|| println!("Tapped!"));§Examples
§Form with Reactive Bindings
use waterui::prelude::*;
#[form]
struct Settings {
username: String,
dark_mode: bool,
volume: f64,
}
#[hot_reload]
fn settings_view() -> impl View {
let settings = Settings::binding();
vstack((
text("Settings").size(24.0),
form(&settings),
Divider,
waterui::text!("Dark mode: {}", settings.project().dark_mode),
waterui::text!("Volume: {:.0}%", settings.project().volume.map(|v| v * 100.0)),
))
.padding()
}§Interactive Gesture Handling
use waterui::prelude::*;
use waterui::gesture::{TapGesture, DragGesture, LongPressGesture};
#[hot_reload]
fn gestures() -> impl View {
let tap_count = Binding::int(0);
vstack((
waterui::text!("Taps: {}", tap_count),
text("Tap Me")
.padding()
.background(Color::srgb_hex("#2196F3").with_opacity(0.3))
.gesture(TapGesture::new(), {
let tap_count = tap_count.clone();
move || tap_count.set(tap_count.get() + 1)
}),
text("Long Press")
.padding()
.background(Color::srgb_hex("#FF9800").with_opacity(0.3))
.gesture(LongPressGesture::new(500), || {
println!("Long press detected");
}),
))
}§Dynamic List Rendering
use waterui::prelude::*;
use waterui::component::list::{List, ListItem};
#[derive(Clone)]
struct Contact {
id: u64,
name: &'static str,
role: &'static str,
}
impl Identifiable for Contact {
type Id = u64;
fn id(&self) -> Self::Id {
self.id
}
}
fn contacts_list() -> impl View {
let contacts = vec![
Contact { id: 1, name: "Alice Chen", role: "Software Engineer" },
Contact { id: 2, name: "Bob Smith", role: "Product Manager" },
Contact { id: 3, name: "Carol Williams", role: "Designer" },
];
List::for_each(contacts, |contact| ListItem {
content: AnyView::new(
vstack((
text(contact.name).size(17.0).bold(),
text(contact.role)
.size(14.0)
.foreground(Color::srgb(128, 128, 128)),
))
.padding_with(EdgeInsets::symmetric(12.0, 16.0)),
),
on_delete: None,
})
}§API Overview
§Layout Components
vstack(),hstack(),zstack()- Vertical, horizontal, and depth stacks with configurable spacing and alignmentscroll()- Scrollable container with automatic content overflow handlingspacer()- Flexible space filler for pushing elements apartpadding()- Add insets around views withEdgeInsetsconfigurationFrame- Fixed, minimum, and maximum sizing constraints
§Controls
Button- Tappable button with action handler and style variantsTextField- Single-line text input with label and placeholderToggle- Boolean switch control with reactive bindingSlider- Continuous value selector within a rangeStepper- Discrete value adjuster with step incrementPicker- Selection control for choosing from multiple options
§Text & Media
Text- Styled text with font, size, weight, and color configurationtext!()macro - Reactive text with format string interpolationstyled()- Rich text with multiple style runsVideoPlayer- Native video playback with controls and event handlinginclude_markdown!()- Compile-time markdown to view conversion
§Form Components
#[form]derive macro - Automatic form generation from structsTextField,Toggle,Slider- Form-compatible controls with labels- Automatic field-to-control mapping based on type
§Navigation
NavigationView- Hierarchical navigation with title barTabView- Tab-based navigation container.title()modifier - Set navigation bar title
§Advanced
Dynamic::watch()- Observe reactive signals and rebuild views on changeAnyView- Type-erased view container for heterogeneous collectionsEnvironment- Dependency injection and context propagationViewExt- Extension trait providing modifier methods for all views
§Features
§Default Features
The base waterui crate includes layout, controls, text, media, navigation, and form components with native rendering backends.
§Optional Features
graphics- Enables GPU rendering with canvas drawing primitives andGpuSurface(requireswaterui-graphics)graphics-minimal- GPU surface only, without canvas (smaller binary size)
§Application Entry Point
Every WaterUI app follows this pattern:
use waterui::prelude::*;
use waterui::app::App;
// Initialize environment (called once at app startup)
pub fn init() -> Environment {
Environment::new()
}
// Root view (called on every render)
pub fn main() -> impl View {
text("Your app content here")
}
// Alternative: App with custom environment setup
pub fn app(mut env: Environment) -> App {
// Install plugins, themes, etc.
env.install(Theme::new().color_scheme(ColorScheme::Dark));
App::new(main, env)
}
// Export FFI entry points for native backends
waterui_ffi::export!();The waterui_ffi::export!() macro generates C-compatible functions that native backends (Swift/Kotlin) call to render your UI.
§Core Architecture
waterui-core- Foundation types:Viewtrait,Environment,AnyView, reactivity primitiveswaterui-ffi- C FFI bridge withexport!()macro for native backend integration
§Component Libraries
waterui-layout- Layout containers and geometrywaterui-controls- Buttons, toggles, sliders, text fieldswaterui-text- Text rendering, fonts, and stylingwaterui-form- Form builder with#[form]derive macrowaterui-media- Video/audio playback componentswaterui-navigation- Navigation containers and routingwaterui-graphics- Canvas drawing and GPU rendering (optional)
§Tools
waterui-cli- Command-line tool for creating, building, and running apps
§CLI Commands
The water CLI provides a complete development workflow:
# Create new project
water create --name "My App" --backend apple --backend android
# Create playground (auto-configured backends)
water create --playground --name my-playground
# Run with hot reload
water run --platform ios --device "iPhone 15 Pro"
water run --platform android
# Build Rust library for specific target
water build ios
water build android
# Check development environment
water doctor
# List available devices
water devices§Platform Support
- iOS/macOS: Renders to UIKit/AppKit (requires Xcode)
- Android: Renders to Android View (requires Android SDK)
§Documentation
- API Reference - Complete API documentation
- Architecture Guide - Technical architecture overview
- Roadmap - Planned features and improvements
§Contributing
Contributions are welcome! Please submit pull requests to the dev branch. The main branch is reserved for releases.
§License
License under Apache 2.0 OR MIT license.
Re-exports§
pub use waterui_color as color;pub use waterui_form as form;pub use waterui_layout as layout;pub use waterui_media as media;pub use waterui_text as text;pub use nami as reactive;pub use tracing as log;
Modules§
- accessibility
- Helpers for customizing accessibility metadata when the built-in
WaterUIdefaults are not enough. - animation
WaterUIAnimation System- app
- A
WaterUIapplication representation. - background
- This module provides types for defining background and foreground colors in a UI.
- component
- UI components for
WaterUI - debug
- Debug utilities for
WaterUI. - env
- Environment management module for sharing data across views.
- error
- Error handling utilities for converting standard errors into renderable views. Utilities for displaying runtime errors inside WaterUI views.
- filter
- Filters Module
- fullscreen
- Full-screen overlay system for
WaterUI. - gesture
- Declarative gesture descriptors used by
WaterUIcomponents. - id
- Identity, tagging, and mapping functionality for UI components.
- metadata
- Metadata definitions for
WaterUI. - prelude
- A collection of commonly used traits and types for easy importing.
- signal
- This module provides a framework for reactive computations that can track dependencies and automatically update when their inputs change.
- style
- This module provides types for working with shadows and vectors in the UI system.
- task
- Task management utilities and async support.
- theme
- Theme System
- view
- Task management utilities and async support. This module provides extension traits and builder patterns for creating and configuring views.
- views
- Collection of view-related utilities for managing and transforming UI components.
- widget
- Widget components for building complex UI elements.
- window
- Module defining the
Windowstruct for UI windows.
Macros§
- hot_
reloadable_ library - Entry point macro for hot-reloadable views.
- impl_
extractor - Implements the
Extractortrait for a type. - include_
markdown - Includes a Markdown file as a
RichTextwidget at compile time. - raw_
view - Implements a native view that is handled by the platform backend.
- s
- Function-like procedural macro for creating formatted string signals with automatic variable capture.
- text
- Creates a reactive text component with formatted content.
Structs§
- AnyView
- A type-erased wrapper for a
View. - Binding
- A
Binding<T>represents a mutable value of typeTthat can be observed. - Color
- A color value that can be resolved in different color spaces.
- Computed
- A wrapper around a boxed implementation of the
ComputedImpltrait. - Environment
- An
Environmentstores a map of types to values. - Str
- A string type that can be either a static reference or a ref-counted owned string.
Traits§
- Form
Builder - Trait for types that can be automatically converted to form UI components.
- Identifiable
- Defines an interface for types that can be uniquely identified.
- Signal
- The core trait for reactive system.
- Signal
Ext - Extension trait providing additional methods for
Signaltypes. - View
- View represents a part of the user interface.
- ViewExt
- Extension trait for views, adding common styling and configuration methods.
Functions§
- entry
- Wraps the root view for an application, allowing custom entry pipelines to compose around it in the future.
Attribute Macros§
- form
- The
#[form]attribute macro that automatically derives multiple traits commonly used for forms. - hot_
reload - Attribute macro for enabling hot reload on view functions.
Derive Macros§
- Form
Builder - Derives the
FormBuildertrait for structs, enabling automatic form generation. - Project
- Derive macro for implementing the
Projecttrait on structs.