Hypen Engine
The core reactive rendering engine for Hypen, written in Rust. Compiles to WASM for web/desktop or native binaries with UniFFI for mobile platforms.
Quick Start
Rust
use ;
use parse_component;
use json;
let mut engine = new;
engine.set_render_callback;
let ast = parse_component?;
engine.render;
engine.update_state;
JavaScript/TypeScript (WASM)
import init, { WasmEngine } from './wasm/hypen_engine.js';
await init();
const engine = new WasmEngine();
engine.setRenderCallback((patches) => applyPatches(patches));
engine.setModule('App', ['increment'], ['count'], { count: 0 });
engine.renderSource(`Column { Text("\${state.count}") }`);
See BUILD_WASM.md for detailed WASM build instructions.
Overview
Hypen Engine is a platform-agnostic UI engine that:
- Expands Hypen DSL components into an intermediate representation (IR)
- Tracks reactive dependencies between state and UI nodes
- Reconciles UI trees efficiently using keyed diffing
- Generates minimal platform-agnostic patches for renderers
- Routes actions and events between UI and application logic
- Serializes for Remote UI scenarios (client-server streaming)
Architecture
┌─────────────────────────────────────────────────────────┐
│ Hypen Engine │
├─────────────────────────────────────────────────────────┤
│ Parser → IR → Reactive Graph → Reconciler → Patches │
│ ↓ ↓ │
│ Component Registry Platform Renderer│
│ Dependency Tracking (Web/iOS/Android)│
│ State Management │
└─────────────────────────────────────────────────────────┘
Core Systems
-
IR & Component Expansion (
src/ir/)- Canonical intermediate representation
- Component registry and resolution
- Props/slots expansion with defaults
- Stable NodeId generation
-
Reactive System (
src/reactive/)- Dependency graph tracking
${state.*}bindings - Dirty marking on state changes
- Scheduling for efficient updates
- Dependency graph tracking
-
Reconciliation (
src/reconcile/)- Virtual instance tree (no platform objects)
- Keyed children diffing algorithm
- Minimal patch generation
-
Patch Types (Platform-agnostic):
Create(id, type, props)- Create new nodeSetProp(id, name, value)- Update propertySetText(id, text)- Update text contentInsert(parent, id, before?)- Insert into treeMove(parent, id, before?)- Reorder nodeRemove(id)- Remove from tree- Event handling is managed at the renderer level
-
Action/Event Routing (
src/dispatch/)- Map
@actions.*to module handlers - Forward UI events (click, input, etc.)
- Stable dispatch contract for SDKs
- Map
-
Lifecycle Management (
src/lifecycle/)- Module lifecycle (created/destroyed)
- Component lifecycle (mount/unmount)
- Resource cache (images/fonts) with pluggable fetcher
-
Remote UI Serialization (
src/serialize/)- Initial tree serialization
- Incremental patch streaming
- Revision tracking and optional integrity hashes
- JSON format support
Usage
Basic Example
use ;
use parse_binding;
use IndexMap;
use json;
// Create engine
let mut engine = new;
// Register a custom component
// Note: In practice, you'd typically parse Hypen DSL with ast_to_ir
engine.register_component;
// Set render callback
engine.set_render_callback;
// Register action handler
engine.on_action;
// Render UI
let ui = new
.with_child;
engine.render;
// Update state
engine.update_state;
With Module Host
use ;
// Create module definition
let module = new
.with_actions
.with_state_keys
.with_persist;
// Create module instance
let instance = new;
engine.set_module;
Compilation Targets
Native (Development)
WASM (Web/Desktop)
The WASM build is fully functional and tested. See BUILD_WASM.md for detailed build instructions.
Quick Start:
# Install wasm-pack (one time)
# Build for all WASM targets
# Or build manually for specific targets:
Output directories:
pkg/bundler/- For use with bundlers (webpack, vite, rollup)pkg/nodejs/- For Node.jspkg/web/- For vanilla HTML/JS (seeexample.html)
Build to custom directory:
# Build directly to your renderer project
The WASM binary is optimized for size (~300KB) with LTO and size optimizations enabled.
JavaScript/TypeScript API
The WASM build provides a WasmEngine class with a complete API:
import init, { WasmEngine } from './pkg/web/hypen_engine.js';
// Initialize WASM (required before creating engine)
await init();
// Create engine instance
const engine = new WasmEngine();
// Set render callback to receive patches
engine.setRenderCallback((patches) => {
console.log('Patches:', patches);
// Apply patches to your platform renderer
applyPatchesToDOM(patches);
});
// Register action handlers
engine.onAction('increment', (action) => {
console.log('Action received:', action.name, action.payload);
// Handle action (e.g., update state)
engine.updateState({ count: action.payload.count + 1 });
});
// Initialize module with state and actions
engine.setModule(
'CounterModule', // Module name
['increment', 'decrement'], // Available actions
['count'], // State keys
{ count: 0 } // Initial state
);
// Render Hypen DSL source code
const source = `
Column {
Text("Count: \${state.count}")
Button("@actions.increment") { Text("+1") }
}
`;
engine.renderSource(source);
// Update state (triggers reactive re-render)
engine.updateState({ count: 42 });
// Dispatch action programmatically
engine.dispatchAction('increment', { amount: 1 });
// Get current revision number (for remote UI)
const revision = engine.getRevision();
WasmEngine API Reference:
constructor()- Create a new engine instancerenderSource(source: string)- Render Hypen DSL source codesetRenderCallback(callback: (patches: Patch[]) => void)- Set patch callbacksetModule(name, actions, stateKeys, initialState)- Initialize moduleupdateState(patch: object)- Update state and trigger re-renderdispatchAction(name: string, payload?: any)- Dispatch an actiononAction(name: string, handler: (action: Action) => void)- Register action handlergetRevision(): number- Get current revision numbersetComponentResolver(resolver: (name: string, context?: string) => ResolvedComponent | null)- Set dynamic component resolver
See BUILD_WASM.md for more details and examples.
Testing WASM Build
Open example.html in a web server:
# Using Python
# Using Node.js
# Then visit: http://localhost:8000/example.html
Mobile (UniFFI)
UniFFI bindings for native mobile platforms are planned but not yet implemented.
# Future: Generate Swift/Kotlin bindings
For now, mobile platforms can use the WASM build via WebView or native WASM runtimes.
Project Structure
hypen-engine-rs/
├── src/
│ ├── lib.rs # Public API exports
│ ├── engine.rs # Main Engine orchestrator
│ ├── wasm.rs # WASM bindings (wasm-bindgen)
│ ├── state.rs # State change tracking
│ ├── render.rs # Dirty node rendering
│ ├── logger.rs # Logging utilities
│ ├── ir/ # IR & component expansion
│ │ ├── mod.rs # Module exports
│ │ ├── node.rs # NodeId, Element, Props, Value
│ │ ├── component.rs # Component registry & resolution
│ │ ├── expand.rs # AST → IR lowering
│ │ └── children_slots_test.rs
│ ├── reactive/ # Reactive system
│ │ ├── mod.rs # Module exports
│ │ ├── binding.rs # ${state.*} parsing
│ │ ├── graph.rs # Dependency tracking
│ │ └── scheduler.rs # Dirty marking & scheduling
│ ├── reconcile/ # Reconciliation
│ │ ├── mod.rs # Module exports
│ │ ├── tree.rs # Instance tree (virtual DOM)
│ │ ├── diff.rs # Keyed diffing algorithm
│ │ └── patch.rs # Patch types
│ ├── dispatch/ # Events & actions
│ │ ├── mod.rs # Module exports
│ │ ├── action.rs # Action dispatcher
│ │ └── event.rs # Event router
│ ├── lifecycle/ # Lifecycle management
│ │ ├── mod.rs # Module exports
│ │ ├── module.rs # Module lifecycle
│ │ ├── component.rs # Component lifecycle
│ │ └── resource.rs # Resource cache
│ └── serialize/ # Serialization
│ ├── mod.rs # Module exports
│ └── remote.rs # Remote UI protocol
├── tests/ # Integration tests
├── Cargo.toml # Rust dependencies
├── build-wasm.sh # WASM build script
├── BUILD_WASM.md # Detailed WASM build docs
├── example.html # WASM demo page
└── README.md # This file
Key Data Structures
Element (IR Node)
Value (Props)
Patch (Output)
Integration with Parser
The engine integrates with the Hypen parser from ../parser:
use parse_component;
use ast_to_ir;
let source = r#"
Column {
Text("Hello, ${state.name}")
Button("@actions.greet") { Text("Greet") }
}
"#;
let ast = parse_component?;
let element = ast_to_ir; // Convert AST → IR
engine.render;
Full Example with Parser
use ;
use parse_component;
use json;
Performance Considerations
- Keyed reconciliation: Use
keyprops for list items to minimize DOM churn - Dependency tracking: Only re-render nodes affected by state changes
- Lazy evaluation: Bindings are resolved on-demand during reconciliation
- Resource caching: Images/fonts are cached with configurable eviction
Remote UI Protocol
For client-server streaming:
// Initial tree (client connects)
// State update (server → client)
// Incremental patches (server → client)
// Action dispatch (client → server)
Testing
# Run all tests
# Run with output (useful for debugging)
# Test specific module
# Test specific file
# Run tests in parallel (default)
The test suite includes:
- Unit tests for each module
- Integration tests for engine workflows
- WASM integration tests
- Reactive dependency tracking tests
- Reconciliation algorithm tests
Contributing
This is part of the Hypen project. See the main repository for contribution guidelines.
License
See main Hypen project for license information.
API Reference
Engine (Rust)
The main Engine struct provides the core functionality:
Key Exports
pub use Engine;
pub use ;
pub use ;
pub use Patch;
pub use StateChange;
Status
✅ Implemented:
- Core reactive rendering engine
- Component expansion and registry
- Dependency tracking and dirty marking
- Keyed reconciliation algorithm
- Patch generation
- Action/event dispatch system
- Module lifecycle management
- Resource caching
- WASM bindings (fully functional)
- Remote UI serialization
Related Documentation
- Documentation Index - Full documentation index
- Control Flow Components - ForEach, When/If, Map usage guide
- Router - Declarative routing and navigation
- Architecture Internals - Reactive system, reconciliation, IR
- Advanced SDK Usage - Custom renderers, component resolvers, Remote UI
- Glossary - Key terms and binding syntax reference
- Browser Compatibility - Browser, platform, and WASM target support
- BUILD_WASM.md - Detailed WASM build instructions
- ../parser/README.md - Hypen parser documentation