# whisker (whiskerrs/whisker)

> A Rust framework for building native iOS, Android, web and desktop apps. It uses a fine-grained reactive runtime and native Host renderers, with no virtual DOM.

- GitHub: https://github.com/whiskerrs/whisker
- GitHub.Locker page: https://github.locker/whiskerrs/whisker
- Stars: 374
- Language: Rust
- License: Apache-2.0
- Last push: 2026-11-08

## Questions and answers

Written by GitHub.Locker from the README and the repository; check the README below for details.

**Is it a framework I code against, or a ready-made app?**

A framework you code against. You write the app in Rust, and 'whisker run' or 'whisker build' generates the native projects under gen/ for you.

**How do I get it running?**

Install the Rust target for each platform you need: aarch64-linux-android for Android, wasm32-unknown-unknown for Web, and x86_64-apple-ios for the iOS Simulator on an Intel Mac. Then run 'whisker doctor' to see what's missing.

**What do I need installed first?**

Rust with the target for each platform. For Android you also need the Android SDK, the NDK and a JDK. 'whisker doctor' will tell you what's missing.

**Is it ready for real projects?**

Not yet. It is pre-alpha: the runtime, styling, renderers, routing and hot reload work on all four platforms, but APIs may still change before 1.0.

**Does it use a virtual DOM?**

No. It uses a fine-grained reactive runtime and native Host renderers instead of a virtual DOM.

**How does it handle layout?**

Layout is done by the Taffy layout engine, alongside the reactive runtime and native Host renderers.


---

## README (checked against GitHub 2026-11-08)

Source: https://github.com/whiskerrs/whisker/blob/main/README.md

<p align="center">
  <a href="https://whisker.rs">
    <picture>
      <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/whiskerrs/whisker/main/.github/assets/banner-dark.png" />
      <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/whiskerrs/whisker/main/.github/assets/banner-light.png" />
      <img alt="Whisker — Build cross-platform apps in Rust" src="https://raw.githubusercontent.com/whiskerrs/whisker/main/.github/assets/banner-dark.png" width="100%" />
    </picture>
  </a>
</p>

<p align="center">
  Build native iOS, Android, desktop, and web apps in Rust with a
  fine-grained reactive runtime, Taffy layout, and native Host renderers.
  No virtual DOM.
</p>

<p align="center">
  <a href="https://crates.io/crates/whisker-cli"><img src="https://img.shields.io/crates/v/whisker-cli?logo=rust&label=whisker-cli&color=fdba74" alt="crates.io" /></a>
  <a href="https://whisker.rs/docs"><img src="https://img.shields.io/badge/docs-whisker.rs-22d3ee" alt="Documentation" /></a>
  <a href="#license"><img src="https://img.shields.io/crates/l/whisker-cli" alt="License" /></a>
</p>

---

```rust
use whisker::prelude::*;

#[whisker::main]
fn app() -> Element {
    render! {
        Counter
    }
}

#[component]
fn counter() -> Element {
    let count = signal(0);
    render! {
        View(style: css!(
            flex_grow: 1.0,
            display: Display::Flex,
            flex_direction: FlexDirection::Column,
            justify_content: JustifyContent::Center,
            align_items: AlignItems::Center,
            gap: px(12),
            background_color: Color::hex(0x0B0B0F),
        )) {
            Text(
                value: computed(move || format!("Count: {}", count.get())),
                style: css!(color: Color::hex(0xFFFFFF), font_size: px(28)),
            )
            View(
                style: css!(
                    padding: (px(10), px(20)),
                    border_radius: px(10),
                    background_color: Color::hex(0x7C5CFF),
                ),
                on_tap: move |_| count.set(count.get() + 1),
            ) {
                Text(value: "+1", style: css!(color: Color::hex(0xFFFFFF)))
            }
        }
    }
}
```

<p align="center">
  <img alt="Whisker hot reload — edit the code, save, and the running app updates in under a second with state intact" src="https://raw.githubusercontent.com/whiskerrs/whisker/main/.github/assets/hot-reload.gif" width="100%" />
</p>

<p align="center"><sub>Edit, save — the running app hot-reloads in under a second, with state intact.</sub></p>

## Get started

```sh
cargo install whisker-cli
rustup target add aarch64-apple-ios-sim   # iOS Simulator on Apple silicon
whisker new my-app && cd my-app
whisker run ios          # also: android, web, desktop
```

Each platform needs its Rust target: `aarch64-linux-android` for Android (plus
the Android SDK, NDK, and a JDK), `wasm32-unknown-unknown` for Web, and
`x86_64-apple-ios` instead for the iOS Simulator on an Intel Mac. Run
`whisker doctor` to see what is missing, or follow
[Installation](https://whisker.rs/docs/installation).

`whisker run` watches your source and hot-patches the running app in under
a second, without a restart. Components you didn't edit keep their state.

App metadata and platform settings live in `whisker.rs`. `whisker run` and
`whisker build` generate the native projects from it under `gen/`, so there is
nothing else to run. Add plugins with `cargo add` and configure them there.

## Documentation

Everything — installation, core concepts, guides, and the full API
reference — lives at **[whisker.rs/docs](https://whisker.rs/docs)**.

## Status

Pre-alpha. The retained Rust runtime, typed styling, Host renderers, modules,
routing, and hot reload work across iOS, Android, Web, and Desktop. APIs may
still change before `1.0`.

## License

Licensed under either of [Apache-2.0](LICENSE-APACHE) or [MIT](LICENSE-MIT)
at your option.

