Dioxus Knowledge Patch
[!CAUTION] Dioxus 0.8.0-alpha.1 is prerelease guidance and may change before stable release.
Use this skill when creating, migrating, debugging, testing, or packaging a Dioxus application. Inspect the project before selecting an API: stable and prerelease behavior differ.
Reference index
| Reference | Topics |
|---|---|
| components-reactivity.md | Components, props, signals, stores, hooks, tasks, resources, suspense, errors, events |
| assets-styling-ui.md | Assets, RSX, attributes, CSS, Tailwind, document elements, evaluation, accessible UI |
| fullstack-routing.md | Server functions, Axum, SSR, hydration, forms, streaming, WebSockets, files, routing |
| cli-platforms-bundling.md | CLI, project configuration, Web/Desktop/Mobile, logging, debugging, deployment, installers |
| renderers-testing-internals.md | Native and custom renderers, LiveView, direct SSR, tests, hot-patching, WASM splitting, native plugins |
| migration-edge-cases.md | Breaking API changes, deprecations, dependency boundaries, behavioral edge cases, preview cautions |
| ecosystem-sdk-components.md | Styled components, primitives, virtual lists, attributes, SDK services, persistence, timers |
First checks
- Inspect
Cargo.toml,Cargo.lock,Dioxus.toml, active Cargo features, and the installeddxversion before changing APIs. - Determine whether the application is Web, Desktop, Mobile, Fullstack, LiveView, SSR-only, or a custom renderer; the same source may be compiled for more than one target.
- Keep client-only and server-only dependencies behind their respective Cargo features. A server-function body does not hide nearby native code or secrets from the client build.
- Prefer the unified
dioxuscrate and its current prelude. Low-level runtime, scheduler, and renderer APIs may require explicit imports. - Run
dx doctorbefore diagnosing native or mobile toolchain failures. - Treat preview APIs as opt-in and verify the exact dependency and CLI versions before applying them to a stable project.
Breaking changes and deprecations
Components no longer take a scope
Components take props directly, Element is static and result-based, and
runtime helpers such as spawn and consume_context do not need a Scope
argument.
fn Counter() -> Element {
let mut count = use_signal(|| 0);
rsx! {
button { onclick: move |_| count += 1, "{count}" }
}
}
Use rsx! {} to render nothing. Ordinary errors can propagate with ? into an
ancestor ErrorBoundary; do not use the removed VNode::None pattern.
Prefer readable props and store lenses
Use ReadSignal<T> for reactive readable props. RSX can decay a signal, memo,
store lens, or plain value into it. Generic store helpers should accept
Readable or Writable bounds because generated lens types are intentionally
unnamed.
#[component]
fn Title(title: ReadSignal<String>) -> Element {
rsx! { h1 { "{title}" } }
}
ReadOnlySignal is deprecated. Use Store for collections whose children need
per-item reactive lenses rather than borrowing through a signal read guard.
Launch and features are platform-selected
Use dioxus::launch or LaunchBuilder. Renderer features live on the main
dioxus crate; fullstack client and server builds must enable web and
server separately.
[features]
web = ["dioxus/web"]
desktop = ["dioxus/desktop"]
server = ["dioxus/server"]
The old dioxus-lib crate is gone. Use dioxus with the lib feature when
only the framework library layer is required.
Event cancellation is synchronous
Call event.prevent_default() before any .await. Web forms submit by
default, so cancel onsubmit when the application handles submission itself.
LiveView executes Rust handlers on the server and cannot cancel a browser
default in time; use synchronous browser-side JavaScript there.
Asset paths and options changed
asset! paths are absolute from the current crate root and begin with /.
Use AssetOptions and its variant constructors; do not use the old mg! or
ImageAssetOptions::new() forms.
let image = asset!(
"/assets/image.png",
AssetOptions::image().with_format(ImageFormat::Avif),
);
Fullstack types are Dioxus-facing
Use explicit route macros for durable APIs, especially for native clients.
Dioxus's ServerFnError is not the identically named generic server_fn type,
and public dependency boundaries should align with the versions expected by
Dioxus.
If a locked stable project fails after dependency corrections associated with
0.7.5, run cargo update before changing source code.
Reactivity and async work
Reads create subscriptions
A signal read during rendering subscribes that component. A read solely in an
event handler does not. Memos, effects, futures, resources, and loaders track
reads according to their execution semantics; use peek() for an intentional
non-subscribing read.
Signal writes within one runtime step are batched. An .await ends the step,
permitting pending UI to paint. A dependent memo read immediately after a
write recomputes synchronously.
Pick the right task primitive
use_actionstores the latestResultand cancels stale work when called again.spawnowns a!Sendfuture for the current component and cancels it on unmount.spawn_foreverattaches app-long work to the root; it must not retain shorter-lived signals.- Move CPU-bound work to a native thread or Web Worker.
Resources, loaders, and suspense
use_resource restarts when a tracked dependency changes. Use CapturedError
or dioxus::Ok when its result error needs to be cloneable. use_loader
routes loading and error states through suspense and error boundaries; start
independent loaders before the first ? to avoid waterfalls.
Fullstack suspense data must use a server future so the result can be serialized for hydration. Keep reactive reads in the outer closure.
Fullstack quick reference
Compose an Axum server
#[cfg(feature = "server")]
dioxus::serve(|| async move {
use dioxus::server::axum::routing::get;
Ok(dioxus::server::router(app)
.route("/health", get(|| async { "ok" })))
});
Ordinary Axum routes added to the assembled router take precedence over the SSR fallback. Use server-only extractors for request extensions such as authenticated sessions so they never enter the client payload.
Preserve HTTP semantics
- An unrecognized server error becomes HTTP 500; use
OrHttpErroror a typed error implementing the status-conversion traits. - An
ErrorBoundarythat handles an SSR error must recommit its HTTP status throughFullstackContext. - Headers and status freeze when the first streaming chunk commits.
- Native clients support server functions, files, streams, and WebSockets, but
not SSR, hydration data, SSG, or
FullstackContext.
Keep hydration deterministic
The client reruns the component tree during hydration. Put synchronous
nondeterminism in use_server_cached, async nondeterminism in a server future
or loader, and browser-only reads in use_effect. Do not put side effects in
server-cached closures.
Routing quick reference
Derive Routable, mount Router::<Route> {}, and navigate with typed variants.
Matching prefers static paths, then dynamic fields, then catch-alls; enum order
breaks ties. Query and hash segments do not reject a route when typed values are
absent or malformed.
#[derive(Clone, PartialEq, Routable)]
enum Route {
#[route("/")]
Home,
#[route("/post/:id")]
Post { id: u64 },
}
Layouts render children through Outlet::<Route> {}. Configure a history
provider explicitly when URL behavior matters, especially for browser, hash,
LiveView, or memory routing.
Assets, styling, and RSX
- An asset is bundled only when its
Assetvalue survives Rust optimization; retain exported library assets from the final app or mark intentional indirect statics#[used]. - Build child paths beneath an asset directory from the formatted hashed
Asset, not from its source name. - Attribute spreads apply in source order; later values win.
Noneremoves a dynamic attribute. - Quote unknown attributes and all web-component attributes. Dashed tags create untyped web components.
- In multi-node RSX, place a
keyon the first node. - For Tailwind 4, import Tailwind in the input, scan Rust sources with
@source, and include DX's generated stylesheet.
CLI and platform workflow
dx doctor
dx serve --web
dx build --raw-json-diagnostics
dx bundle --json-output
The CLI can serve web, desktop, iOS, Android, fullstack, and ordinary Rust
packages. Native bundles are host-bound; mobile builds additionally depend on
platform SDKs and signing configuration. Use --log-to-file for complete
diagnostics and dx print when another tool must reproduce DX's build
arguments.
For a fullstack web deployment, ship both the generated public directory and
server executable. Bind production containers with IP=0.0.0.0;
dioxus::launch reads IP and PORT.