Original Hashnode Post

hey ๐Ÿ‘‹

Iโ€™m Marc and I am happy to announce the first alpha (v0.1) of Freya, an experimental cross-platform native GUI library for ๐Ÿฆ€ Rust, built on top of ๐Ÿงฌ Dioxus and powered by the ๐Ÿ–ผ๏ธ Skia library.

What is Freya ๐Ÿฆ€ ?

Freya is a GUI library that extends Dioxus by adding its own renderer based on Skia with the help of a custom layout library, its own elements namespace, attributes and events, plus a set of components and hooks, and also some developer tools like a Devtools panel or a headless components testing runner.

Do you want to try it?

Read this. Just be aware that it is still in the โš ๏ธ experimentation phase, I would like this first release to be an opportunity to gather feedback, suggestions, new contributions and ideas!

What is Dioxus ๐Ÿงฌ ?

Dioxus is a renderer-agnostic UI library for Rust, like React. It uses components as functions and hooks. It supports many renderers: web, backend with SSR, liveview and fullstack, desktop and mobile with webview, desktop with WGPU, or even TUI.

Learn more about Dioxus. And see the differences with Freya.

Reasons to use Freya โœ…

Reasons to not use Freya โŒ

Example

Here there is a simple counter app with Freya (source code here):

fn app(cx: Scope) -> Element {
    let mut count = use_state(cx, || 0);

    render!(
        rect {
            height: "20%",
            width: "100%",
            background: "rgb(233, 196, 106)",
            padding: "12",
            color: "rgb(20, 33, 61)",
            label { 
                font_size: "20", 
                "Number is: {count}"
            }
        }
        rect {
            height: "80%",
            width: "100%",
            background: "rgb(168, 218, 220)",
            color: "black",
            padding: "12",
            onclick: move |_| count += 1,
            label { "Click to increase!" }
        }
    )
}

Freya Demo Example

โœจ Supported features

๐Ÿ’ป Supported platforms

All major desktop OS:

It could technically run on more platforms, like Mobile or Web via Wasm, feel free to contribute ๐Ÿ˜

๐Ÿ”„ Hot reload

Freya supports Dioxusโ€™s hot reload, which means that you can write and update the layout, styling and other static attributes of your components without having to recompile any rust code, it updates on the fly.

Demo

๐Ÿงฐ Testing

Freya supports headless testing of components, you can simulate from the window size to events, like mouse or keyboard, and also assert the layout or text values of your components.

Simple example:

#[tokio::test]
async fn no_state() {
    fn no_state_app(cx: Scope) -> Element {
        render!(
            label {
                "Hello"
            }
        )
    }

    let mut utils = launch_test(no_state_app);

    assert_eq!(utils.root().get(0).get(0).text(), Some("Hello"));
}

A more complex example that even simulates click events:

#[tokio::test]
async fn simulate_events() {
    fn stateful_app(cx: Scope) -> Element {
        let enabled = use_state(cx, || false);
        render!(
            rect {
                width: "100%",
                height: "100%",
                background: "red",
                direction: "both",
                onclick: |_| {
                    enabled.set(true);
                },
                label {
                    "Is enabled? {enabled}"
                }
            }
        )
    }

    let mut utils = launch_test(stateful_app);

    let rect = utils.root().get(0);
    let label = rect.get(0);

    // Inital render
    utils.wait_for_update().await;

    let text = label.get(0);

    assert_eq!(text.text(), Some("Is enabled? false"));

    utils.push_event(FreyaEvent::Mouse {
        name: "click".to_string(),
        cursor: (5.0, 5.0).into(),
        button: Some(MouseButton::Left),
    });

    // New render after clicking
    utils.wait_for_update().await;

    let text = label.get(0);

    assert_eq!(text.text(), Some("Is enabled? true"));
}

๐Ÿ” DevTools

Freya integrates an experimental DevTools panel to help you navigate and inspect the elements of your app while you are developing. It is not included in release builds.

You can do:

DevTools

๐Ÿค“ Complex examples

For simpler examples see the Freya repository.

Freya-editor: An experimental code editor.

Freya Editor

Canvas: A canvas for floating editors that you can drag around.

Canvas

๐Ÿ“† Roadmap

I am aware Freya is not perfect, and it will take some time to be production-ready, but I am sure it will keep getting better.

๐Ÿ‘€ See you soon!

I hope you liked this post and want to try Freya at some point, or even contribute!

Make sure to give Dioxus some love, Jonathan, Evan and the other contributors have made an amazing work with Dioxus, they have been a fundamental piece for Freya to work ๐Ÿซ‚.

Also thanks to Armin for his amazing work in rust-skia and help with issues and doubts ๐Ÿ’ช, and Tropix126 for his work in new styling features like more font customization, better rounded corners, better shadows and a few more things ๐Ÿ’ฏ !

You can leave a star โญ in the repository or sponsor me on GitHub Sponsors if you want ๐Ÿ’–. You can join the Discord server or follow me on ๐Ÿฆ Twitter, I usually share the progress I make in Freya.

Thanks!