cairn
A self-hosted, browser-only personal file store. Upload from one device, browse and download from another — the server only ever holds ciphertext.
Read the case studyCase study: cairn →- Chunked streaming AEAD (libsodium secretstream, XChaCha20-Poly1305, 4MB frames) — built chunked from day one so large files never need a whole-blob format migration later
- Two separate secrets: a server-checked access password for the front door, and a vault passphrase that never leaves the browser (Argon2id → 256-bit key)
- Filename, folder path and mimetype live inside a per-file encrypted envelope — the server's database has no plaintext name or path column at all
- Virtual folders: no folder objects server-side, the tree is derived client-side from decrypted paths
- Vault key cached per device as a non-extractable WebCrypto wrapping key in IndexedDB, so reopening the tab doesn't mean retyping the passphrase
- Truncation detection via secretstream's final tag — a download cut short by the network fails loudly instead of yielding a quietly corrupt file
- SQLite metadata and ciphertext blobs on separate mounts, split by how often each needs backing up
The third answer to “how do I move a file,” next to flit and wisp: flit is realtime and stores nothing, wisp is async and forgets after one retrieval, cairn is the one that keeps things. Many files, many devices, no expiry, browsable like a small personal cloud drive — without a sync engine, sharing permissions or an account system.
It shares its siblings’ crypto posture: everything is encrypted in the browser and the server sees ciphertext, a byte count and a timestamp. The difference is that the files have to survive indefinitely and be big enough to be annoying (video, backups), so the encryption is chunked and streaming rather than whole-blob.
Deliberately not a Dropbox clone. No sync, no sharing links, no multi-user — wisp already owns “share a file with someone.” Rename/move, local caching and thumbnails are not built yet.