# 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 backup path is shown in the UI under Settings → Automatic Backups (including 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/`.
- On desktop, automatic backup files use the filename format `YYYY-MM-DD_HHmmss.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_HHmmss.json` for desktop automatic backups.
- **Content:** Complete application state serialized as JSON.
- **Naming:** Timestamped by local date and time (e.g. `2025-01-15_143022.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). The interval and backup subdirectory are not configurable in the UI. Storage location depends on platform:

| Platform               | Where automatic backups are stored                                                                                                                                                           |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Electron (desktop)** | `{userData}/backups/` as timestamped JSON files (`YYYY-MM-DD_HHmmss.json`)                                                                                                                   |
| **Android**            | A native app-private SQLite store (`SupKeyValStore`, keys `backup` / `backup_prev` for the latest and previous slots), separate from the WebView IndexedDB so it survives IndexedDB eviction |
| **iOS**                | Capacitor Filesystem API: latest and previous JSON files in `Directory.Data`                                                                                                                 |
| **Web**                | No automatic file backups; use "Export data" to download a file manually                                                                                                                     |

On desktop, the **Maximum backup files** setting caps the number of timestamped automatic backup files kept in the `backups/` folder. Older files are deleted when the cap is exceeded. At the default cap, cleanup keeps the 30 most recent backup files plus up to one newest backup per day for the current day and previous 20 days, when files for those days exist. The exact file count can be lower because the daily backups often overlap with the 30 most recent files.

On mobile (Android/iOS), if the app launches with no local data but a usable on-device backup exists — the typical "blank app after the system evicted WebView storage" case — the newest usable backup is **restored automatically on startup**, without a prompt, with a snackbar reporting how many tasks and projects were restored. This only happens when the live store is genuinely empty; a deliberate in-app "delete all data" leaves a valid (empty) state and is not auto-restored. **Restore latest automatic backup** also remains available manually in Settings -> Sync & Backup -> Automatic Backups, which shows a **Last backup** timestamp so you can confirm you are protected; the manual restore replaces the current local data after confirmation. If sync is configured, restored data (auto or manual) is treated as a backup import: on the next sync it propagates to and overwrites your other synced devices, so use it as a recovery action rather than a routine one.

**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 in the Electron desktop app. Main-process grants are currently issued only for packaged built-in plugins whose manifests can be verified by the app; uploaded/community plugins declaring `nodeExecution` are rejected for now.

## 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 a synced operation cannot be applied cleanly, the app flags the sync state and re-validates; a full re-sync restores 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; desktop automatic backup naming includes date and time.

## 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).
