# Snora
[](https://crates.io/crates/snora)
[](https://docs.rs/snora)
[](https://deps.rs/crate/snora)
[](https://crates.io/crates/snora-core)
[](https://docs.rs/snora-core)
[](https://deps.rs/crate/snora-core)
[](https://github.com/nabbisen/snora/blob/main/LICENSE)
[](https://github.com/nabbisen/snora/actions/workflows/docs.yaml)
**An iced GUI framework that gets out of the way of your application.**
## Overview
Snora gives an iced application a small, opinionated **skeleton**
(header, sidebar, body, footer) plus the overlay surfaces it almost
certainly needs (dialog, bottom sheet, context menu, toasts) — and
then steps back. Every slot accepts any `iced::Element`, so your UI
code stays your UI code.
## When to use it
snora is a good fit when you are building:
- a **local-first desktop app** that runs heavy work alongside an
interactive UI (AI inference, dataset converters, file processors);
- an app that needs **accessibility correct from day one** — RTL
layout, theme-aware colors, logical edges baked into the API;
- a **standard desktop chrome** (header / sidebar / body / footer)
with a few overlays.
snora is *not* the right tool for games, real-time visualization,
or web-first applications. See
[docs/getting-started/05-when-to-use.md](docs/src/getting-started/05-when-to-use.md)
for fuller fit guidance.
## Quick start
```toml
[dependencies]
iced = { version = "0.14", features = ["tokio"] }
snora = "0.8"
```
```rust
use iced::{Element, widget::text};
use snora::{AppLayout, render};
#[derive(Debug, Clone)]
enum Message {}
#[derive(Default)]
struct App;
impl App {
fn update(&mut self, _msg: Message) {}
fn view(&self) -> Element<'_, Message> {
let body: Element<'_, Message> = text("Hello, snora!").into();
render(AppLayout::new(body))
}
}
fn main() -> iced::Result {
iced::application(App::default, App::update, App::view)
.title(|_: &App| String::from("Hello"))
.run()
}
```
That's the whole program. Adding a header, sidebar, and footer is
three more chained calls — see
[docs/getting-started](docs/src/getting-started/) for the step-by-step
walk-through, or jump straight to the runnable
[examples directory](https://github.com/nabbisen/snora/tree/main/examples)
for one-shot demos of every overlay and widget.
## Features
- **Skeleton + injected slots.** `AppLayout::new(body).header(h).side_bar(s).footer(f)`.
Each slot is any `iced::Element`. No trait to implement, no
dispatcher enum to write.
- **Framework-managed toasts.** `Vec<Toast<Message>>` on your state,
two one-liners (`subscription` + `sweep_expired`) for lifetime,
intent → theme color, six anchor positions including RTL-aware ones.
- **One close sink per channel.** `on_close_modals` for dialogs and
sheets, `on_close_menus` for header / context menus. Wired once.
- **Vocabulary instead of magic numbers.** `SheetSize::Half`,
`SheetEdge::Start`, `ToastPosition::TopEnd`,
`LayoutDirection::Rtl`, `Edge::Start` — explicit choices, not
hardcoded constants.
- **Navigation widgets out of the box.** `app_header`, `app_side_bar`,
`app_tab_bar`, `app_breadcrumb`, plus dropdown menus and context
menus — direction-aware, theme-aware, and entirely opt-in.
- **Three crates, one umbrella.** `snora-core` is the iced-free
vocabulary, `snora-widgets` is the optional prefab UI parts, and
`snora` is the engine — applications only depend on `snora`.
## Design notes
- *Accessible by Default and by Design.* Layout is described in
logical edges (`Edge::Start` / `Edge::End`); LTR ↔ RTL is one
setter on `AppLayout`.
- *No silent drops.* If you populate an overlay but leave its close
sink `None`, the overlay still renders — snora omits only the
click-outside backdrop, never the content.
- *Skeleton, not styling.* Snora positions and stacks. The look of
your dialog card, the typography of your header — those are your
decisions, not ours.
## Read more
For the full picture, head to **[docs/](docs/)**:
- New to snora? Start with [Getting started](docs/src/getting-started/).
- Looking up something specific? [Reference](docs/src/reference/) and
[Guides](docs/src/guides/).
- Wanting to contribute? [docs/src/contributing/](docs/src/contributing/) is
for you — and we'd be glad to have you.
Per-release notes live in [CHANGELOG.md](CHANGELOG.md); the
direction of upcoming work is sketched in [ROADMAP.md](ROADMAP.md).
Built with [iced](https://iced.rs).