$ exifreg backup

Backups that can prove they are good.

Most photographers discover their backup was broken on the day they need it. exifregistry takes the opposite path: every copy is checksummed the moment it is made, every change is versioned, and one command re-checks every byte, months or years later.

Get exifregistry npm install -g exifregistry
exifreg
$ exifreg backup ~/Photos --to /Volumes/Backup
218 new, 3 changed, 12,431 unchanged (4.1 GB to copy).
Dry run. Nothing was changed. Add --apply to execute.
$ exifreg backup ~/Photos --to /Volumes/Backup --apply
โœ“ 221 files copied and verified (4.1 GB),
3 previous versions archived.
$ exifreg backup --verify --to /Volumes/Backup
12,652/12,652 files verified OK.
โœ“ Backup is healthy: every file matches its checksum.
// sync is not backup

A mirror repeats your mistakes.

Copy tools and sync folders make the destination look like the source. That is exactly the problem: delete a photo by accident and the mirror deletes it too. A silently corrupted file gets mirrored just as faithfully. A backup has one job that a mirror cannot do: remember.

ScenarioA mirror / syncexifreg backup
You delete a photo by accidentDeleted from the backup on the next runKept. Deletions never propagate
A file corrupts silently on diskThe corruption is copied faithfully--verify names the exact file
You edit a photoThe previous version is goneOld copy archived under _versions/
"Is my backup still good?"You hope so12,652/12,652 files verified OK
// how it works

Four steps, zero trust.

01

Scan and plan

Unchanged files are skipped instantly by size and date, so incremental runs on a huge library take seconds. Like every file operation in exifregistry, you see the full plan before anything is copied. A --paranoid flag re-hashes everything when you want the slow, certain answer.

02

Copy atomically, verify immediately

Each file is written to a temporary name, hashed on both sides, compared, and only then renamed into place. A power cut mid-copy cannot leave a half-written file with a valid name. If the hashes disagree, the copy is discarded and the run stops: that disagreement usually means a dying disk, and you want to know now.

03

Record everything in a manifest

A manifest at the backup root stores each file's source path, size, SHA-256 checksum, capture date and camera. It turns a pile of copied files into an archive that knows what it holds, and it is what makes verification and semantic restore possible.

04

Verify anytime

One command re-reads every byte of the backup and compares it against the manifest. Run it after every big import, or once a month. If a single bit has flipped anywhere in the archive, you get the file's name instead of a bad surprise years later.

// the silent enemy

Bit rot is real.

Storage degrades. Magnetic charge fades, flash cells leak, controllers write bad sectors. The files most at risk are exactly the ones a photo archive is made of: written once, then untouched for years. Nothing crashes, no error appears. The file simply is not the file anymore, and a JPEG with a few flipped bits can lose half the image.

Because the manifest remembers the checksum of every file at the moment it was known to be good, --verify can prove the archive is still intact, and point at exactly what is not.

$ exifreg backup --verify --to /Volumes/Backup
12,650/12,652 files verified OK.
CORRUPTED (bytes changed since backup):
2019/iceland/DSC_0417.NEF
MISSING from backup: 2019/iceland/DSC_0418.NEF
2 problem(s) found. The affected files should be
re-copied from a healthy source.
$ exifreg restore /Volumes/Backup --taken 2026-07
214 to restore, 3,201 already in place, 1 conflict(s).
conflict (exists with different content, kept):
~/Photos/2026/wedding/DSC02481.ARW
Dry run. Nothing was changed. Add --apply to execute.
$ exifreg restore /Volumes/Backup --taken 2026-07 --apply
โœ“ 214 files restored and checksum-verified.
// getting it back

Restore is just as careful.

  • Semantic restore. The manifest knows capture dates, so you can restore one day, one month or one year of photos without digging through folders.
  • Never overwrites. A file that exists with different content is a conflict. It is reported and left alone, always.
  • Refuses corruption. Every restored file is checked against its manifest checksum first. A rotten backup copy is refused, not propagated back into your library.
  • Anywhere you want. Restore to the original locations, or into a separate folder with --to.
// reference

The whole feature, six lines.

$ exifreg backup ~/Photos --to /Volumes/Backup # preview the plan
$ exifreg backup ~/Photos --to /Volumes/Backup --apply # copy, verified
$ exifreg backup ~/Photos --to /Volumes/BK --by "{year}/{date}" --apply # organized layout
$ exifreg backup --verify --to /Volumes/Backup # re-check every byte
$ exifreg backup --status --to /Volumes/Backup # files, size, capture span
$ exifreg restore /Volumes/Backup --taken 2026-07 --apply # bring photos back
3-2-1 rule

Keep 3 copies of your work, on 2 different media, 1 of them offsite. exifregistry covers the local legs: your working library plus one or more verified drives. Pair it with any offsite copy of your choice, and run --verify on a schedule.

Your life's work deserves a receipt.

Free, open-source, and it runs 100% on your machine.

$ npm install -g exifregistry
โ† Back to everything else exifregistry does