Backup, Export, and Restore

Backup is for recovery. Export is for user ownership and interoperability. They can share code, but they are not the same product feature.

FeatureUser expectationFormat
CSV exportinspect data in spreadsheetslossy but human-friendly
JSON exportmove data between app versions or toolsstructured and readable
SQLite exportpreserve relational structuredurable app document
Encrypted backuprestore private data latercomplete and protected
Restorereplace or merge local state safelyvalidated import path

SQLite Backup Options

Use the online backup API or VACUUM INTO for live databases. Avoid naive file copy while the DB is open in WAL mode.

VACUUM INTO 'backup.sqlite';

For very large databases, expose progress and allow cancellation. After backup, open the backup separately and run integrity checks.

PRAGMA integrity_check;
PRAGMA foreign_key_check;

Restore Drill

Every local-first app needs a clean-install restore drill:

  1. Create realistic data.
  2. Export or back up.
  3. Delete the app data directory or install on a clean device/profile.
  4. Restore.
  5. Verify counts, key rows, attachments, settings, and derived indexes.
  6. Run the app offline.

Import Policy

Before import, decide:

  • replace all local data
  • merge by stable IDs
  • create a new workspace/document
  • dry-run and show conflicts
  • refuse unsupported versions

Gotcha: Restore is a destructive operation when it replaces local data. Take a pre-restore backup first.