Tauri Is Turning Into Electron (And That's a Good Thing)

Share on Twitter

Electron, since it’s creation, has slowly taken over desktop app development. Every single major desktop app made in the last few years have been almost all Electron: Slack, Discord, VSCode, all built using it. However Electron has received heavy criticism because of numerous flaws in the apps it powered, which even if not inherently a problem of the framework itself still gets associated with it nonetheless. Tauri, an alternative to Electron and by far it’s biggest competitor, got released in 2020 to challenge Electron’s shortcomings by providing an alternative desktop framework that also offered developers a way to build desktop apps with web technologies on the frontend using the native webview of the operating system the app was running on, with a lightweight Rust backend, mainly to minimize the performance and size problems that plagued Electron. In more recent years though, the problems of the native webviews are coming to light with the increasing popularity of the framework, and this has led to the Tauri team rearchitecting the runtime to make it basically an Electron with a Rust backend. But I believe this step taken by the framework is a good thing, and I’ll go over why in this post.

Electron’s Rise

One of the main selling points of Electron and other Electron-like frameworks is the use of web technologies to design interfaces for desktop, which before, required specialized native teams to get the job done.

This was exacerbated especially with the flaws of Windows where there seemingly never existed a good way to build a native UI for it. Even today, native Windows UI solutions released by Microsoft aren’t that good and some apps like Whatsapp actively migrated away from a native app to an Electron app on Windows specifically because it was easier than dealing with Microsoft’s unreliable toolkits. Even Microsoft itself has been working more on developer solutions like React Native for Windows instead of native. And for this point, Linux is also an example of a platform where not many desktop apps existed, because unlike the other two major operating systems, very few people even built for Linux in the first place as it was always an afterthought because of it’s lower userbase. Electron made building apps for all these major platforms, that looked, and functioned properly as simple as adding a build target, which allowed developers to make apps that ran the same way on all platforms without much hassle, which led to more activity in the desktop space, especially for Linux.


One of the main components of Electron that made this possible was Chromium, which in my eyes is the real value piece in this entire story, and it is the main focus of this post.

Chromium & CEF

Most if not all desktop users in the world are using Chromium in at least some form every single day. It is THE web rendering platform that works fast and consistently across almost all platforms. Even apps that don’t use Electron, like Spotify, still use a custom CEF wrapped application. The reason major apps use CEF despite the “Chromium tax” is because it simply works. And more importantly, even if it’s a resource hog, the rendering behavior across platforms is consistent, it’s up-to-date with modern browser features, and the web apps run fast on it.

CEF or the Chromium Embedded Framework exists to serve the apps that need to run web technologies in a reliable way, and Electron from day one was built on it. Initially, this was the biggest advantage and also the biggest disadvantage of Electron. Since Chromium is great at web rendering, there’s no unexpected “This animation looks…off” or “Why is this gradient/dynamic opacity element flickering?” However, it also caused Electron it’s memory hog reputation. Electron already needs to run Node on the user’s device, adding Chromium on top of that create’s a CEF + Node application that takes up 100MB of RAM just to render some text on the screen. Obviously the benefits start showing more when the app’s actually decently sized and not over-engineering a hello world app, but when an issue exists and is very visible to the end user, people will find anything involved to blame, whether it be JavaScript, Chromium, Node, Google, Electron, …, anything.

Tauri’s Promises & Flaws

When Tauri initially released, it marketed itself as a faster and lightweight alternative to Electron. What it did was use the system’s native webview to render the frontend content, and instead of Node, it used Rust for the app’s backend, which is way faster and smaller than packaging Node + CEF for a single application. There’s a problem though. Since Tauri uses wry, which interfaces with the native webviews on each platform, there was no guarantee of consistent rendering across platforms. On Windows, Tauri was seemingly just a better Electron, because Tauri uses Windows’ native Microsoft Edge WebView2 which itself is just Chromium underneath, so you just got a faster windows app on switching to Tauri with no rendering anomalies. However, for macOS, Tauri uses WKWebView (Apple’s native Webkit engine) and on Linux, it uses WebKitGTK which can cause various issues depending on what you are building.

I’m saying all of this from experience of working on a large Tauri app side-project for a good 5 months at this point called Wavelength. It’s a music streaming service, very similar to something like Spotify and even draws a lot of it’s UI from Spotify and partly from Apple Music. Of course, that would mean it has various animations, like the Apple Music style word-synced lyrics, hover animations, dynamically gradiented music player, and so much more. It’s an SPA, with it’s web/desktop interface written in SvelteKit. And here’s the thing, Wavelength isn’t just for Windows and macOS, it’s also for Android and iOS (Separate codebase), as well as an additional Google Cast receiver app written for TVs. Initially I didn’t really expect much trouble when I chose Tauri, but as the app grew, the feature list grew, and so did the number of roadblocks I faced. At one point I kind of wished I would’ve chosen Electron just because of Chromium, but I ended up building around Tauri instead.

This part lists the problems I personally faced while working on a project with the native webview on macOS (and potentially Linux if I used it). If you want to read more about the change in Tauri’s architecture, you can skip to the next section.

Roadblock #1: Using HLS

Wavelength initially had content stored in HLS with the FLAC and Opus codecs. This worked great at first when Wavelength was desktop-only. Then came mobile, where despite HLS being supported, was a pain to manage inside the app, because downloading was made incredibly difficult by the format. Since you need to manage lke 50 chunks of one singular song, it quickly gets messy when dealing with a list of songs downloaded on the user’s device. The final blow came when the TV receiver just straight up refused to play DRM-protected HLS. At the time I used the default Google Cast receiver because this was just a side project, but the frustration grew and I ended up paying the €5 to build a custom web receiver for the Google Cast part. Even with that, it seemed like HLS was more of a burden. And this is when it all crumbled, WKWebView (Safari) does not support playing DRM-protected FLAC-in-fragmented-mp4 HLS streams if you do not use Apple’s FairPlay DRM, nor does it even support Opus for the same reason for that matter. (Opus came later, initially Wavelength was going to use AAC but soon changed so it wasn’t a problem until now) So I bit the bullet and migrated off of HLS to whole .flac and .webm files stored in object storage. That wasn’t the end though.

Roadblock #2: Not Using HLS

Wasn’t that the entire reason I switched off of HLS? Well, WKWebView had one more limitation that I was about to face, it doesn’t support MSE for DRM-protected FLAC-in-mp4 files either. So I had two options: Either migrate the app to Electron for Chromium, or write a separate Rust playback engine. And I ultimately chose the latter and that’s how libplayback was born.

The Major Roadblock: The App Feels Terrible To Use

Saying “the app feels terrible to use” is an understatement. I never for the life of me could fix the rendering issues on WKWebView. Navigation speeds were abysmally slow, like enough that the app would feel frozen. And moreover, during the navigation, it would feel pretty much like the entire app’s frozen until the webview finally showed a response after some time. It was bad in production, worse while running the development version.

The subtle opacity animations themselves never correctly worked. The opacity changes always caused a very noticeable flicker on hover, and certain parts like tooltip, popover, and dialog animations often did not show at all. The Apple Music style lyrics animation was mostly alright, but the glow effects on text got a bit messed up sometimes, as if the glow would abruptly get cutoff in one direction.

Tauri’s Solution

For a long time, there has been a proposal to add Chromium (CEF) as an alternative webview supported for Tauri apps for apps that need consistent rendering. It was idle for a while when it was initially proposed, but it finally picked up pace in May 2025, and by Late September of 2026, Tauri has finally released 3.0.0-alpha of it and all its official plugins. It includes the support for the modular runtime architecture, where now, you can specify which runtime to use in your Tauri app.

And recently they also put up the documentation for it. (But yes, all of this is alpha, so better to be a bit wary to use it right now.)

All you need to do is update all your packages and Tauri in Cargo.toml to 3.0.0-alpha (Might not be alpha if you are reading this in the future.)

tauri = { version = "3.0.0-alpha", features = ["tray-icon"] }

# all official plugins have alpha versions released
tauri-plugin-log = "3.0.0-alpha"
tauri-plugin-opener = "3.0.0-alpha"
tauri-plugin-fs = "3.0.0-alpha"
tauri-plugin-os = "3.0.0-alpha"
tauri-plugin-deep-link = "3.0.0-alpha"

And also the JavaScript side APIs to their @next versions:

{
  "devDependencies": {
    "@tauri-apps/cli": "^3.0.0-alpha.4"
  },
  "dependencies": {
    "@tauri-apps/api": "^3.0.0-alpha.2",
    "@tauri-apps/plugin-deep-link": "^3.0.0-alpha.2",
    "@tauri-apps/plugin-fs": "^3.0.0-alpha.2",
    "@tauri-apps/plugin-opener": "^3.0.0-alpha.2",
    "@tauri-apps/plugin-os": "^3.0.0-alpha.2"
  }
}

Make sure your CLI is also updated to version three otherwise Tauri won’t be able to locate CEF that it downloads on your machine. For version 3 specifically, you need to configure a runtime like tauri-runtime-cef. They also released tauri-runtime-wry which is the original native webview based runtime. To use CEF, you need to install the former and configure it as the runtime:

$ cargo add tauri-runtime-cef
#[tauri_runtime_cef::cef_entry_point]
pub fn run() {
    tauri::Builder::default()
        .runtime(tauri_runtime_cef::Cef::default())
        .setup(...);
        .build(tauri::generate_context!())
        .expect("Launch failed.")
        .run(...);
}

The Cef::default() will create the runtime with a predefined config, but additional configuration is allowed with methods on Cef.

Doesn’t This Kill Tauri’s Advantage?

Well, yes and also no. First and foremost, this is completely optional. If your UI is relatively simple and does not require the consistency of Chromium’s rendering, you probably do not need to add the massively sized CEF to your app’s bundle. wry and it’s more lighter approach is still an option for everything else. But here arises a greater question, if both Tauri and Electron offer Chromium for the established apps, does Tauri have any advantage for those who use CEF? In fact is it at all lighter when you use CEF in Tauri vs. Regular Electron? Turns out, it is… but probably not by as much as you’d expect. From a purely numbers standpoint, Tauri is still slightly lighter than Electron because it has a compiled Rust backend instead of shipping a Node binary. (But obviously it’s not always the case, because you can totally write or use a lot of Rust/crates and create binary larger than Electron that outgrow a JavaScript bundle) This keeps Tauri’s “lead” in the performance numbers, because obviously running Rust on the backend would also be better for CPU and memory usage than Node. Though the metric where Tauri used to “beat” Electron by hundreds of MBs is out of the question when using CEF because it’s basically the same thing, like to an average person 270MB vs. 300MB is not a noticeable difference.

The Real Motivation Behind The Work On CEF

It’s not like Tauri is foreign to “add a CEF feature flag” requests. The earliest ones date back to mid-2022, that was before even Tauri 2.0 was a thing (released Late 2024). The early requests usually just received a “No” in the GitHub discussions. Mostly because they just did not want to add it, and were also focused on servo, which is an alternative to both system webviews and Chromium, by providing a webview written and usable directly in Rust. But this was out of consideration for most people who wanted something that they could actually use to get their apps working properly, and the thing they wanted was CEF. Initially the proposals weren’t “get rid of wry and put Chromium”, it was more of providing a way to patch the runtime to use Chromium, and most of these issues have two common words in them, it’s “Linux” and “WebKit”, specifically “WebKitGTK” As said earlier, Tauri uses WebKitGTK on Linux, which is an even worse webview compared to Apple’s WKWebView (I’m saying this off of the feedback I’ve seen others post about on GitHub discussions). Apps that worked good on Windows with Microsoft Edge WebView2 (Chromium), okay with WKWebView, were like, really awful in WebKitGTK. It’s very underused. The performance of WebKitGTK isn’t that great compared to Chromium, and not only that, it lacks support for many browser APIs, some because it’s built on WebKit which explicitly does not support APIs like Bluetooth and HID, and additionally some APIs that WebKitGTK itself does not support like WebRTC, Speech, and MIDI, and has various quirks with DRMs. It’s pretty evident why the Linux experience put off many people to just outright demand for CEF instead.

The Myth Surrounding Tauri

Since Electron and Tauri are on the same boat with this update, I want to go over this specific concern that a lot of JavaScript developers have: “Tauri is only for Rust developers because the framework forces you to write a lot of Rust to get stuff working.” Well, this statement is sort of true, but honestly it’s not as serious that you absolutely NEED to write a lot of Rust. The Tauri team and the open source community surrounding it have already developed many official and unofficial plugins that provide functions written in JavaScript that you can call directly to do lower-level native functions without ever writing the Rust side yourself. You do not need to write Rust as much as you might expect unless you are doing something really oddly specific. In my case with Wavelength, some parts that require Rust are the audio playback library, some SQLite for caching stuff, and Google Cast. (And technically you don’t even need to write for Google Cast anymore because with the Chromium/CEF runtime you get Google Cast built-in to the webview) Everything else in the Rust side was written either because it was better for security or more performant than using JavaScript. Also, I like to write Rust, so writing it for Tauri isn’t that big of a deal, but I can totally see how it might be a bit of a concern for use when Electron is just right there for an all-JS stack.

Ending It

What more can I say here? I guess check Tauri v3 out: https://v3.tauri.app