Desktop App — Overview
Audience: Support / QA / Management (engineers for the technical section) · Where in app: Download from Settings → Downloads; white-label via build flag · Plan availability: All plans (the desktop-app feature flag exists per package — verify)
The desktop app is a native Electron wrapper around the same Vue 3 frontend, with extras that browsers can't do well for team members who handle calls and chats. It is not a separate codebase — the renderer is the frontend app (same routes, stores, components). Electron adds native notifications, dedicated call/chat popup windows, auto-update, and per-agency white-label installers.
What it does
Gives agents a reliable, always-available client:
- A real ringtone for incoming calls (no browser autoplay blocking).
- Native OS notifications that escape the browser tab.
- A dedicated popup window for incoming calls (and optionally chats).
- A screen-share picker window during calls.
- Auto-update so non-technical staff stay current.
- White-label installers so agencies ship the app under their own brand.
How it works
The Electron main process (electron/main.ts) owns the windows and native integrations; the renderer loads the frontend (Vite HMR in dev, file:// in production). A preload script (electron/preload.ts) exposes a restricted ipcRenderer (on / off / send / invoke) over contextBridge so the renderer can ask the main process to open popups, show notifications, check for updates, etc. A single-instance lock prevents multiple copies running at once.
White-label is a build-time flag (__WHITE_LABEL__), not a runtime toggle and not a fork — WHITE_LABEL=true at build time swaps the app name, icon, bundle id, menu links, and update feed.
Desktop is synced from the frontend at release time, not per-PR. Don't copy frontend changes into desktop/ during frontend work. (Matches the engineering desktop service doc.)
Configuration & options
Windows
| Window | Purpose | Notes |
|---|---|---|
Main (win) | The full app — dashboard, chats, sessions, settings | Vite HMR in dev, file:// in prod |
Incoming call popup (call_window) | Accept/decline an incoming call | ~320×380, frameless, always-on-top |
Chat popup (chat_window) | Incoming chat request | ~350×148, frameless, top-right |
Screen-share (screen_share_window) | Pick a screen/window to share during a call | ~820×540 |
Notifications
- Native OS notifications (Electron Notification API) via the
show-notificationIPC channel. - Audio ringtone for incoming calls (autoplay always allowed).
- Taskbar/dock badge with unread count (
notification-count). - In-app toast (
DesktopToast.vue) and hot-lead banner (LeadNotificationBanner.vue). - A mute notifications toggle and per-event notification sounds.
- Built-in spell check with suggestions in text inputs.
Auto-update (electron-updater)
- Polls GitHub Releases roughly every 5 minutes once the app is ready.
- Shows download progress (with a taskbar progress bar); installs and restarts on completion.
- Manual "Check for Updates" lives in the app menu / Settings → About.
- The target repo depends on the white-label flag (Knock Knock vs. the agency's repo).
Launch at login
- Get/set via IPC (
launch-at-login-get/launch-at-login-set); on Windows this is registry-based.
Builds & white-label
| Build | Command | Brand | appId | Update repo |
|---|---|---|---|---|
| Standard | npm run build / npm run publish | Knock Knock App | com.knock-knockapp.app | KnockKnock GitHub |
| White-label | npm run build:next / npm run publish:next (WHITE_LABEL=true) | Next Level AI | com.nextlevelai.app | NextLevelAI GitHub |
White-label injects the app name, icon, bundle id, window title, menu links (e.g. web-app URL → app.nextlevelai.site), the auto-updater repo, and the default company name. The current white-label target is the "Next Level AI" brand.
Build targets (electron-builder)
- macOS: DMG + ZIP, x64 and arm64 (hardened runtime, notarization, camera/mic entitlements).
- Windows: NSIS installer, x64.
- Linux: AppImage.
- Publish provider: GitHub Releases (consumed by electron-updater).
Behaviors & edge cases
- Linux availability (QA/support discrepancy): an AppImage target is built, but the customer-facing Settings → Downloads screen and customer docs currently list Windows and macOS only. If a customer on Linux asks, confirm whether the Linux AppImage is exposed for their tenant before promising it. On Linux, GPU/hardware acceleration is disabled in the app to avoid Wayland/X crashes.
- macOS Gatekeeper: users may need to allow the app under System Settings → Privacy & Security the first time (unidentified-developer warning) unless notarized for that channel.
- White-label signing: agencies distributing outside the Knock Knock signing chain must provide their own signing certificates.
- Background updates require the app to be running; if it's closed it updates on next launch.
- Same app as web: because the renderer is the frontend, routes/stores/components behave identically — bugs reproduce in both unless they're Electron-specific (popups, notifications, update flow).
Web vs. desktop
| Feature | Web | Desktop |
|---|---|---|
| Incoming call UI | Modal | Dedicated popup window |
| Notifications | Browser permission | Native OS |
| Audio autoplay | Permission prompt | Always allowed |
| Updates | Reload | Auto-updater |
| White-label | Per-agency portal domain | Per-agency installer |
Plan & limits
- The desktop app is available on all plans in principle; the
desktop_appfeature flag exists onPackageModel— verify whether any tier gates it. - Desktop version (at time of writing): app version 0.7.9, Electron 37 — verify current.
Technical implementation
- Repo:
/home/bilal/Projects/knock-knock-app/desktop/. - Main process:
electron/main.ts(windows, IPC, single-instance lock, auto-update, CSP, notifications, screen capture). Preload:electron/preload.ts. - Build:
electron-builder.config.js(appId, targets, publish),vite.config.ts(injects__WHITE_LABEL__,__APP_VERSION__, etc.),package.jsonscripts (build,build:next,publish,publish:next). - CSP: the main process sets headers allowing Twilio/Stripe/Firebase/Socket.IO and the Knock Knock / white-label domains.
- See the engineering deep dive: /services/desktop. White-label branding overall: White-Label.