A starter template for Dioxus Desktop apps, with Tailwind & Nix support.
Act as starter project for writing new desktop apps using Dioxus, along with
- Nix support
- Author's preferred tools
- Tailwind
This repository is still a work-in-progress. Here's the current progress:
- Nix
- Devshell
- Nix package
- Simple
nix build
/nix run
- Nix package containing macOS app bundle
- Nix package for Linux
- Simple
- Deployment
- macOS bundling
- Linux bundling
- Tailwind
- Routes & navigation
- Application state (via
dioxus-signals
from 0.5)
Stretch goals:
- macOS Application menu entries
In the nix develop
shell, run:
just watch
just bundle
nix run github:srid/dioxus-desktop-template
# Or just `nix run` in the project directory
This repository began in large part to understand how to manage application state in Dioxus Desktop apps, and come up with some best demonstrable practices for it.
- Shared read-only state
- In the top
App
component, useuse_shared_state_provider
to initialize the application state. - In inner components, use
use_shared_state::<T>
, followed by a.read()
on it, to access the current state value. - The state can be changed to a new value, but not mutated. There is no per-field granularity.
- In the top
- Shared state, that can be modified (from anywhere in the component tree)
- We use dioxus-signals (requires Dioxus from Git) to provide fine-grained mutation and component rerendering.
- In the top
App
component, useuse_context_provider(cx, AppState::new());
- In inner components, use
let state: AppState = *use_context(cx).unwrap();
to access the current state value. - Make individual fields of the state struct a
Signal
type- The state struct should use
Signal
for its field types. Nested tree ofSignal
s is the idiom.
- The state struct should use
- Use
state.<field>
to render a component based on a field signal- Use
dioxus_signals::use_selector
to produce a derived signal
- Use
- Component re-renders when only relevant subset of the state changes
- State modification that relies on a long-running blocking task
- Write async modifier methods on the state struct, and have them update the field signals.
- In the UI components, use
use_future
to invoke these async methods to update the state before the component is renderer (or upon an user event).
This project uses rust-flake to keep flake.nix
minimal.
- Blank screen on Linux? See NixOS/nixpkgs#32580
WEBKIT_DISABLE_COMPOSITING_MODE=1 nix run