In this tutorial, you’ll build your first interactive Dioxus application. We’ll create a counter app with multiple features to demonstrate the core concepts of Dioxus development.
Before starting, make sure you’ve completed the Installation guide and have the Dioxus CLI installed.
Open src/main.rs in your editor. You’ll see something like this:
use dioxus::prelude::*;fn main() { dioxus::launch(app);}fn app() -> Element { rsx! { div { "Hello, world!" } }}
Let’s break this down:
Import the prelude
use dioxus::prelude::*;
This imports all the commonly used Dioxus types and macros, including Element, rsx!, component macros, and more.
Launch the app
fn main() { dioxus::launch(app);}
The launch function starts your Dioxus application. It takes a root component function (in this case, app) and renders it using the appropriate renderer for your platform.
Define a component
fn app() -> Element { rsx! { div { "Hello, world!" } }}
Components are functions that return Element. The rsx! macro lets you write HTML-like syntax that compiles to Rust code.
use_memo creates a computed value that automatically updates when its dependencies change. It’s only recalculated when count changes, making it efficient.
Use memos for expensive computations or derived state to avoid unnecessary recalculations.
use_effect(move || { println!("Count changed to: {}", count());});
use_effect runs side effects when dependencies change. Perfect for logging, API calls, or syncing with external systems.
Effects run after the component renders and whenever captured signals change.
if count() > 10 { div { "High score!" }}
Use regular Rust if statements inside rsx! for conditional rendering. Only the matching branch is rendered.
div { style: "color: red; font-size: 20px;", ... }
Add CSS styles directly with the style attribute. For larger apps, consider using external CSS files or Tailwind CSS.
#[component]fn CounterDisplay(value: i32) -> Element { ... }
The #[component] macro automatically creates a props struct from your function parameters. It’s not required but highly recommended for better error messages and auto-completion.
Passing props
CounterDisplay { value: count() }
Props are passed using the component name followed by key-value pairs. The syntax is similar to struct initialization.
Passing signals
CounterControls { count: count }
You can pass signals directly to child components. This allows children to read and modify parent state.
For read-only access, use ReadSignal<T> as the parameter type instead of Signal<T>.
Hot-reload is your friend: Make changes and see them instantly. The RSX hot-reload works for markup and styles, while the experimental --hot-patch flag enables Rust code hot-reload.
Use the community: Join the Dioxus Discord to ask questions, share your projects, and learn from others.
Check out examples: The Dioxus GitHub repository has dozens of examples covering advanced topics like routing, server functions, animations, and platform-specific features.
Read the docs: The official Dioxus guide provides in-depth coverage of all features.