v0.14.2  -  AGPL-3.0  -  Node.js >= 24

BFS

Your drives will fail. Your data won't.

Split backups across multiple drives so no single drive holds your complete data. Lose a drive? Pull a new one, recover, keep going. It's math, not luck.

npm install -g bfs-vault
GitHub

Why BFS?

🧩

Survive Drive Failures

Your backup is split into N+K pieces using Reed-Solomon erasure coding - the same math that keeps CDs readable despite scratches. Lose up to K drives and still recover everything from any N.

🔐

Your Eyes Only

AES-256-GCM encryption with Argon2id key derivation, on by default - opt out with --no-enc. Each drive holds one piece: encrypted, incomplete, and useless on its own.

📦

Smaller Backups, Automatically

ZIP/Deflate compression is on by default. BFS detects already-compressed files (photos, videos, archives) and skips them - no wasted CPU, smaller pieces.

🌐

Use Whatever Storage You Have

USB drives, external HDDs, NAS, FTP/FTPS and SSH/SFTP servers, network folders - anything that can hold a file. Mix and match across providers. No cloud subscription required. No vendor lock-in.

🗂️

Every Push Is a Snapshot

Each backup creates a new numbered version. Keep the last 7, or 30, or all of them. Verify health, prune old ones, restore from any point.

🛡️

Failures Don't Stop a Backup

One drive offline mid-backup? BFS doesn't give up. It keeps uploading to the rest and remembers exactly which ones failed - so later you fix and retry only those, not the whole thing.

🕸️

Lost Everything? One Piece Finds the Rest

Every piece of your backup carries a map to all the others. Find one surviving drive, run bfs recovery - your setup is back and BFS knows where the other pieces live. Restoring the files themselves then needs N of them reachable.

Quick Start

1 Initialize (one command, mix any storage)
# 3 data + 2 parity = 5 providers (local, FTP, SSH)
bfs init mybackup --ci --data-shards 3 --parity-shards 2 \
  --provider "local:disk1 --path /mnt/disk1" \
  --provider "local:usb   --path /mnt/usb" \
  --provider "ftp:nas     --config-file ./nas.json" \
  --provider "ssh:vps     --config-file ./vps.json" \
  --provider "ssh:pi      --config-file ./pi.json"
2 Backup & restore
# Each push creates a new versioned snapshot
bfs push  # backup -> new version
bfs pull  # restore latest version
3 Machine failure or disk swap? Rebuild the setup from any one provider
# ANY ONE provider rebuilds the configuration - BFS reads the map from its piece.
# Restoring the files then needs N providers reachable (3 of 5 in this scheme).
bfs recovery --provider ssh --name mybackup \
  --bootstrap "--config-file ./vps.json"
bfs pull  # restore files as usual

Commands

Command Description
bfs init Initialize a backup in the current directory
bfs push Backup current directory -> new version
bfs pull Restore files from backup
bfs status Show backup health and version info
bfs verify [--deep] Check piece availability and health across providers; flag missing/damaged header files. Exits 0 healthy, 4 degraded, 5 damaged; --deep verifies every piece's full data and catches damage the header check cannot see
bfs recovery Rebuild backup config from provider pieces
bfs repair Fix storage locations without re-uploading - repoint a moved device, rebuild a lost piece, or restore missing/damaged header files
bfs prune Delete old backup versions
bfs versions List all versions with health status