Building cross-platform Rust for Web, Android and iOS – a minimal example

One of the advantages of writing code in Rust is that it can be re-used in other places. Both iOS and Android allow using native libraries within your apps, and Rust compiles to native. Web pages can now use WebAssembly (WASM), and Rust can compile to WASM.

So, it should be easy, right?

Well, in practice it seems a little tricky, so I created a small example project to explain it to myself, so maybe it’s helpful to you too.

The full code is at gitlab.com/andybalaam/example-rust-bindings, but here is the general idea:

  • crates/example-rust-bindings – the real Rust code
  • bindings/ffi – uniffi code to build shared objects for Android and iOS
  • bindings/wasm – wasm_bingen code to build WASM for Web
  • examples/example-android – an Android app that generates a Kotlin wrapper, and runs the code in the shared object
  • examples/example-ios – an iOS XCode project where we generate Swift bindings, so we can call the code in the shared object
  • examples/example-web – a web page that imports the WASM and runs it

Steps for WASM

Proof that I did this on Web - Firefox showing "This string is from Rust!"

Variation: if you modify the build script in package.json to call wasm-pack with --target node instead of --target web you can generate code suitable for using from a NodeJS module.

Steps for Android

Proof that I did this on Android: Android emulator showing a label "This string is from Rust!"

Steps for iOS

5 thoughts on “Building cross-platform Rust for Web, Android and iOS – a minimal example”

  1. Hi Andy,

    Thanks for the great intro/reference. We’re currently looking at building a cross platform rust app targeting Android and Web. Being new to Rust, we’re in the process of getting our heads around the idea that we must choose an async runtime to underpin async language features like futures. We don’t have a need for multi-threading, but DX-friendly concurrency abstractions like futures and event-based/reactive programming will help us a lot in our particular domain which is heavily async.

    Do you have any recommendation for how to solve this cross platform? We’ve seen that WASM bindgen can convert futures code to promises, but this ultimately ends up in the JS layer. I guess what we’re looking for is the ability for our rust module to use things like futures and events internally, and expose related methods/events/callbacks externally to JavaScript or Java/Kotlin code.

    A concrete example would be the ability for the rust code to schedule an HTTP request and await a response, where the making of request is delegated to fetch or OkHttp respectively, and the response returned.

    Any help much appreciated!

  2. Hey Andrew,
    It would be great to see true cross platform examples. You are missing Windows, Mac, and Linux. Especially, Windows since there about as many of those devices as Android ones

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.