plushie 0.7.1

Desktop GUI framework for Rust
# plushie

Build native desktop apps in Rust. **Pre-1.0**

Write your entire application in Rust (state, events, UI) and get
native windows on Linux, macOS, and Windows. The
[renderer](https://github.com/plushie-ui/plushie-rust) is built on
[iced](https://github.com/iced-rs/iced) and can run in-process (no
subprocess needed) or as a separate binary over stdin/stdout.

SDKs are also available for
[Elixir](https://github.com/plushie-ui/plushie-elixir),
[Gleam](https://github.com/plushie-ui/plushie-gleam),
[Python](https://github.com/plushie-ui/plushie-python),
[Ruby](https://github.com/plushie-ui/plushie-ruby), and
[TypeScript](https://github.com/plushie-ui/plushie-typescript).

## Quick start

```rust
use plushie::prelude::*;

struct Counter { count: i32 }

impl App for Counter {
    type Model = Self;

    fn init() -> (Self, Command) {
        (Counter { count: 0 }, Command::none())
    }

    fn update(model: &mut Self, event: Event) -> Command {
        match event.widget_match() {
            Some(Click("inc")) => model.count += 1,
            Some(Click("dec")) => model.count -= 1,
            _ => {}
        }
        Command::none()
    }

    fn view(model: &Self, _widgets: &mut WidgetRegistrar) -> ViewList {
        window("main").title("Counter").child(
            column().spacing(8.0).padding(16)
                .child(text(&format!("Count: {}", model.count)).size(24.0))
                .child(row().spacing(8.0).children([
                    button("inc", "+").style(Style::primary()),
                    button("dec", "-").style(Style::danger()),
                ]))
        ).into()
    }
}

fn main() -> plushie::Result {
    plushie::run::<Counter>()
}
```

```toml
[dependencies]
plushie = "0.6"
```

Direct mode (default) embeds the renderer. For wire-only (lighter build):

```toml
[dependencies]
plushie = { version = "0.6", default-features = false, features = ["wire"] }
```

`default-features = false` without either runner feature (`direct` or
`wire`) is a library-only build. It supports APIs such as queries and
`TestSession`, but `plushie::run()` returns `Error::NoRunnerFeature`
because no renderer runner is compiled in.

Run the [examples](examples/) with `cargo run -p plushie --example counter`.

## How it works

Your Rust application and the renderer share a process by default
(direct mode). The SDK builds UI trees and handles events; the
renderer draws native windows and captures input.

The SDK diffs each new tree against the previous one and sends only
the changes. In wire mode, the renderer runs as a separate process
and communication happens over stdin/stdout, using the same protocol
that powers the Elixir, Gleam, Python, Ruby, and TypeScript SDKs.

## Features

- **Elm architecture** - init, update, view with typed events
  and commands
- **Built-in widgets** - layout, input, display, and interactive
  widgets out of the box
- **Canvas** - shapes, paths, gradients, transforms, and
  interactive elements for custom 2D drawing
- **Themes** - dark, light, nord, catppuccin, tokyo night, and
  more, with custom palettes and per-widget style overrides
- **Animation** - renderer-side transitions, springs, and
  sequences with no wire traffic per frame
- **Multi-window** - declare windows in your view; the framework
  manages the rest
- **Platform effects** - native file dialogs, clipboard, OS
  notifications
- **Accessibility** - keyboard navigation, screen readers, and
  focus management via [AccessKit]https://accesskit.dev
- **Custom widgets** - compose existing widgets, draw on the
  canvas, or implement `PlushieWidget` in Rust
- **Two rendering modes** - direct (in-process, default) or wire
  (subprocess binary via stdin/stdout)

## Testing

Use `TestSession` for headless testing without a display:

```rust
use plushie::test::TestSession;

let mut session = TestSession::<Counter>::start();
session.click("inc");
session.click("inc");
assert_eq!(session.model().count, 2);
session.assert_text("count", "2");
```

## Status

Pre-1.0. The core works (built-in widgets, event system, themes,
multi-window, testing, accessibility) but the API is still evolving.
Pin to an exact version and read the
[CHANGELOG](../../CHANGELOG.md) when upgrading.

## License

MIT OR Apache-2.0