Intro Zero

Introductory programming and math content.

Follow publication

[Rust] Dioxus v0.6.0-alpha Walkthrough (Updated for v0.6.1)

Rohan Kotwani
Intro Zero
Published in
6 min readOct 29, 2024

This is a walkthrough of examples which I’ve found helpful to get started with Dioxus and cross-platform Rust application development. I’ll go over state components, routing, subcomponents, assets and styling, and desktop specific configurations.

Edit: I updated the last example for v0.6.1. Everything else looks compatible.

Introduction

Dioxus uses Rust’s lifetime system to manage component states efficiently. This hides some of the complexity and makes the code resemble JavaScript. The goal of Dioxus is to make Rust a powerful and user-friendly language for cross-platform app development. In this way, an indie app developer doesn’t need to know numerous technologies and programming languages across every platform or device (Mac, Linux, Windows, iOS, TVs).

Design Philosophy

When creating clean and simple libraries, it is an important to balance performance and development speed without getting bogged down in “ideology”. Dioxis is declarative, component-based, and uses a virtual DOM, inspired by React.

Virtual DOM

The virtual DOM is a concept where a virtual UI representation is synced with the real DOM through a process called reconciliation. It only re-renders components when explicitly instructed, similar to React’s state management. This approach abstracts away the error-prone manual manipulation of DOM elements, ensuring the DOM matches the desired state, greatly simplifying UI development.

The DOM is a tree-like representation of the web page that gets loaded into the browser.

Component-based

Component-based means user interfaces are functions which describe 1) layouts, 2) encapsulating states, and 3) handling user inputs. These functions are composed of subcomponents. Instead of creating individual elements, an !rsx markup macro is passed into Dioxis, which then handles the "drawing" through a virtual DOM.

The rsx! macro makes it easy for developers to write jsx-style markup to create components. RSX supports iterators, conditionals, and event handlers, and interactive functionality.

By using HTML and CSS for the UI, it allows developers to leverage existing web development knowledge across platforms.

Environment Setup

To run this examples in this post, you can start by creating a new rust binary application with cargo init then use the Cargo.toml configuration below.

Cargo.toml

[package]
name = "hello-world"
version = "0.1.1"
edition = "2021"

[dependencies]
anyhow = "1.0.52"
pretty_env_logger = "0.5.0"
dioxus = { git = "https://github.com/DioxusLabs/dioxus.git", features=[ "desktop", "router"]}
log = "0.4.22"

Component State

States can be added using use_signal(|| $OBJECT), where $OBJECT is the initial state that you want your app to manage. This method provides a mutable reference to a value which allows you to manage states without declaring structs. The use_signal function is a type of "hook" which adds functionality to the component and runs and updates in order.

Hooks and Component State

The simple static generator example shows a simple use case of use_signal.

In the example above, an integer state variable, count is initialized to zero. On button clicks, the state is updated within the scope of the app component.

use_signal returns your value wrapped in a smart pointer of type Signal with trait Copy. This is why you can both read the value and update it, even within an event handler.

Every time the component’s state changes, it re-renders and calls the component function. For this example, the component will re-rendered every time the count is updated.

Personal note: it seems that use_signal can be used with almost any object, and I was able to use it with a sled database object.

Finally, hooks cannot be initialized in any “nested” scope like conditionals, loops, or closures.

Routing & Subcomponents

Apps will have different webpages, views, or “scenes” that a user can navigate to.

The example below shows a website, https://example.com, with multiple pages, i.e., https://example.com/home and https://example.com/blog. There is also a catch all route. However, we will be running this code in a desktop application.

Note that, as shown in the Blog component, subcomponents can be quickly created within a component using a rsx! render loop. This modularity allows you to create self-contained components with their own states.

We have two main components in the example above, i.e., Home and Blog inside of an enum called Route. The "catch all" component PageNotFound takes in the route input as a vector string then prints the error message.

Route has the following traits: Clone, Routable, Debug, PartialEq. The PartialEq trait is used to determine if a component should re-render or not when its parent component re-renders. It also has a Routable trait to defined the "location" or paths within the app.

Notice that there is a clickable Link component that can be used to navigate Routes, but it is also possible to programmatically navigate to Routes instead of through a Link.

The navigator function should be included in the dioxus prelude. Here, push will navigate to the target route. There are also other programmatic commands which can be found here

Assets and Styling

Dioxus recently changed how assets are managed (with manganis) so the following is subject to change. At the time of writing this, there is a bug that prevents us from using an assets folder.

I’m using the dx serve command to run the example below. The Dioxus CLI can be installed with this cargo install dioxus-cli. See more information on the getting started page.

Here is my Dioxus.toml file:

This files links important resources to the executable. It also continuously updates the app on code/asset changes which makes for a nice dev environment. Notice where we link the assetsfolder and web.resource . More information can be found in publishing and in configure.

For a desktop application, let’s take a look at a few common asset and CSS styling related examples.

For static files, we can use the asset! macro to link files to the executable. The document::Link and img elements allow us to pass CSS files and images.

This application can be run with dx serve

You can also create inline style as shown with the button. Within onclick (a function?), you can specify how the button interacts with other elements and the UI.

It is also possible to modify the application’s window settings with WindowBuilder. In the example above, I’m allowing the window to not be resizable and to be a specific size. You can find more options here.

Conclusion

This posted focused more on Desktop applications, but the code, in theory, should be transferable to other platforms like terminal, web, and even mobile*. While the project is still in development, the author Jonathan Kelley is actively developing and maintaining the library.

I think it's the perfect time to start developing with, and contributing to, Dioxus. You’ll have the chance to get some nuts-and-bolts experience with open-source development, but also a lot of what is needed to build applications is already provided.

Intro Zero
Intro Zero

Published in Intro Zero

Introductory programming and math content.

Rohan Kotwani
Rohan Kotwani

Written by Rohan Kotwani

My goal is to share a collection of thoughts, ideas, and possibilities from high quality artists and content producers.

Responses (1)

Write a response