Besides going full native, a Tauri [0] app might have been another good alternative given they already use Rust. There are pros and cons to that choice, of course, and perhaps Tauri was considered and not chosen. Tauri plus Extism [1] would have been interesting, enabling polyglot plugin development via wasm. For Extism see also the list of known implementations [2].
I have been using Tauri for a macOS app I'm making[1] and it has been great. The app is only 11MB and I've had most of the APIs I'd need.
However, there are still some rough edges that have been annoying to work with. I think for my next project I will actually go back to electron. There are two issues that caused me pain:
1. I can't use Playwright to run e2e tests on the tauri app itself. That's because the webview doesn't expose the Chrome DevTools Protocol, and the tauri-driver [2] does not work on MacOS.
2. Security Scoped Resources aren't fully implemented which means if a user gets the app through the app store the app won't be able to remember file permissions between runs [3]. It's not too much of an issue since I probably won't release it on the app store, but still annoying.
But I hope Tauri continues to grow and we start seeing apps use it more.
I have also used Tauri for one of my private apps, and using the OS's webview just doesn't work for me, so for my next stuff I'm probably going to use Electron as well since you can embed the webview. Yeah, it's bloated, but I'm so tired of things not working properly on Wayland without disabling this and that with random env vars and not able to do a fully OOTB single portable AppImage build on Linux. I can either make it work in Kubuntu + Arch (building on Ubuntu), or Arch + Fedora (building on Arch), but not all 3.
I tried Uno Platform and AvaloniaUI last year but I had similar problems there with external drag 'n' drop not working on Wayland and the difficulty in writing your own advanced components of which there are oodles to choose from using React/Vue/Solid/Svelte.
I'm not rewriting that other app in Electron, so for Tauri (the development of which largely seems to have stalled?) I'm hoping this[1] will solve my Linux hurdles. Going to try that branch out.
My team is building a cross platform app with Tauri that is mobile, web, and desktop in one codebase and we've had almost nothing bad to say. It's been great. Also the executable size and security are amazing. Rust is nice. Haven't done as much with it yet but it will come in useful soon as we plan to implement on-device AI models that are faster in Rust than WebGPU.
I find it a bit odd how much people talk up the Rust aspect of Tauri. For most cases you'll be writing a Typescript frontend and relying on boilerplate Rust + plugins for the backend. And I'd think most of the target audience would see that as a good thing.
I working on a project using tauri with htmx. I know a bit uncommon. But the backend part use axum and htmx. No Js/Ts UI. It's fast, reliable and it work well. Plus its easy to share/reuse the lib with the server/web.
I built a vibe-coded personal LLM client using Tauri and if I'm being honest the result was much worse than either Electron or just ditching it and going full ratatui. LLMs do well when you can supply them an verification loop and Tauri just doesn't have the primitives to expose. For my personal tools, I'm very happy with ratatui or non-TUI CLIs with Rust, but for GUIs I wouldn't use it. Just not good dev ex.
I am considering a Tauri app, but still wondering about architecture design choices, which the docs are sparse about. For instance the Web-side may constitute a more full-blown, say NextJS, webapp. And include the database persistance, say SQLite based, on the web side too, closest to the webapp. That goes against the sandboxing (and best-practice likely), where all platform-related side effects are dealt with Platform-side, implemented in Rust code. I wonder if it is a valid choice. There is a trade-off in more ease of use and straightforwardness vs. stricter sandboxing.
At least with Tauri it's easy to both make the choice and change it later if you want to. I think the docs are sparse because it's your decision to make. I've done it both ways and there are pros and cons. If you use the sqlite plugin and write the actual statements on the JS side then you don't need to worry about the JS<->Rust interface and sharing types. Easier to just get going. If you write your own interface then you probably want to generate TS types from Rust. I think a big advantage to the Rust interface way is that it makes it easier to have the web side be dual purpose with the same code running on the web and in Tauri - the only difference being whether it invokes a tauri call or an API call.
I'll note that I have gone a slightly different path for the main app I wrote: I've written adapters on the js side that generate SQL or API calls depending on where the code is running and I wrote my own select/insert/update/delete tauri commands. The reason I ended up with what seems like a hybrid of the approaches I suggested above is that the js side knows more about what it wants and therefore generates SQL/api calls with the appropriate joins and preloads. On the tauri side I wanted to intercept at the data layer for a custom sync engine, which the frontend doesn't need to know about. However, I've ended up at that solution maybe because I added the tauri side after writing for the web.
It may be interesting with event sourcing, having the message bus + eventstore be on the rust side, and SQL projections be exposed in a sqlite db on the web side.
+1 for Tauri, I've been using it for my recent vibe-coded experimental apps. Making rust the "center of gravity" for the app lets me use the best of all worlds:
- declarative-ish UI in typescript with react
- rust backend for performance-sensitive operations
- I can run a python sidecar, bundled with the app, that lets me use python libraries if I need it
If I can and it makes sense to, I'll pull functionality into rust progressively, but this give me a ton of flexibility and lets me use the best parts of each language/platform.
Its fast too and doesn't use a ton of memory like electron apps do.
Also, Rust's strong and strict type system keeps Claude honest. It seems as if the big LLM models have trained on a lot of poorly written TypeScript because they tend to use type assertions such as `as any` and eslint disable comments.
I had to add strict ESLint and TypeScript rules to keep guardrails on the coding agents.
Looks cool, but the phrase 'build applications with the flexibility and power of go' made me chuckle. Least damn flexible language in this whole space.
[0] https://tauri.app/
[1] https://extism.org/
[2] https://github.com/extism/extism/discussions/684