Let's discuss the benefits of writing fullstack Rust, as well as crossplatform development for Desktop and web targets. What are pros and cons of this approach? I've been using Rust in the browser since early days and noticed a number of interesting points.
Shared code and data structures: one of the key benefits for me personally is that you don't need to document you api with tools like swagger. Define the shared data structures in a module, import it on the client and server sides, and you are good to go. In addition, thanks to serde it's easy to switch between different serialization formats. Want to switch from JSON to MessagePack? Define encode/decode function in the shared module and use them from both client and server. Now changing the format takes a few lines of code.
One language: you can switch between writing client and server without a lot of effort. Of course, WebAssembly adds technical overhead. But I would argue that it's less than using two different languages. Still, there's a need to write platform dependent code at times, and it requires the familiarity with the target platform.
One package manager: when you use a language it's not only about the syntax, but also the ecosystem. And crates.io provides solutions for many common problems already. It saves a lot of time if you have only one package ecosystem to explore. As far as it has the packages you need, of course.
A bit more about WebAssembly: it was created when people wanted to build desktop applications for the browser. And now it's just a nice and convenient benefit when you make a desktop app, but you have an option to build it for the web too.
Binary size: the example application has .wasm file of 4.4Mb when compiled in release mode and optimized with wasm-opt from binaryen.
Font loading: when you use canvas to render your app in the browser, there's a need to load the fonts and it can easily add another 10Mb to the downloading data depeding on the fonts used.
In the end, I'd like to thank all the people who are working on the tools and ecosystem. It's possible only because of your hard work!
What do you think about fullstack and crossplatform development in Rust?
One of the reasons for me personally is a rich selection of packages from crates.io. For example if you are writing a server in Rust, and use something like https://crates.io/crates/reqwest for http requests, then you can reuse it in your mobile app. Also there's serde. You don't need to write the schema for your data if you have Rust on both server and client. Just make a shared crate and use serde to encode/decode the data. It really saves a lot of time if you don't have to use swagger or similar tools. And there's a documentation out of the box with `cargo doc`
You shouldn't use reqwest on mobile devices, you should be using the built-in platform-specific HTTP libraries.
On Android this appears to be less of an issue, but on iOS there's documentation floating around that you really want to use e.g NSURLSession for battery/radio reasons. Spotify even went so far as to write a cross-platform lib for this kind of thing some years back.
I see, still a really cool project! Is accessing the internals simply not possible or just really hard to pull off programmatically? I am wondering about that because I never found anything in the android space to enable that without resorting to Kotlin/Java components.
You can call into to the JVM via FFI (e.g. using the jni crate in Rust), but it's not very nice. And most of the abstractions people have written thus far seem to be primarily (or solely) targeting the "Java calls into native code" use case rather than the "native code calls into Java" use case.
I'd love to see something better here. I suspect it's possible.
It's limited to what NativeActivity / GameActivity can provide. And as @nicoburns mentioned, you'll have to use FFI if you want to access some Android functionality. But it doesn't always go smooth. For example, all my attempts to fix issues with software keyboard didn't work.
slintpad.com uses the wasm port to run on a browser and is not the same as when using Slint to build a "native" app, especially on mobile.
Slint does support decent text input and IME. Including text selection with the native handle. As a demo for android you can try the demo from https://material.slint.dev/ ("Download APK")
Dioxus is WebView, as you've mentioned. Though there's an experimental native renderer mentioned in the README, I would keep an eye on it. And slint should be the same kind of solution as I wrote about. When building native apps for Android, there's usually an issue with text inputs. NativeActivity doesn't support IME, and GameActivity is supposed to solve this. So in case of slint, I would check how they solved the text inputs.
> Though there's an experimental native renderer mentioned in the README,
The native renderer should be available in 2026! (technically it's available now as a preview, but I wouldn't recommend using it until after the next release)
I think it’s important to note that the “native renderer” is still an HTML/CSS portable, render engine, not what would typically be called a native renderer.
I left WebView based solutions out of scope. As you can see, I'm focusing on NativeActivity / GameActivity in my post. Though WebView brings you interesting options. For example, iced is inspired by Elm, and with Dioxus you can use Elm to build mobile apps.
Dioxus has this idea stuck that it's webview only. They're actively working on (and ship at least in some form of alpha or beta) a native-renderer backend.
Shared code and data structures: one of the key benefits for me personally is that you don't need to document you api with tools like swagger. Define the shared data structures in a module, import it on the client and server sides, and you are good to go. In addition, thanks to serde it's easy to switch between different serialization formats. Want to switch from JSON to MessagePack? Define encode/decode function in the shared module and use them from both client and server. Now changing the format takes a few lines of code.
One language: you can switch between writing client and server without a lot of effort. Of course, WebAssembly adds technical overhead. But I would argue that it's less than using two different languages. Still, there's a need to write platform dependent code at times, and it requires the familiarity with the target platform.
One package manager: when you use a language it's not only about the syntax, but also the ecosystem. And crates.io provides solutions for many common problems already. It saves a lot of time if you have only one package ecosystem to explore. As far as it has the packages you need, of course.
A bit more about WebAssembly: it was created when people wanted to build desktop applications for the browser. And now it's just a nice and convenient benefit when you make a desktop app, but you have an option to build it for the web too.
Binary size: the example application has .wasm file of 4.4Mb when compiled in release mode and optimized with wasm-opt from binaryen.
Font loading: when you use canvas to render your app in the browser, there's a need to load the fonts and it can easily add another 10Mb to the downloading data depeding on the fonts used.
In the end, I'd like to thank all the people who are working on the tools and ecosystem. It's possible only because of your hard work!
What do you think about fullstack and crossplatform development in Rust?