24 releases

new 0.0.57 Mar 22, 2026
0.0.56 Mar 7, 2026
0.0.47 Feb 28, 2026
0.0.37 Jan 31, 2026

#1438 in GUI


Used in cranpose-testing

Apache-2.0

2.5MB
56K SLoC

Cranpose

Cranpose is a declarative UI framework for Rust. It is the primary entry point for building applications using the Cranpose system, re-exporting necessary types and macros from core, UI, and foundation crates.

When to Use

Use this crate when you are building an end-user application. It provides the AppLauncher for bootstrapping the runtime and the prelude module which contains the most commonly used widgets (Column, Row, Text) and modifiers.

If you are developing a custom widget library or a low-level extension, you might prefer depending on cranpose-core or cranpose-ui directly to reduce compile times or dependency footprint.

Key Concepts

  • AppLauncher: The entry point that initializes the platform-specific window (via winit, Android Activity, or HTML Canvas) and starts the composition loop.
  • Prelude: A convenience module that brings Composer, Modifier, Element, and core widgets into scope.
  • Feature Flags: Controls which platform backends (desktop, android, web) and renderers (wgpu, pixels) are compiled.

Feature Flags

  • desktop (default): Application shell for Linux, macOS, and Windows.
  • android: Bindings for Android Activity.
  • web: Bindings for WASM/WebGL2.
  • renderer-wgpu (default): Hardware-accelerated rendering using wgpu.
  • renderer-pixels: Software rendering fallback using pixels.

Architecture

Cranpose is composed of several crates:

  • cranpose-core: The composition runtime, slot table, and state snapshot system.
  • cranpose-ui: UI primitives, layout protocol, and high-level widgets.
  • cranpose-foundation: Essential building blocks (Box, Row, Column) and the Modifier system.
  • cranpose-animation: Physics-based animation system.

Example

use cranpose::prelude::*;

#[composable]
fn CounterApp() {
    let count = useState(|| 0);

    Column(Modifier.fill_max_size().padding(20.0), || {
        Text(format!("Count: {}", count.value()));
        
        Button(
            onClick = move || count.set(count.value() + 1), 
            || Text("Increment")
        );
    });
}

fn main() {
    AppLauncher::new()
        .with_title("Counter Demo")
        .run(CounterApp);
}

Dependencies

~10–61MB
~1M SLoC