docs/wiki/3.05-Web-App-vs-Desktop.md
This reference enumerates functional differences and limitations of the web app compared with the desktop (Electron) app. Most limitations stem from browser security (CORS, CSP, sandboxing) rather than intentional feature removal.
Plugins that require Node.js execution (elevated permissions) are disabled in the web version. When such a plugin is loaded, the app shows a disabled placeholder with an error stating the plugin requires the desktop version.
Calendar providers can be disabled for the web app or Android app via an isDisabledForWebApp flag to avoid CORS and WebView failures. When this flag is set and the app runs in a browser or Android WebView, calendar event requests return empty results instead of performing the HTTP request. The UI shows a prominent warning that calendar integration will likely not work in the browser or Android app and recommends downloading the desktop version.
In the web version, time tracking only works while the app is open. Idle time tracking in the browser requires the Super Productivity Chrome Extension to be installed.
WebDAV sync and calendar integration are likely to fail in the browser due to CORS. The app detects CORS-related failures and can show localized messages suggesting the user check server configuration. The desktop app can bypass CORS for these requests; the web app cannot.
The web app depends on modern browser support for:
window.crypto.getRandomValues and window.crypto.subtle.digest.crypto.subtle) is only available in secure contexts (HTTPS). The app shows alerts when WebCrypto is unavailable or when run over non-HTTPS.The web version uses BroadcastChannel to prevent multiple tabs from running the app at once. If another tab already has the app open, the new tab shows a blocker message asking the user to close one of the tabs.
The web app requests persistent storage from the browser. If the request is denied, the user sees a warning that data may be lost. Denial is surfaced via a snack notification.
The app uses the Storage API to estimate usage and quota. When available space falls to 333 MiB or less, the user is alerted that disk space is low and the app may be affected.
When IndexedDB quota is exceeded, the app triggers emergency compaction with reduced retention (24 hours instead of 7 days) and uses a circuit breaker to avoid infinite retry loops.
The web app registers a Service Worker for offline caching (PWA). This is disabled for Electron and Android. Background behavior is limited to what the browser's Service Worker API allows.
These limits are enforced by the sync server; they affect web users who sync:
The desktop app disables background throttling for its window. The web app is subject to the browser's background tab throttling, which can affect timer accuracy and background task execution when the tab is in the background.
The web app uses a Service Worker (production builds) to cache assets for limited offline use. Full offline behavior is more limited than on desktop and Android. The app shows an offline banner when the network is unavailable.
Iframe plugins receive a filtered window.PluginAPI object injected into index.html.
The iframe can use the injected task/project/tag APIs, dialog and notification APIs,
navigation helpers, persistence helpers, registration helpers, counters, and action
dispatch. APIs not injected into the iframe are unavailable, even if they exist on the
host-side plugin bridge.
executeNodeScript() is proxied through the host bridge for iframe plugins when
the desktop app grants the plugin nodeExecution permission. The desktop app
currently grants this only to packaged built-in plugins whose manifest can be
verified by the main process.
Iframe plugins are isolated from the host page:
allow-same-origin, so iframe content has an opaque origin.postMessage bridge.index.html for portable iframe plugins. Arbitrary extra files from uploaded plugin ZIPs are not served to the iframe; external URLs depend on the app/runtime CSP.Jira integration and idle time tracking in the web version require the Super Productivity Chrome Extension to be installed.
For self-hosted Jira instances where the server is configured with appropriate CORS headers, the extension requirement can be bypassed: enable Fetch Jira directly from the browser (bypass extension) in the Jira advanced settings. When active, the app sends API requests directly from the browser instead of routing them through the extension. This option has no effect in the desktop app or on Android.
If the Jira API is reachable at a different host than the public issue links (e.g. an internal API endpoint vs. a public URL), set Alternative host for Jira links to the public host. That value is used only for constructing browser URLs in task details, not for API calls.
The web version does not have:
Certain UI elements tied to these features are hidden in the web build via platform-specific CSS or logic.
NS_ERROR_DOM_QUOTA_REACHED, Safari code 22) and triggers emergency compaction.For installation and download options, see [[2.01-Downloads and Install]]. For sync backends and limitations, see [[2.09-Configure-Sync-Backend]].