Build1 publisher3 min readPublished
A menu-bar app dropped 274 MB by rendering on the webview macOS already ships
WatchMe's Electron bundle measured 289 MB before its port to Tauri 2. The saving comes entirely from deleting a bundled Chromium, and it transfers only to an app whose interface can accept whatever the system webview draws.
The Engineer · Build desk
What happened
- WatchMe, a macOS menu-bar app that lists processes, owns a tray icon and posts notifications, shipped an Electron bundle that measured 289 MB.
- The migration landed on 10 September as a single commit touching 34 files, one day after the last Electron commit, with Claude Code doing most of the typing.
- Rebuilding the interface surfaced a highlighted-row CSS class added on 19 September 2024 that no stylesheet in the repository has ever defined.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- constraint The 274 MB came off only because nothing in WatchMe's interface cared which engine drew it. An app that pins a Chromium version to keep its layout stable is buying that weight on purpose.
- cost Deleting the browser cost a language boundary and a net 7,279 lines of source. The artifact a user installs got smaller while the codebase a maintainer reads got larger.
- decision Anyone citing the 94.7% to justify a port needs their own compressed installer figures, since the measurement on offer is du against an uncompressed .app directory.
- capability A compiler that rejects a bad port within seconds turns handing 220 lines of main-process JavaScript to a model into a review job instead of a debugging job.
Start with the arithmetic, because the title's 15 MB is not a figure the post prints. It reports the packaged app as 18.9x smaller and a 94.7% reduction in what a user downloads [13]. 289 divided by 18.9 is 15.29 [21]. 289 less 94.7% is 15.32 [22]. The two ratios agree, and 15 MB is rounded down from about 15.3.
Both ends of that ratio come from one command. `du -sh dist/mac-arm64/WatchMe.app` reported 289M [3]. "289 MB. To list processes and show a notification," the developer wrote [28]. du measures the uncompressed bundle on an arm64 disk, and a user downloads a compressed archive, for which the post gives no number [27].
The saving has a single source. Electron shipped an entire Chromium build so that a table could be rendered, and macOS already has a webview that every other app uses for free [5]. "Tauri doesn't make your app fast. It makes your app small, by not shipping a browser," the developer wrote [6]. No timing or memory measurement appears in the post in either direction [27].
So the transfer condition is about layout, not about OS access. WatchMe's interface is a table and two checkboxes, sitting on top of three operations that touch the OS: enumerate processes, own a tray icon, post a notification [4]. Nothing there depends on a particular rendering engine. An app that pins a Chromium version to get its layout right is buying something with that 274 MB [23].
The IPC delta is the part worth copying regardless. The Electron version needed three artifacts: an `ipc-channels.json` listing five channel names, a `preload.js` re-exposing each one through `contextBridge`, and `ipcMain.handle` registrations in the main process [7]. Tauri needs one attribute. `#[tauri::command] fn get_processes()` on the Rust side, `invoke('get_processes')` in the renderer, and the channel name is the function name [8]. The npm dependency went with it: `sysinfo` enumerates processes in the Rust core, and the renderer still reads the same `pid`, `name` and `cmd` [9][10].
The bundle shrank and the repository grew. That single commit was +12,154 and -4,875, a net gain of 7,279 lines [14][24]. Around 220 lines of Electron main-process JavaScript became Rust [16]. Another 579 lines of scaffolding for booting and driving a packaged Electron app were deleted, roughly 11.9% of the deletions in the commit [11][25]. The harness did not go away because Tauri replaced it: "The logic worth testing was always plain JavaScript; it just hadn't been separated from Electron," the developer wrote [12].
Claude Code did most of the typing [15]. The port suited that: known shape, documented target API, and "Rust's type checker is a brutal reviewer, and having one is what makes AI-written Rust tolerable" [17]. The find the developer rates highest came after the port. While rebuilding the UI, the model read the renderer and flagged `row.classList.add('highlighted-row')`, a class added on 19 September 2024 and never defined in any stylesheet [18][20]. For 721 days, close to two years, the only sign that a process was being watched was the checkbox the user had just ticked [19][26].
What to watch
- A compressed DMG or zip size for both builds would show whether the 94.7% holds for what a user actually downloads.
- A cold-start or idle-memory measurement would test the claim that Tauri makes the app small without making it fast.
- A Windows or Linux build of the same app would show whether the ratio survives outside the mac-arm64 slice that was measured.