# Disk file home Source: https://selfstore.dev/docs/disk Back up to a file on the user's own disk with one call - store.connectFile() - the truly zero-backend durable home. The disk file is the purest form of the promise: the durable home is a file on the user's own machine, and **nothing** else is involved. No account, no cloud, no consent screen, no backend of any size. ## One call ```ts const outcome = await store.connectFile(); // opens the browser's save dialog switch (outcome) { case 'started': break; // new file: this device's data now lives in it case 'merged': break; // existing backup: folded with this device case 'manual': break; // no File System Access here (see below) case 'cancelled': break; // the user closed the picker } ``` `connectFile()` needs a user gesture (a click), because the File System Access API does. From then on, every debounced save also writes that file, encrypted if [`protect()`](https://selfstore.dev/docs/quick-start) is on, and the store re-acquires the handle on the next visit without asking again. Pass a password for an already encrypted file: `store.connectFile({ password })`. ## Browser support, honestly File System Access ships in Chromium browsers (Chrome, Edge, Brave, Arc...). Firefox and Safari do not expose it, so there `connectFile()` returns `'manual'`: fall back to a downloaded file the user saves and re-imports. ```ts if ((await store.connectFile()) === 'manual') { await store.downloadBackup(); // they save it themselves // ...later: await store.importBackup(pickedFile); } ``` Same format, same encryption; the difference is one gesture per backup instead of zero. ## Inside a desktop shell A native webview usually has no File System Access at all - macOS and Linux shells embed WebKit - so packaging your app would lose this home in the one place writing a real file is easiest. Hand the shell its own filesystem and dialog calls once and `connectFile()` comes back, on a path rather than a handle: ```ts import { useDesktopFiles } from 'selfstore'; useDesktopFiles({ readFile, writeFile, stat, exists, save, open }); ``` The path outlives the session, so the app reopens on its file with nothing asked of the user. The whole integration is on [desktop shell](https://selfstore.dev/docs/desktop). ## Why this home matters Every other storage story ultimately asks the user to trust someone's server. A disk file asks them to trust their own disk. For a local-first app it is the reference implementation of "your data is yours": auditable with an archive tool, movable on a USB stick, restorable anywhere the [format](https://selfstore.dev/docs/format) is implemented. ## On the advanced store If you own the data model and drive [`createLocalStore`](https://selfstore.dev/docs/advanced) directly, the same home is `fileTarget` from the advanced subpath: ```ts import { fileTarget } from 'selfstore/advanced'; const target = await fileTarget.connect({ kv: cache.kv, fileName: 'my-app.zip' }); await store.attachTarget(target, { password }); // restoreTarget: (kind) => kind === 'file' ? fileTarget.fromSession({ kv: cache.kv }) : null ``` Map of this site for a model: https://selfstore.dev/llms.txt Every page in one file: https://selfstore.dev/llms-full.txt