Dioxus - rsx

Introduction

Introducing RSX

Dioxus apps are comprised of small elements composed into components and then assembled into a tree. To construct our components, we use a combination of Rust code and a simplified dialect of Rust that we call “RSX”.

RSX is designed to look and feel like a blend between HTML and SwiftUI:

rsx! {
h1 { "Welcome to Dioxus!" }
h3 { "Brought to you by {author}" }
p { class: "main-content", {article.content} }
}

The rsx! macro

The rsx! macro transforms RSX syntax into Rust code:

// This macro...
rsx! {
div { "hello {world}!" }
}
// Expands to this template:
static TEMPLATE: Template = Template {
nodes: [
ElementNode {
tag: div,
children: [
TextNode {
contents: DynamicText(0)
}
]
}
]
}
TEMPLATE.render([
format!("hello {world}")
])

RSX does a lot of heavy lifting for us, significantly cutting down on the verbosity of declaring UI. It also constructs our UIs in the most efficient representation, making rendering extremely fast.

Renderer

Dioxus opted to simply rely on HTML and CSS everywhere. For the web, this is handy – websites are already built with HTML and CSS. On desktop and mobile, dioxus ships a renderer that converts your HTML and CSS to native widgets automatically.

Dioxus rendering engine Dioxus - Blitz is open source and is often indistinguishable from browser-grade engines.

Because the RSX representation is generic, you can even swap out the elements, choosing to render UI that is not made of HTML and CSS.

For example, the Freya project renders the Dioxus tree using Google’s Skia renderer. Skia has a CPU-only architecture, works across a wide range of devices, and enables deeper control over UI effects.

The Dioxus team maintains three first-party renderers:

  • Dioxus-Web: A web-compatible engine that renders directly to HTML DOM Nodes
  • Dioxus-Webview: A desktop and mobile engine that renders to the system webview
  • Dioxus-Native: A desktop and mobile engine that renders to native elements

Elements and Text

User interfaces are assembled by combining text and UI elements in a useful and visually appealing tree.

An example of some text and elements with RSX may look like:

#[component]
fn App() -> Element {
let author = "Dioxus Labs";
let content = "Build cool things ✌️";
rsx! {
h1 { "Welcome to Dioxus!" }
h3 { "Brought to you by {author}" }
p { class: "main-content", {content} }
}
}

Text Nodes

Any content surrounded by quotes is rendered as a text node in RSX:

rsx! { "Hello world" }

Text nodes in automatically implement the same rules as Rust’s format! macro, including Display and Debug printing.

let world = "earth";
rsx! { "Hello {world}!" }

Unlike Rust’s format macro, rsx! lets us embed entire Rust expressions which can be quite handy when working with complex objects or calling functions inline.

Elements

The most basic building block of HTML is an element. In RSX, an element is declared with a name and then curly braces.

One of the most common elements is the input element. The input element creates an interactive input box:

rsx! {
input {}
}

Elements can take additional parameters called attributes that modify how the element is rendered. Attributes are added inline, similar to adding fields to a struct instantiation:

rsx! {
input { placeholder: "type something cool!" }
}

There are a huge number of HTML elements available, including, but not limited to:

  • Text and Content: p, h1, span, div, a, pre, etc.
  • Forms and Input: form, input, textarea, select, button, etc.
  • Media and Content: img, video, audio, source, canvas, svg, iframe, etc.
  • Tables: table, thead, tbody, tfoot, tr, th, td, etc.
  • Semantic Elements: details, summary, dialog, progress, meter, time, etc.

For a full list of HTML elements, see the MDN Web Docs.