Skip to content

Introduction

Rebuild your workstation from a commit.

Rivet records the explicit packages and the user-approved configuration that define a Linux or macOS environment, and writes them to storage you control — a Git remote, a mounted NAS, any of ~70 cloud providers via rclone, or a restic repository. It is not a disk imager and not a whole-home backup — it captures the handful of things that actually make a machine yours, and refuses to touch secrets.

Rivet is stable as of 1.0: init, snapshot, restore and doctor are supported on Linux and macOS, the CLI surface is frozen under semantic versioning, and releases carry Sigstore signatures and build provenance that install.sh verifies. It makes a desktop rebuild repeatable, inspectable, and considerably safer than copying your home folder. The gaps that remain are listed in feature status — read them before you rely on it.

Terminal window
curl -sSf https://rivet.fobiat.workers.dev/install | sh

On macOS, use the Homebrew tap instead — Homebrew does not quarantine what it installs, so this avoids the Gatekeeper prompt a downloaded binary triggers:

Terminal window
brew install fobiat/rivet/rivet

Read install.sh before piping it into a shell, same as any installer. Pinning a version, choosing an install directory, and verifying release signatures are covered in the install guide.

Use a separate private repository for your snapshots — never this source tree.

Terminal window
rivet init

On an interactive terminal that is the whole setup: it shows what it found, asks what to keep, and takes the first snapshot. The repository defaults to ~/rivet and its location is recorded, so nothing afterwards needs --repo.

Terminal window
rivet status # what has drifted since the last snapshot
rivet snapshot # save the current state

On the new machine, clone your snapshot repository, then plan the restore before applying it:

Terminal window
rivet restore --repo ~/rivet-snapshots
rivet restore --repo ~/rivet-snapshots --apply --yes

The recorded default is per-machine, so the new machine needs --repo until it has run init against the clone. To restore only part of a snapshot, use rivet restore --only <categories> — a bare rivet restore lists them.

Nothing is installed or overwritten until you pass both --apply and --yes, and every replaced file is preserved under ~/.local/state/rivet/rollback/. The full walkthrough is in the quickstart.

Git is the default because it makes every change reviewable as a diff, but it is only one of four destinations. --repo above is the snapshot repository Rivet manages locally; where it ships those snapshots is up to you:

Terminal window
# A mounted NAS share or second disk — encrypted with age by default
rivet init --repo ~/rivet-snapshots --backend fs --path /mnt/nas/rivet
# S3, Backblaze B2, Google Drive, Dropbox, SFTP, WebDAV, and ~70 more
rivet init --repo ~/rivet-snapshots --backend rclone --remote b2:my-bucket/rivet
# Deduplicated, incremental history without Git
rivet init --repo ~/rivet-snapshots --backend restic \
--restic-repo sftp:nas:/backups/rivet --password-env RESTIC_PASSWORD
Backend Best for Needs Encryption
git (default) Reviewing every change as a diff before it happens none none — plaintext and reviewable by design
fs A NAS already mounted over SMB/NFS, or a second local disk none age, on by default
rclone S3, B2, Drive, Dropbox, SFTP, WebDAV, ~70 providers rclone age, on by default
restic Deduplicated backup history without Git restic restic’s own

Run init --backend again to add another. Configure several and each snapshot fans out to all of them; restore reads from the first, or from --backend <id>. If a snapshot’s optional tool is missing, only that destination fails — the others still succeed. Full reference: storage backends.

Browsing snapshot history in rivet tui, opening a revision, reading its
diffs, and descending into the restore plan

rivet tui puts working-tree drift, snapshot history, per-file diffs and the restore plan on one screen. Every frame above is generated from the real renderer by pressing the keys it shows. See the terminal UI guide.

Packages Native (Pacman/APT/DNF/Zypper/XBPS/Homebrew), foreign (AUR/MacPorts), Nix, Mac App Store, Flatpak, Snap, and AppImage — the ones you explicitly approve
Configuration Curated groups for KDE Plasma, GNOME, Cinnamon, Xfce, Hyprland, Sway, niri, i3, shells, Git, Tmux, Kitty, VS Code, Vim/Neovim, fonts and themes — plus any path you rivet track yourself
Destinations Git, a local/NAS path, an rclone remote, or restic — see where snapshots go
Never captured Secrets, browser profiles, GnuPG, SSH keys, caches, Flatpak app data, system-wide configuration. On macOS also the Keychain, sandboxed app containers, cookies, and known session-token stores — the Keychain is never exported under any flag

Secrets you do want carried go through an explicit encrypted vault: rivet vault add ~/.ssh/config seals that file into every snapshot with age, and the private identity never leaves the machine.

Everything is published at rivet.fobiat.workers.dev — searchable, with the CLI reference, JSON schemas, exclusion policy and threat model. The most common jumping-off points:

docs/ in this repository is the source of truth; the site syncs from it at build time and fails its build if a page goes missing. See web/README.md to work on the site and docs/DOCUMENTATION.md for the standard every page is held to.

To run Rivet from a branch instead of a tagged version, with Rust and Git available:

Terminal window
git clone https://github.com/fobiat/Rivet.git
cd Rivet
cargo run -- scan
cargo test

scan reports the detected distro family, native manager, window manager, explicit packages, and supported configuration groups. The terminal UI is a default-on Cargo feature; --no-default-features builds a headless CLI that keeps every other command.

Pull requests are welcome. CONTRIBUTING.md covers the build, the checks CI runs, the commit conventions, and the parts of the codebase that need extra care. This project follows the Contributor Covenant.

Found a security issue? Do not open a public issue — see SECURITY.md, which also states plainly what has and has not been reviewed.

Dual-licensed under the Apache License 2.0 or the MIT license, at your option — the conventional Rust dual licence: MIT keeps reuse simple, Apache-2.0 adds an explicit patent grant.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Rivet by you, as defined in the Apache-2.0 license, shall be dual-licensed as above, without any additional terms or conditions.