* fix(e2e): stabilize undo task delete sync test Two flakiness sources fixed: - Click on task element could activate title inline editor, causing Backspace to edit text instead of triggering delete. Now clicks the drag handle which calls focusSelf() without entering edit mode. - Replaced deleteTask helper with inline sequence to avoid wasting 2s of the 5s undo snackbar window on dialog-detection timeout. * refactor: address code review findings from 2026-02-03 - Extract getBreakCycle helper to replace error-prone `cycle - 1 || 1` pattern at 3 call sites - Add clarifying comment on intentionally broad 'timed out' match - Reduce Pomodoro E2E test from 9 to 5 sessions (sufficient coverage) - Remove dead _isTransientNetworkError wrapper from DropboxApi - Extract stubWindowConfirm helper in task reducer tests * fix(sync): prevent Formly from clearing provider config on show (#6345) resetOnHide: true caused Formly to reset field values when provider fieldGroups transitioned from hidden to visible, discarding user input if sync was enabled before selecting a provider. * fix(tasks): fix huge space between emoji and text in tag/project menus Use matMenuItemIcon attribute on emoji spans so they project into the icon slot of mat-menu-item instead of the text slot. Update emoji icon sizing to 24x24px to match mat-icon and add overflow: hidden. Closes #5977 * fix(tasks): guard against undefined task entities in selectors and archive (#6359) Prevent TypeError crashes (reading 'dueWithTime', 'dueDay', 'issueProviderId') caused by orphaned IDs in NgRx state. Fix archive merge to deduplicate IDs, filter orphans, and use correct entity precedence (young over old). Add defensive null guards to selectors and archive/task service methods. * fix(tasks): guard against undefined task in mainListTasksInProject$ (#6360) * fix(tasks): detect and sanitize orphaned task IDs to prevent startup crashes (#6359, #6360) Orphaned task IDs (entries in task.ids without matching entities) caused TypeError on app startup. Fix addresses three layers: validation now flags orphaned IDs instead of silently skipping them, loadAllData sanitizes IDs on load as a safety net, and data repair no longer crashes when encountering orphaned IDs it's trying to fix. * fix(sync): prevent recurring task duplication across clients Remove SuperSync special-case that bypassed initial sync wait, causing repeatable task effects to fire before sync completed. Add post-sync cleanup effect that detects and removes stale duplicate repeat instances when multiple active instances exist for the same repeat config. * fix(sync): restore WebDAV provider compatibility warning text * feat(sync): mark WebDAV and LocalFile sync options as experimental * feat(plugins): add UI Kit with inject-first CSS strategy for iframe plugins Introduce a lightweight CSS reset (UI Kit) that auto-styles basic HTML elements in plugin iframes to match the host app theme. Injected after <head> so plugin styles always win by source order. UI Kit provides: element resets (body, headings, buttons, inputs, tables, links, code, lists, hr), .btn-primary/.btn-outline button variants, and .card/.card-clickable components. All bundled plugins updated to use UI Kit classes, removing redundant custom CSS (-542 lines net). Pico CSS removed from automations plugin. sync-md converted from hardcoded colors to host theme variables. * feat(plugins): extract shared CSS utilities into UI Kit Move .text-muted, .text-primary, .page-fade and @keyframes fadeIn from plugin CSS into the UI Kit so all iframe plugins get them automatically. Add box-shadow focus ring to input:focus for better accessibility. Remove per-plugin focus overrides now covered by the UI Kit.
12 KiB
User Data
The User Data concept applies only to the desktop (Electron) application. The web app stores data in browser storage (IndexedDB and localStorage) instead. See 3.05-Web-App-vs-Desktop for web vs desktop differences. For an overview of how import, export, backups, and sync work from a user perspective, see 4.23-Managing-Your-Data.
What Data Is Included
A full backup or export includes all application data: tasks (active and archived), projects, tags, time-tracking state, global configuration, notes, reminders, metrics, simple counters, planner and board state, task repeat configurations, issue-provider settings, plugin user data, and both archive tiers (recent and old). No data is excluded from a complete backup or export.
Purpose of the User Data Folder
The User Data Folder is the application data directory where the desktop app stores:
- All user data, settings, and configurations
- Automatic backups
- Custom theme file (
styles.css) - IndexedDB and localStorage data (managed by Electron)
Default Location by Platform
| Platform | Location |
|---|---|
| macOS | ~/Library/Application Support/superProductivity/ |
| Windows | C:\Users\<YOUR_USER_NAME>\AppData\Roaming\superProductivity/ or %APPDATA%\superProductivity |
| Linux | ~/.config/superProductivity/ |
The path is shown in the UI under Settings → Automatic Backups (without the backups subfolder) and is printed when the app is started from the command line.
Custom Folder Location
You can specify a custom user data directory using the --user-data-dir command-line parameter:
superproductivity --user-data-dir=/path/to/my/data
Trailing slashes are stripped. The custom path is used instead of the default for the session.
Snap Packages (Linux)
For Snap packages on Linux, the app uses the SNAP_USER_COMMON directory so that data is not accessed by the Snap update process. The effective path is $SNAP_USER_COMMON/.config/superProductivity (or the app name equivalent).
Windows Store
The Windows Store build uses a different path that includes the Windows Store package identifier (under Local\Packages\...\LocalCache\Roaming instead of Roaming).
Directory Structure
backups/ Subdirectory
- Stores automatic backup files (JSON).
- Location:
{userData}/backups/. - One backup per day; filename format
YYYY-MM-DD.json.
styles.css (optional)
- Custom theme file for desktop styling.
- Must be created manually by the user and placed directly in the User Data Folder (not in a subfolder).
- Loaded by the main process and injected into the renderer; invalid CSS may fail to load and is logged.
IndexedDB and localStorage (Electron-managed)
- IndexedDB databases and localStorage entries live in platform-specific locations under the userData path.
- Managed by Electron; do not move or edit these files manually.
File Types and Formats
JSON Backup Files
- Format:
YYYY-MM-DD.json. - Content: Complete application state serialized as JSON.
- Naming: One file per calendar day (e.g.
2025-01-15.json).
CSS Theme File
- File:
styles.css(exact name required). - Purpose: Custom CSS for theming; user-created and optional.
IndexedDB Databases
- SUP_OPS (current, version 4): Main database. Object stores:
ops,state_cache,import_backup,vector_clock,archive_young,archive_old. Holds operations log, state snapshots, vector clocks, and archives. - pf: Legacy database used for migration and recovery.
- SUPPluginCache: Plugin cache.
localStorage Keys
UI and app state stored with keys such as:
SUP_UI_HELPER,SUP_ACTION_LOG,SUP_LAST_ERROR_ACTION_LOGSUP_IS_PROJECT_LIST_EXPANDED,SUP_IS_TAG_LIST_EXPANDEDDARK_MODE,SUP_NAV_SIDEBAR_EXPANDED,SUP_NAV_SIDEBAR_WIDTH,SUP_RIGHT_PANEL_WIDTHSUP_IS_ADD_TO_BOTTOM, and others (seestorage-keys.const.tsfor the full set).
Backup Behavior
Automatic backups: When enabled in settings, the app creates a backup on a schedule (default: every 5 minutes). Storage location depends on platform:
| Platform | Where automatic backups are stored |
|---|---|
| Electron (desktop) | {userData}/backups/ as one JSON file per calendar day (YYYY-MM-DD.json) |
| Android | IndexedDB with key backup (single entry, overwritten) |
| iOS | Capacitor Filesystem API: super-productivity-backup.json in Directory.Data |
| Web | No automatic file backups; use "Export data" to download a file manually |
Manual backups: (1) Create manual backup in Settings → Sync & Export creates a backup using the same mechanism as automatic backups (platform-dependent location). (2) Safety backups are created automatically before certain sync operations; the app keeps a limited number of slots (e.g. two most recent, one first from today, one first from day before). (3) Export data downloads a complete backup JSON file to a path you choose (or the browser download folder on web).
What is included: All application data is included in backups and exports; nothing is excluded. When archives are included (e.g. when using "Export data" with full backup), both archive_young and archive_old are part of the file. A separate import backup (pre-import state) is stored in IndexedDB (import_backup store) only for recovery if an import fails; it is not part of the user-visible backup set.
Import and Export
Export: Export produces a snapshot of the current state at the time of export. The file is JSON containing (or wrapping) the full application state. Relationships are preserved by ID references (e.g. tasks reference projectId and tagIds; subtasks reference parentId). Export is available via Settings → Sync & Export → Import/Export (e.g. "Export data" / download backup).
Import: The app accepts a full backup in the same format (complete application state, optionally wrapped with timestamp and version). Supported structures: (1) the raw complete state object, or (2) a wrapper object with data, timestamp, and crossModelVersion where data is the complete state. Legacy V1 format (e.g. config + tasks array) is detected but no longer supported; the user is shown an alert that migration is not supported. Before applying import, the app validates the data (structure and cross-entity relationships). If validation fails, automatic repair may run when possible (e.g. fixing orphaned tasks, invalid project/tag references, missing archive structures). If the backup’s encryption state differs from the current app (encrypted vs unencrypted), the app shows a confirmation dialog before importing. After import, current state is replaced; archive data is written to IndexedDB. See 2.02-Restore-Data-From-Backup for how to perform a restore.
Sync
Strategy: The app uses local-first, operation-based sync. The local device is the source of truth; sync exchanges operations (changes) rather than full state files each time. This reduces payload size and enables entity-level conflict detection.
Providers: Four sync providers are supported: SuperSync (server-based operation sync; very new, still in beta), WebDAV (file-based), Dropbox (file-based), and Local file (file-based, Electron/Android). File-based providers store a single sync file (e.g. sync-data.json) containing a full state snapshot plus a buffer of recent operations and a vector clock for causality.
Conflict resolution: Conflicts are detected using vector clocks (same entity changed in two places before sync). Resolution is last-write-wins (LWW): the operation with the newer timestamp wins; if timestamps are equal, the remote (server) side wins. When local wins, the app creates a new update operation so local state is propagated on the next sync. Identical conflicts (e.g. both sides deleted the same entity or made the same change) are auto-resolved without user action. In first-sync situations where both local and remote already have data, the app may show a dialog to choose use local or use remote. After resolution, state is validated and repaired as needed.
User-Editable Vs System-Managed
User-editable:
- styles.css — Create and edit for custom themes.
- Backup files — Can be restored via Settings → Sync & Export → Import/Export → Import from file (see 2.02-Restore-Data-From-Backup).
System-managed (do not edit manually):
- IndexedDB databases.
- localStorage entries.
- Active backup files (readable as JSON but manual editing is not recommended).
Size Limits and Quota
Client-side IndexedDB
- When
QuotaExceededErroroccurs, the app triggers emergency compaction (24-hour retention instead of 7 days) and uses a circuit breaker to avoid infinite retries. - Browser/OS quota and available disk space apply.
SuperSync Server (if Used; beta)
- Default quota: 100 MB per user.
- Automatic cleanup when quota is exceeded.
Permissions
- The app needs normal read/write access to the User Data Folder. Default locations are under the user's home or app data directory; no administrator/root rights are required.
- Plugins that need file system access require the
nodeExecutionpermission and explicit user consent.
Recovery and Repair
Automatic Data Repair
- Validation runs at several points in the operation lifecycle.
- Repairs issues such as orphaned tasks, invalid references, and inconsistent relationships; creates
REPAIRoperations for the log.
Disaster Recovery
- If the main database (
SUP_OPS) is missing or corrupted, the app attempts to load from the legacypfdatabase and run genesis migration. - If recovery fails, a full re-sync (or restore from backup) is required.
Backup Restoration
- Restore from a backup file in
backups/via Settings → Sync & Export → Import/Export → Import from file. See 2.02-Restore-Data-From-Backup.
Sync State Corrupted
- When an operation cannot be applied because of missing dependencies, the app throws
SyncStateCorruptedErrorand expects a full re-sync to restore consistent state.
Configuration and Versioning
- There are no separate config files in the User Data Folder. Configuration is stored in IndexedDB (
SUP_OPS,state_cache) and in localStorage (SUP_*and related keys). - Database version:
SUP_OPSis at schema version 4. - Application version: Defined in the build (e.g.
src/environments/versions.ts), not stored in the User Data Folder. - Backup files: Each JSON file carries full state; naming is by date only.
Application Access (Desktop)
- Main process: Path obtained via Electron
app.getPath('userData'); custom path set withapp.setPath('userData', path)when--user-data-diror Snap logic is used. - Renderer: Path is exposed via IPC (e.g.
getUserDataPath()). - Backups and file sync: Node.js
fsAPIs (e.g.readFileSync,writeFileSync,readdirSync,statSync,unlinkSync) are used for backup and local file sync.
Notes
- Web app: Data lives in browser storage only; there is no User Data Folder. See 3.05-Web-App-vs-Desktop.
- Custom WebDAV syncing: As an alternative to built-in sync, you can sync the contents of the User Data Folder using external WebDAV or cloud sync tools.
- Themes: Example themes and theme-creation guidance: super-productivity-themes.