All build notes

Umang: several WhatsApp and Slack accounts, one 3 MB installer

Umang

Umang is a free desktop app for macOS, Windows and Linux that keeps your messaging accounts side by side: WhatsApp, Slack, Telegram, Discord, Gmail, or any web app you add by its address. Two WhatsApp numbers, a work Slack and a personal one, grouped into workspaces — each logged in at the same time, none logging the others out.

Apps like this usually bundle a full copy of Chromium. Umang doesn't. It is built with Tauri, so it uses the web engine your operating system already has. On a macOS release build with no services open, the installer is 3.1 MB, and our CI refuses to publish any installer that reaches 10 MB.

One window, many web views

Umang's window holds one web view for its own interface — written in Svelte — and one more native web view for each service you add. A service's web view is only created the first time you open it.

Rust owns everything that matters: the list of services, settings, validation and the web views themselves. The Svelte side only draws the shell, and it is the only page allowed to call Umang's commands. The service pages — WhatsApp, Slack and the rest — get a much smaller set: report a notification, a keyboard shortcut, or whether they're logged in. A service you add by URL gets that small set for its own origin only.

Keeping accounts apart

Every service gets its own random ID, which names a separate storage partition for cookies and site data. How that partition is made depends on the platform:

  • macOS: each account gets its own WebKit data store. That API only exists from macOS 14, which is why Umang needs macOS 14 or later — older versions simply can't keep two WhatsApp sessions apart.
  • Windows and Linux: each account gets its own data directory.

Umang itself never stores a password or token; each service keeps its own login in its own partition. When you remove a service you can choose to wipe its login or keep it, and adding the same app back with the same label picks the kept login up again.

Cleaning up is where we were careful. Unused partitions are deleted two seconds after their web view closes, because on Windows WebView2 can hold file locks for a moment, and they are swept again at every start. And if Umang can't read its own database at that moment, it deletes nothing. Not knowing which partitions are live and deleting anyway would log you out of every account.

A user agent that never goes stale

WhatsApp and Slack refuse to load in engines that aren't Chromium, and in old versions of Chrome. So Umang presents itself as Chrome — but which version? A hard-coded number would go stale between our releases.

Chrome ships a new stable version every four weeks, so Umang works the version out from the date:

// Anchor: Chrome 141 stable on 2025-09-30
const ANCHOR: u64 = 1_759_190_400;
const CYCLE: u64 = 28 * 24 * 3600;
141 + unix_secs.saturating_sub(ANCHOR) / CYCLE - 1

It deliberately stays one version behind the newest stable release.

Notifications that open the right chat

Web apps notify you through the browser's Notification API, or through their service worker. Umang injects a small script into each service page that replaces both and forwards the notification to Rust, which cleans the text — stripping control characters and capping the length — before showing a native notification titled with the account and workspace.

The script also remembers the last 50 notifications. When you click one, Umang opens that service and runs the page's own click handler, so you land in the chat that sent it rather than on the app's home screen.

"Mentions only" mode needs to know which messages are direct. Umang reads the notification's tag: WhatsApp contacts end in @c.us while groups end in @g.us, and Slack direct-message conversations start with D.

Unread counts come from the page title — most of these apps put "(3)" in front of it. Rust reads the title natively, adds up the services you haven't muted, and shows the total on the dock, the taskbar or the tray.

One honest gap: a notification raised by a service worker while that service's page isn't running isn't bridged yet.

Many web apps, limited memory

Each service is a real web app, and five of them can use a lot of memory. Umang puts services to sleep: by default, a service you haven't opened for 30 minutes hibernates, and at most three stay awake, least recently used first. You can mark a service as "never sleep", and it won't count towards the limit.

What we did not do is let the operating system throttle hidden pages on its own. On macOS, WebKit suspends a hidden page after about five minutes, which drops WhatsApp's connection and its notifications with it. So background throttling is off, and hibernation is our decision rather than the engine's. On Windows, hidden services get WebView2's low-memory target, which makes Chromium release its caches; macOS and Linux offer no public control like that.

The interface shell itself uses about 78 MB on macOS against our 80 MB target. That's tight, and our own notes say so.

Native views live on top

Native web views always draw above the HTML interface. That rules out the usual web tricks: a dialog can't simply appear over WhatsApp. So when a dialog opens, Umang hides the active service, and right-click menus are native menus.

It also caused a real bug. The interface measures the content area and tells Rust where to place the service's web view. When you resized the window quickly, several of those messages could arrive out of order, and the service ended up cut off at an old size. The fix: only one resize request in flight at a time, and the latest size wins.

Linux, and knowing when a page has frozen

Linux brought its own surprises. A GTK save dialog can't run inside WebKitGTK's download callback, so downloads ask for a location through zenity or kdialog instead. And Linux gets a .deb package only: the AppImage bundles its own WebKit and is usually larger than our download host's 25 MiB file limit. The updater installs a new .deb for you, which means Linux users see an administrator password prompt.

Web apps can also freeze. When you open a service that's already running, Umang sends it a ping with a one-time value. If no answer comes back within five seconds, the service is marked as not responding, and Reload recreates its web view with your login intact.

Known limits

Google may refuse to sign in inside an embedded web view, which can affect Gmail. The Windows installer isn't code-signed yet, so Windows shows a SmartScreen warning the first time you run it.

Umang is free at umang.kreasimaju.id.