# 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\\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: ```bash 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_LOG` - `SUP_IS_PROJECT_LIST_EXPANDED`, `SUP_IS_TAG_LIST_EXPANDED` - `DARK_MODE`, `SUP_NAV_SIDEBAR_EXPANDED`, `SUP_NAV_SIDEBAR_WIDTH`, `SUP_RIGHT_PANEL_WIDTH` - `SUP_IS_ADD_TO_BOTTOM`, and others (see `storage-keys.const.ts` for 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 `QuotaExceededError` occurs, 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 `nodeExecution` permission 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 `REPAIR` operations for the log. ### Disaster Recovery - If the main database (`SUP_OPS`) is missing or corrupted, the app attempts to load from the legacy `pf` database 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 `SyncStateCorruptedError` and 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_OPS` is 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 with `app.setPath('userData', path)` when `--user-data-dir` or Snap logic is used. - **Renderer:** Path is exposed via IPC (e.g. `getUserDataPath()`). - **Backups and file sync:** Node.js `fs` APIs (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](https://github.com/super-productivity/super-productivity-themes).