# 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:

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