hypen-server
Rust server SDK for building Hypen applications.
Hypen is a declarative UI language and reactive runtime for building cross-platform applications. This SDK provides a type-safe, idiomatic Rust API for defining stateful modules, handling actions, managing routing, and discovering components.
Installation
# Cargo.toml
[]
= "0.4"
= { = "1", = ["derive"] }
The crate is named hypen-server (the repository directory is hypen-sdk-rs/).
Quick Start
Define modules with HypenApp::module::<S>(name), then register them on HypenApp::builder() routes and serve the whole app via your web framework (Axum / Actix / etc.):
use *;
use ;
let counter =
.state
.
.
.ui
.build;
let app = builder
.route
.build;
// Plug `app` into your HTTP server's WebSocket route (see "Framework Integration" below).
HypenApp::module::<S>(name) is the canonical entry point and is equivalent to ModuleBuilder::<S>::new(name). For a quick single-module sanity test you can use the built module directly without wrapping it in a HypenApp — but real apps should route through HypenApp::builder().
Action Handling
Actions always take a type parameter for the payload and a string name. Use () for actions with no payload.
// No payload
.
// Typed payload (just needs #[derive(Deserialize)])
.
// Raw JSON access
.
Routing
let app = builder
.route
.route
.components_dir
.build;
app.navigate;
Lifecycle Hooks
let module =
.state
.on_created
.on_destroyed
.build;
Session Lifecycle
When a client disconnects, Hypen can suspend the session and resume it on reconnect (within a TTL). Hook into the transitions to persist, restore, or clean up state:
let module =
.state
.on_disconnect
.on_reconnect
.on_expire
.build;
For manual session management (e.g. in a custom transport), use SessionManager:
use SessionManager;
let manager = new;
let session = manager.create_session;
manager.track_connection;
// on socket close:
if manager.connection_count == 0
Nested Modules
Complex screens can compose several independently stateful modules. Each nested module registers under its lowercase name in the shared GlobalContext, so @{feed.items} / @actions.feed.refresh etc. work from the parent template:
use Arc;
use *;
use create_nested_instance;
let feed_def = new;
let ctx = new;
let feed = create_nested_instance?;
assert!;
At the app level, HypenApp::instantiate_nested(def) does the same thing using the app's own context.
Features
- Typed state with automatic JSON diffing and path-based change detection
- Typed action payloads via
serde::Deserialize(no custom traits needed) - Lifecycle hooks:
on_created,on_destroyed - Session hooks:
on_disconnect,on_reconnect,on_expirewith TTL-basedSessionManager - Nested modules — compose multiple stateful modules under a shared
GlobalContext - URL router with pattern matching and parameter extraction
- Component discovery from
.hypenfiles on the filesystem - Cross-module communication via
GlobalContextandEventEmitter - Patch-based rendering compatible with all Hypen renderers (DOM, Canvas, iOS, Android)
License
MIT