danrhodes5 downloadsBackup and restore your vault with verification, retention and optional encryption. Works on mobile and desktop.
Backup, restore and verification for your Obsidian vault, on desktop and mobile.
Rewind Vault keeps dated backups of your notes inside your vault, checks that they can really be restored, and lets you bring back a whole vault, a folder, a single note, or an older version of a note. Everything is configurable, and nothing it does can overwrite your live notes unless you explicitly ask.
.zip files you can open with any tool (unless you turn on encryption).restore/ folder by default, so your notes are never touched. Restoring into the vault itself is a deliberate choice, takes a safety snapshot first, and only replaces the files you tick.Rewind Vault is in the Obsidian community plugin store.
Requires Obsidian 1.4.0 or newer.
To build it yourself instead:
git clone https://github.com/danrhodes/Rewind-Vault.git
cd Rewind-Vault
npm install
npm run build
Then copy main.js and manifest.json into <your vault>/.obsidian/plugins/rewind-vault/ and enable the plugin.
Open the command palette and type "Rewind Vault":
| Command | What it does |
|---|---|
| Back up now | Backs up using your chosen automatic style (differential by default). The ribbon icon does the same. |
| Back up now (full) / (differential) | A complete backup, or only what changed since the last one. |
| Restore from a backup… | Opens the backup list; press Restore on a backup. |
| Browse backups | The backup list: search, compare, restore, verify, pin, repair, delete. |
| Verify the latest backup | Checks every file's SHA-256 against the backup's record. |
| Time machine for the current note | Every saved version of the open note: show changes, restore a copy, or replace the note. |
| Recover deleted files | Files you deleted since they were last backed up. |
| Vault time travel (read-only) | Look at the vault as it was at any backup, search it and read notes. Nothing is written. |
| Create a named milestone | A full backup with a name, kept until you delete it. |
| Copy / show / import settings | Move settings between devices as a link or QR code. |
With Show legacy commands turned on you also get: non-destructive backup, resume an interrupted backup, deep verification (follows the whole chain), a restore rehearsal, reset backup state, and updating the status note.
Restoring. Press Restore on a backup. You see the files that would be added and the files that differ from what you have now, each with a checkbox. By default everything goes to restore/<backup name>/ and your notes stay as they are. Choose "My vault" to restore in place: files that would replace your current ones start unticked, and ticking one is your consent to replace it. Before anything is written, a snapshot of the current vault is taken so the restore can be undone.
backup/ (configurable; never included in its own backups)
index.json list of backups
state.json what the vault looked like at the last backup
2026-10-07T21-24-00_full/
manifest.json what is in this backup, with checksums
part-001.zip part-002.zip …
2026-10-08T09-00-00_diff/
log.txt activity log (rotated by size)
restore/ restored files land here by default
Folder names are UTC times. Do not edit the backup folder by hand.
Exclude the backup folder from Obsidian Sync, iCloud, Dropbox and Git. Otherwise every device uploads copies of the same large files, and a sync conflict can damage a backup. Rewind Vault excludes the folder from its own backups, but it cannot stop another tool syncing it.
Settings > Rewind Vault has a section for each group. Desktop and mobile keep separate settings, so a vault shared between a laptop and a phone can behave differently on each.
| Section | What you can set |
|---|---|
| Basic | Backup on startup and delay, automatic style (off, full, differential, non-destructive), hidden files, legacy commands |
| Destination | Inside the vault or an external copy folder (desktop), backup folder, restore folder |
| ZIP | Files and size per ZIP part, splitting large output, compression level |
| Triggers | Startup, resume, timer, daily times, after N edits, idle, create/delete/rename, on close |
| Conditions | Minimum battery, skip when nothing changed, minimum free space, Wi-Fi only |
| Exclusions | Path patterns (gitignore style), hidden files, .obsidian, .git, node_modules, trash |
| Retention | Keep newest N, keep N days, daily/weekly/monthly, maximum folder size, pinned exempt |
| Encryption | On/off, passphrase handling, key-derivation strength |
| Verification | Check after each backup (off, L1, L2, L3), deep check schedule, what to do on failure |
| Safety | Snapshot before restoring, lock timeout, and the settings for the features below |
| Notifications | Silent, errors only, or verbose; status bar; log size |
| Misc | Settings passphrase, low-memory mode, keep screen on, chunk size |
Every setting is in the settings screen. If you turn on Keep a backup status note, a note with Dataview-readable properties shows the health of your backups.
A differential backup is built on the one before it, so restoring it needs the full backup and every differential up to it. Retention therefore never deletes a backup that a kept one depends on. The practical effect: with differential backups, "keep the newest 10" can leave more than 10 backups on disk until the next full backup lets the older chain go. If you want a hard limit, use Maximum backup folder size, which removes the oldest backups together with the ones built on them (but never the newest good backup or pinned ones).
Turn on Encrypt backups and every file inside each ZIP is encrypted with AES-256-GCM, using a key derived from your passphrase with PBKDF2-SHA256 (600,000 iterations or more; you can raise it).
data.json, readable by anyone who can read your vault; prompting is safer.You are never locked in to the plugin. tools/decrypt-backup.mjs in this repository decrypts a backup folder using only Node.js 18 or newer, with no packages to install:
node tools/decrypt-backup.mjs "backup/2026-10-07T21-24-00_full" "./decrypted"
It asks for the passphrase (or reads the REWIND_PASSPHRASE environment variable) and writes the original files to the output folder. Decrypt the full backup first, then each differential in date order, letting later files overwrite earlier ones. The header of the script documents the format, if you would rather write your own tool:
master = PBKDF2-HMAC-SHA256(passphrase, salt, iterations, 32 bytes), with salt (base64) and iterations from manifest.json.key = HMAC-SHA256(master, "rewind-vault/encrypt/v1")."RVE1", a 4-byte chunk size, then frames of iv (12) | ciphertext | tag (16), each AES-256-GCM with the header, frame number and a final-frame flag as associated data.Unencrypted backups need none of this: they are ordinary ZIP files.
Rewind Vault runs on iOS and Android, with these limits:
npm install
npm run typecheck # TypeScript, strict
npm run lint # ESLint (no `any`, no default exports, files under 300 lines)
npm test # Vitest: unit, integration and fault-injection tests
npm run build # bundle main.js
npm run dev # watch mode
The design is in PLAN.md and the build progress, decisions and open manual tests are in TRACKER.md. The code is layered: core/ (engines) knows nothing about Obsidian and is tested against an in-memory vault; ui/ and commands/ are thin and call the engines through a services object; main.ts only wires things together.
Bug reports and ideas are welcome as GitHub issues.
MIT © 2026 Dan Rhodes