Shipped a Rust-heavy app on the iOS App Store with Tauri 2 — time for a recap

52 points tm9657 16 comments

Hi guys,

when starting with flow-like.com I knew two things: I want the code base to be in Rust as much as possible and I don't want to rule out any target platforms.

The decision was quickly made to use Tauri (which I had some minor experience in from past projects). The App was released on App Store yesterday and it is more than a simple to-do app (complete offline ready automation application with features like local ORT runtime for local AI models), so I think it is time for recap!

Architecture Overview

Around 80% of the core logic lives in Rust — the frontend is really just glue that brings the APIs together. Here's roughly what's under the hood:

  • Tauri 2 as the shell across iOS, Android, macOS, Windows, Linux
  • Wasmtime for sandboxed workflow nodes using the WASM Component Model (WIT interfaces). On iOS this means Cranelift AOT compilation since Apple doesn't allow JIT. On everything else it's full JIT.
  • ONNX Runtime via ort for running local AI models completely offline
  • LanceDB for vector storage
  • DataFusion for analytical queries
  • SQLite (via a custom Tauri middleware) for blob offloading and local persistence

All of these are Rust crates talking to each other directly. The TypeScript frontend calls into this through Tauri's IPC or backend APIs (Axum).

Pros

Tauri is not really promoting their mobile capabilities anymore (at least I feel like that). That's a shame. The experience of building and publishing using their framework was mostly pleasant.

  • You will end up with ONE code-base that mostly behaves the same across all platforms
  • Tauri allows you to use native TS / JS in the frontend (all frameworks that can do static output are supported + some rust frameworks I didn't look into that much)
  • The whole Rust & TS Ecosystem is at your fingertips
  • You can always integrate into the core platform (iOS or Android) using tauri plugins. I had to do that for a few things like Push Notifications (this seems a bit hacky for now)
  • Cross-compiling Rust crates to iOS/Android mostly just works — cargo + the right target triple and you're there
  • Wasmtime with Cranelift AOT on iOS is surprisingly solid. The App Store JIT prohibition is not too bad.
  • Having your core logic in Rust means your mobile and desktop apps behave identically — no "works on desktop but breaks on mobile" logic bugs
  • ORT on-device inference works on all platforms. Same model, same results, no cloud dependency

Cons

  • Integrating native iOS features can seem hacky — e.g. Push Notifications required a custom Tauri plugin since there's no official one that covers FCM properly
  • Getting the frontend to work with all the safe area stuff on iOS is painful
  • The iOS simulator does not seem to work for me (not sure if this is a tauri problem tho) — I ended up testing on a physical device for most of the development
  • You'll occasionally hit a dependency that doesn't compile for aarch64-apple-ios and need to either patch it or find an alternative - some of them you can find on my Github Org
  • Build times for the full stack (Rust + WASM + frontend + Xcode/Gradle) are long. Get comfortable with incremental builds
  • Debugging Rust panics on mobile is rougher than on desktop — the stack traces aren't always helpful and you'll lean heavily on logging

Would I use Tauri again? 100%.

Ask me anything that you would like to know about more. If you run into problems you can also use my implementation here as reference: https://github.com/TM9657/flow-like