A feature-rich desktop client for WhatsApp Web. Native window, system tray, notifications, chat themes, privacy blur, multiple accounts, spell-check and more — on Linux and Windows, with an experimental macOS build.
This is a fork. It is maintained by Ángel Guzmán Maeso (@shakaran) and builds on the original WhatSie created by Keshav Bhatt, which remains MIT-licensed. All upstream copyright and authorship is preserved — see LICENSE. Whatly is not affiliated with, endorsed by, or connected to WhatsApp or Meta.
| 👥 Multiple accounts | Separate windows or tabs in one window, each a fully separate session. The tray badge sums the unread count across them all. |
| 🎨 Chat themes | 14 themes that recolour WhatsApp Web itself, plus your own wallpaper behind the messages and load-your-own custom CSS. |
| 🕶️ Privacy blur | Blur the chat list and open conversation until you hover, so nobody reads over your shoulder. Five levels. |
| 🔤 Spell checker | Actually works — Chromium .bdic dictionaries are shipped, and you can check against several languages at once. |
| 🖥️ Native integration | System tray with a monochrome option and live connection status, desktop notifications, an app lock, a download manager, global shortcuts. |
| 🌗 Follows your desktop | Optionally track the system light/dark preference, live. |
| 🌍 15 languages | The interface is translated, with an in-app language picker. |
| 🪟 Windows 10+ | One codebase, native toasts and a proper GUI executable. |
| 🍎 macOS (experimental) | Builds as an unsigned .app/.dmg; not yet runtime-validated. |
Whatly is a desktop wrapper around web.whatsapp.com. It gives WhatsApp Web a native window with system integration — tray, notifications, themes, an app lock, shortcuts, a download manager — but the chat interface itself is WhatsApp's own web client, running in Qt WebEngine.
That distinction decides where a problem belongs:
- WhatsApp Web's limits are not Whatly bugs. WhatsApp Web lags behind the phone app for some message types, so you may see "your version of WhatsApp Web doesn't support it". The same message appears in Chrome or Firefox — only Meta can change that.
- WhatsApp Web's shortcuts come from WhatsApp, not from Whatly, so they never appear in the app's shortcut list (see Keyboard shortcuts).
- Whatly is not a WhatsApp client of its own: it does not implement the protocol, store your messages or talk to WhatsApp's servers directly.
On top of upstream WhatSie, this fork adds:
- Scheduled messages — write a message to any number and have Whatly send it later. The schedule is saved to disk, so a message still goes out even if the app was closed when it came due: the next time you open Whatly, anything overdue is sent as a catch-up, and while the app is open a timer sends due messages on time. Manage the queue from Scheduled messages… in the tray menu.
- Pick the font family — render WhatsApp Web's text in any font installed on your system (Settings → Appearance). Emoji, icons and monospaced message formatting are left untouched.
- Hide muted status updates — an optional toggle removes the "Muted updates" section of the Status panel, so statuses from muted contacts do not show up.
- Multiple WhatsApp accounts — as separate windows with
whatly --profile=<name>, as tabs inside one window, or all at once in a grid (tray menu → Grid view, or Ctrl+G). Each account is a fully separate session with its own storage; the tray badge sums the unread count across all of them. Add a tab with the +, and rename or remove one by right-clicking it. With a single account the tab bar is hidden, so nothing changes if you do not use this. - Spell checker — actually works now. Qt WebEngine needs Chromium
.bdicdictionaries, not hunspell's; the fork converts and ships them, so the language list is no longer empty. Pick one or several languages in Settings and Chromium checks against all of them at once. - Chat themes, wallpaper and a privacy blur — recolour WhatsApp Web (14 themes), set your own image behind the chats, or blur them until you hover so nobody reads over your shoulder. Toggle the theme and the blur from buttons in WhatsApp's own sidebar.
- Custom CSS, JavaScript addons and smooth scrolling — load a community
stylesheet (catppuccin and friends) to restyle WhatsApp Web, add your own
.jsaddons (each runs in its own sandbox, toggle them individually), and turn on animated scrolling. Custom CSS and addons are stored per account. - Command palette — Ctrl+K fuzzy-jumps to any action, account or saved reply, then runs it with Enter.
- Notification rules — a daily Do Not Disturb window that holds popups back (badges still update), plus highlight keywords that always break through. Clicking a notification also focuses the message box, so you can reply by just typing.
- Recurring schedules and reminders — a scheduled message can repeat daily, on weekdays or weekly, and a remind me mode notifies you instead of sending.
- Saved replies — keep the texts you send often and insert one from the command palette.
- Focus mode — mask contact names and message previews in the chat list (hover to reveal one) while the open conversation stays readable: for screen sharing and shoulder-surfing.
- Screen sharing that works — a screen/window picker plus PipeWire capture via the desktop portal, so calls can share a screen on Wayland and X11.
- Profile backup & restore — export an entire account (settings, session and
addons) to a
.tar.gzand import it back. - Customisable keyboard shortcuts, an update checker, a storage manager with its own Clear cache, and lock-on-screen-lock.
- Performance & privacy controls — the rendering-engine switches that used to be hard-coded are now yours: turn GPU acceleration back on (or off), ignore the driver blocklist, pick a lower-memory process model, cap the JavaScript heap, choose the HTTP cache type/size, and shield your local IP from WebRTC leaks (Settings → Performance & Privacy).
- Network proxy — route Whatly through your system proxy, none (direct), or a manual SOCKS5 / HTTP proxy with optional credentials (Settings → Network & Startup).
- Start at login, interface scale and an optional custom window frame — have Whatly launch when you log in, set a UI scale factor without an environment variable, or replace the system title bar with Whatly's own slim one (frameless, off by default).
- Portal notifications — on Linux, notifications can go through the XDG desktop portal (Flatpak-friendly) or the system service; Automatic picks the right one.
- A first-run wizard — a short welcome that sets a few sensible defaults, then points at the QR code to sign in.
- A smarter system tray — an optional monochrome icon that matches your panel, an unread-count badge, and a connection-status dim when WhatsApp is offline.
- Follow the system light/dark theme, live, if you want the window chrome to track your desktop.
- A bug report you can actually file — F1 opens About; its Report a Bug button opens a GitHub issue with the version, commit, memory use of the whole process tree, and the recent log (including WhatsApp Web's console) already filled in.
- Windows 10+ support from a single codebase — platform-specific pieces are
behind
Q_OS_*guards, so Linux behaviour is unchanged. Native toast notifications, Win32 Caps Lock detection and a GUI-subsystem executable with icon/version resources. Every push is compile-checked by a Windows CI workflow. - Experimental macOS build — a CI job builds a
.appbundle and packages a.dmg, attached to each release. It is unsigned (first launch needs a right-click → Open) and not yet validated at runtime; feedback welcome. - Connection watchdog — WhatsApp Web's WebSocket can die or freeze, leaving the app stuck on "Connecting…" with messages that never send. A health probe now detects it and reloads the page automatically, capped at 3 attempts per hang so an unfixable cause (no disk space, network down) never turns into a reload loop.
- Self-updating User-Agent — the reported Chrome version is derived from the bundled Chromium instead of being hardcoded, so it can no longer go stale and get the client treated as an outdated browser. It follows Qt WebEngine upgrades automatically.
- "Identify as Whatly in linked devices" — linked sessions show up on your phone as "Whatly for Linux" (or the matching platform) with a desktop icon, instead of a generic "Google Chrome (Linux)". Applies to devices linked afterwards.
- "Close emoji/sticker panel when clicking outside" (opt-in) — WhatsApp Web otherwise keeps the expressions panel open until its button is pressed again.
- It no longer stalls a KDE logout, and Quit actually quits — the minimize-to-tray veto used to cancel the session-end close, so logging out waited on the app; a session-end close is now honoured as a real quit.
- Safer cache clearing — the "clear cache" action refuses any path that is not inside the app's own storage, so it can never run a recursive delete on your home directory.
The chat list is shown with the privacy blur on — that is the feature in action, not a redaction. More screenshots appear next to the features they show, below.
- Light and Dark themes with automatic, time-based switching — or follow the system
- Native desktop notifications and a configurable custom popup
- Global keyboard shortcuts
- Built-in download manager
- Mute audio, disable notifications, do-not-disturb
- App lock, with auto-lock after an interval
- Hardware-permission manager (camera, microphone, …)
- Spell checker with 31 dictionaries, several active at once
- Fine-grained control over the web view:
- Full-view mode, configurable page zoom per window state
- Native vs. custom notifications, configurable popup timeout
- Disable auto-playback of media
- Minimize to tray on start, single-click hide to tray
- Switchable download location
- Configurable close-button action and User-Agent
- Storage management (clear residual cache and persistent data — safely)
- Close emoji/sticker panel when clicking outside (opt-in)
- Identify as Whatly in linked devices, with a desktop icon
Snap — on any distribution with snapd:
snap install whatlyA few interfaces do not connect automatically. For voice and video calls, connect the camera and microphone (and, to keep the screen awake during a call, the screen-inhibit interface):
sudo snap connect whatly:camera
sudo snap connect whatly:audio-record
sudo snap connect whatly:screen-inhibit-control
# optional: access removable drives when attaching files
sudo snap connect whatly:removable-mediaFlatpak — a whatly.flatpak bundle is attached to each
release:
flatpak install --user whatly.flatpak
flatpak run net.shakaran.whatlyTo build it yourself: packaging/flatpak/build-flatpak.sh.
AppImage — download Whatly-<version>-x86_64.AppImage from the
release, make it executable and
run it. The matching .zsync gives it delta auto-updates via AppImageUpdate:
chmod +x Whatly-*-x86_64.AppImage
./Whatly-*-x86_64.AppImageDebian/Ubuntu and Fedora — debian/ and packaging/rpm/whatly.spec build a
native .deb and RPM; see packaging/README.md.
Arch (AUR) — the community whatsie-git
package (maintained by M0Rf30) tracks the upstream
WhatSie project, not this fork:
yay -S whatsie-gitPrebuilt binaries are attached to each release; otherwise build from source.
Grab the build from the latest release, or the artifact from the Windows Build CI run. See docs/WINDOWS_BUILD.md to build it yourself.
A Whatly-<version>-macos.dmg is attached to each
release, built by the macOS
Build CI job. It is unsigned, so the first launch needs a right-click →
Open (or removing the quarantine flag). It has not yet been validated at
runtime — notifications, tray and calls in particular — so treat it as a
community-testing preview and please report back. Build it yourself with CMake +
Qt 6 exactly as on Linux.
On Linux, Whatly runs Chromium with the GPU disabled by default. This avoids a class of blank-window and crash-on-start bugs on some NVIDIA / Wayland / Flatpak setups, at the cost of GPU-accelerated rendering. The easiest way to change this is Settings → Performance & Privacy: turn GPU acceleration back on, ignore the driver blocklist, or pick the workaround that fits your setup — no environment variable needed (the change applies after a restart).
If you prefer, you can still drive Chromium directly with your own flags (a
non-empty value takes over the base flags completely; leave out
--disable-gpu):
QTWEBENGINE_CHROMIUM_FLAGS="--disable-translate --no-sandbox" whatlyOn a HiDPI / 4K display where everything looks too small, set QT_SCALE_FACTOR.
Whatly mirrors it into WhatsApp Web's own scaling, so a single value enlarges
both the window chrome and the page:
QT_SCALE_FACTOR=1.5 whatlyTo let WhatsApp Web run at your display's full refresh rate instead of Chromium's
default cap, set WHATLY_MAX_FPS to any non-zero value:
WHATLY_MAX_FPS=1 whatlyThe interface font size (menus, dialogs, Settings — not the chat text) can also be set from Settings → Appearance → Interface font size; for the chat text itself, use the zoom.
Whatly comes with CLI support to interact with an already-running instance.
Run whatly -h to see them all.
Usage: whatly [options]
Options:
-h, --help Displays help on commandline options
-v, --version Displays version information
-b, --build-info Shows detailed current build information
-w, --show-window Show main window of a running instance
-s, --open-settings Open the Settings dialog in a running instance
-l, --lock-app Lock a running instance
-i, --open-about Open the About dialog in a running instance
--open-scheduled Open the scheduled-messages dialog in a running instance
-t, --toggle-theme Toggle dark/light theme in a running instance
-r, --reload-app Reload the app in a running instance
-n, --new-chat Open the new-chat prompt in a running instance
-u, --unread Print the current unread message count and exit
-p, --profile <name> Run as a separate account, in its own window
--migrate-from <name> [--dry-run]
Copy settings and the logged-in session from a
previous install (e.g. the older "whatsie" build)
Three independent ways to be signed in to more than one account:
- Separate windows —
whatly --profile=workruns a wholly separate account with its own WhatsApp session, its own settings file and its own window. Run as many as you like side by side; launching the same profile again just raises the one already running. Without the flag, everything is exactly as before. - Tabs in one window — click the + on the account tab bar to add another account inside the current window. Right-click a tab to rename or remove it. The tray icon's unread badge is the total across every tab.
- Grid view — show every in-window account at once in a tiled grid instead of one at a time. Toggle it from the tray menu (Grid view / Tabbed view) or with Ctrl+G; the choice is remembered.
The interface follows your system locale and can be changed in Settings → General settings → Interface language (takes effect after a restart). 15 languages ship with the app.
Only
it_ITwas translated by a human. The rest were machine-generated without native-speaker review and will contain mistakes. Corrections are very welcome and need no C++ — see docs/TRANSLATIONS.md.This covers Whatly's own interface only. The language of the chats comes from WhatsApp Web and cannot be changed here.
Whatly's own shortcuts. The same list is available in the app under Settings → Global shortcuts → Show shortcuts.
| Shortcut | Action |
|---|---|
| Ctrl+N | New chat |
| Ctrl+P | Settings |
| Ctrl+T | Toggle light/dark theme |
| Ctrl+L | Lock the app |
| Ctrl+W | Minimize to tray |
| Ctrl+Q | Quit |
| F5 | Reload |
| F11 | Toggle fullscreen |
| Ctrl++ / - | Zoom in / out |
| Ctrl+0 | Reset zoom |
WhatsApp Web has its own shortcuts too — for searching, starting a chat, marking as unread and so on. Those come from WhatsApp itself, not from Whatly, so they will never show up in the list above; they simply work inside the app as they do in a browser.
- git, ninja-build
- cmake >= 3.24, or >= 4.0 if the bundled
libnotify-qtsubmodule has to be built — that happens whenevernotify-qt6is not installed as a system package, and the submodule itself requires CMake 4.0 - Qt6 >= 6.10 (qt6-base-dev, qt6-webengine-dev, qt6-positioning-dev)
- C++17 compiler (GCC 7+, Clang 5+)
- libx11-dev
Qt 6.10 is a hard floor. Debian 13, Ubuntu 24.04 and Linux Mint 22.x still ship Qt 6.4, which will not work: the code needs
QWebEnginePermission(Qt 6.8+), and WhatsApp Web refuses to load in the older Chromium those builds bundle. On those distributions, install a newer Qt with the official Qt online installer (select the Qt WebEngine and Qt Positioning modules) and point CMake at it with-DCMAKE_PREFIX_PATH=/path/to/Qt/6.10.0/gcc_64.
Ubuntu/Debian:
sudo apt-get install cmake ninja-build qt6-base-dev qt6-webengine-dev \
qt6-positioning-dev libx11-dev build-essentialFedora:
sudo dnf install cmake ninja-build qt6-qtbase-devel qt6-qtwebengine-devel \
qt6-qttools-devel libX11-devel gcc-c++Arch Linux:
sudo pacman -S cmake ninja qt6-base qt6-webengine qt6-positioningThe project uses CMake (with the Ninja generator) and bundles libnotify-qt
as a git submodule, so remember to initialise submodules after cloning.
git clone https://github.com/shakaran/whatly.git
cd whatly
git submodule update --init --recursive
# Configure and build (Release)
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel
# Run
./build/whatlyThe install prefix is baked in at configure time, so set
CMAKE_INSTALL_PREFIX when configuring, then install.
# Install into your home (no sudo, ~/.local/bin is usually on PATH)
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="$HOME/.local"
cmake --build build --parallel
cmake --install build
# OR install system-wide to /usr (needs sudo)
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr
cmake --build build --parallel
sudo cmake --install buildComing from the older WhatSie build? Your settings and logged-in session are copied over automatically on first run. If anything is missed,
whatly --migrate-from=whatsie(add--dry-runto preview) does it by hand.
| Problem | Solution |
|---|---|
| CMake not found | sudo apt install cmake |
Qt 6.10 or newer is required (distro ships Qt 6.4) |
Install a newer Qt with the Qt online installer and configure with -DCMAKE_PREFIX_PATH=/path/to/Qt/6.10.0/gcc_64. |
libnotify-qt submodule requires CMake 4.0 |
Install notify-qt6 from your distribution (the submodule is then not built), or upgrade CMake. |
| Qt6 not found | sudo apt install qt6-base-dev qt6-webengine-dev (or export CMAKE_PREFIX_PATH=/usr/lib/cmake/Qt6) |
| Ninja not found | sudo apt install ninja-build |
notify-qt submodule missing |
git submodule update --init --recursive |
| Permission denied on install | Reconfigure with -DCMAKE_INSTALL_PREFIX=$HOME/.local (no sudo) |
For detailed build instructions, see docs/BUILD_QUICK_REFERENCE.md
and docs/CMAKE_MIGRATION.md.
There is a QtTest suite covering the headless parts of the app — the helpers, the injected-script generators, the scheduled-message queue, the sun calculations, identicons, palettes, dictionary resolution and the About/Rate screens' assets. It is off by default and builds without the main window, so it is quick and runs headless:
cmake -B build -DWHATLY_TESTS=ON
cmake --build build --target tst_ui_assets tst_logic
QT_QPA_PLATFORM=offscreen ctest --test-dir build --output-on-failureIt runs in CI on every push (.github/workflows/tests.yml).
Coverage. With gcovr installed, tools/coverage.sh builds the suite
instrumented, runs it and writes an HTML report. The unit-tested modules (the
logic + light-widget layer, ~1.7k lines) sit at ~92% line / ~95% function
coverage. The only thing deliberately excluded there is one modal error dialog
that blocks on user interaction and so can't run headless (marked with a
GCOVR_EXCL comment).
Integration coverage. tools/integration.sh drives the real,
coverage-instrumented binary headless — the CLI, app bootstrap, the main window,
the Qt WebEngine setup (it loads the QR/link page) and the dialogs reachable over
the single-instance IPC — under a throwaway HOME, without logging in. An
in-process tst_settings also builds the whole app to construct SettingsWidget
and drive every control (run it locally for coverage — it is not part of the CI
run, whose headless environment aborts it). Combined with the unit tests this
brings whole-app line coverage to ~65% (src/main.cpp 0% → ~79%,
settingswidget.cpp → ~82%). It
cannot go much higher: the rest is Qt WebEngine internals and the chat/messaging
features, which are gated behind a real WhatsApp session that a headless CI
cannot provide.
- Windows 10 or later
- Visual Studio 2022 with the "Desktop development with C++" workload (MSVC is required — Qt WebEngine does not support MinGW)
- Qt 6.10+ for MSVC 64-bit, with the Qt WebEngine, Qt WebChannel and Qt Positioning modules
- git, cmake >= 3.24
git clone https://github.com/shakaran/whatly.git
cd whatly
cmake -G "Visual Studio 17 2022" -A x64 -B build -DCMAKE_PREFIX_PATH=C:\Qt\6.10.0\msvc2022_64
cmake --build build --config Release
C:\Qt\6.10.0\msvc2022_64\bin\windeployqt.exe build\Release\whatly.exe
build\Release\whatly.exeFor detailed instructions, see docs/WINDOWS_BUILD.md. Every push is also compile-checked on Windows by the Windows Build GitHub Actions workflow, which uploads a ready-to-run build as an artifact.
Whatly is an MIT-licensed fork of WhatSie by Keshav Bhatt (ktechpit.com); all upstream copyright and authorship is preserved. The fork is maintained by Ángel Guzmán Maeso.
Contributions. Some features build on work by
Gert Bolten Maizonave (gbmaizol),
contributed as pull requests to upstream WhatSie: identifying the app in the
phone's linked-devices list
(#324), the fix for the dark
theme resetting across restarts
(#326), and Windows support
(#321).
Released under the MIT License. Not affiliated with WhatsApp or Meta; "WhatsApp" is a trademark of its respective owner.
Whatly is free and MIT-licensed, developed in spare time. If it is useful to you, a sponsorship or a one-off tip keeps it maintained — and directly funds new features and packaging.



























