MIT Rust Linux · macOS · Windows

A vault for
your dotfiles.

Clone, deploy, and keep in sync across Linux, macOS, and Windows.

One Rust binary replaces stow and the pile of .setup / .update bash scripts around it. Copy-based deploy with manifest-tracked drift detection, driven by a declarative .krypt.toml.

krypt — daily update
$ krypt update
 pull       dotfiles up to date (3 commits, auto-stashed 1 file)
 deploy     71 files · 2 updated · 0 drifted
 hooks
   [hook] reload-hypr    platform:linux        
   [hook] rebuild-bat    command_exists:bat    
   [hook] brew-bundle    platform:macos        skipped
 up to date in 1.2s

$ krypt diff
M ~/.config/nvim/init.lua   deployed ≠ staged
$ krypt adopt-edits
 adopted edits for 1 entries (70 clean, 0 missing)

why

stow can't run your setup. bash can't track your drift.

01 — BINARY

One binary, three OSes

Linux, macOS, Windows from the same .krypt.toml. No Perl, no Python, no shell dialect roulette.

02 — DEPLOY

Copy-based deploy + drift

Replaces stow. Every deployed file is recorded in a manifest, so krypt diff tells you exactly what drifted, krypt adopt-edits copies those hand-edits back into the repo, and krypt adopt <path> imports a new file and prints the [[link]] block for it.

03 — DECLARE

Declarative .krypt.toml

Links, templates, packages, prompts, commands, and hooks in one schema, splittable across files with include globs. krypt validate runs the whole include + ${VAR} pipeline, so a typo fails there instead of at first dispatch.

04 — RUNNER

Step runner with predicates

Steps gate on command_exists: / platform: / env: / file_exists:. The machine that doesn't have bat just skips the bat hook — no if command -v soup.

05 — PKG

Package managers, abstracted

pacman · paru · apt · dnf · brew · scoop · winget behind one dependency list. Declare the package once, install it on whatever distro you woke up on.

06 — WIZARD

First-run [prompts.*]

krypt setup walks the wizard your [prompts.*] sections declare — git identity, machine profile, whatever you write — and writes the answers through the [[template]] files that name them. Packages are krypt deps, deploy is krypt link.

07 — DISPATCH

Generic subcommand dispatcher

Any [[command]] entry is reachable as krypt <group> <name> with no binary changes. Your rofi launchers become first-class subcommands.

08 — VARS

${VAR} interpolation

Built-ins (${HOME}, ${XDG_CONFIG}, ${LOCAL_BIN}) then process env, resolved eagerly at config load. Unknown var = hard error citing file, location, and name.

09 — GIT

Auto-stash on update

Uncommitted work at pull time gets stashed via gix-stash, pulled over, and popped back. Conflicts surface with the stash OID so you can apply by hand. Opt out with --no-stash. Clone and pull run through gix — no git binary, HTTPS remotes only.

10 — NOTIFY

Platform-correct notifications

krypt notify <title> <body> picks the backend the host actually has: notify-send on Linux, terminal-notifier or osascript on macOS, PowerShell MessageBox on Windows (no BurntToast install), stderr when there is nothing. Pin one with [meta] notify_backend.

11 — CRATES

Four-crate workspace

krypt-cli (thin clap dispatch) · krypt-core (schema, resolver, copy engine, manifest, runner, predicates, hooks) · krypt-pkg · krypt-platform.

12 — MIGRATE

Coming from stow + bash

docs/migrating-from-bash.md ↗ maps stow → [[link]], .updatekrypt update, launcher scripts → [[command]].

commands

Five verbs cover the daily loop.

krypt init <url> clone your dotfiles repo to the XDG path
krypt setup interactive [prompts.*] wizard
krypt deps install [[deps]] via the host's package manager
krypt link deploy files to their declared destinations
krypt update the daily one: pull, redeploy, run post-update hooks
krypt doctor diagnose config, paths, and missing dependencies
krypt validate parse .krypt.toml, report schema errors
krypt diff show staged vs deployed differences
krypt adopt <path> import a file into the repo, print its [[link]]
krypt adopt-edits sync every drifted deployed file back into the repo
krypt unlink / relink reverse or refresh a deploy
krypt paths print every resolved path variable
krypt notify <title> <body> desktop notification on whatever OS you're on
krypt menu [name] list or run group = "menu" commands
krypt <group> <name> generic dispatcher for any declared command group
krypt battery built-in battery report / log / clear

Worked example: mxaddict/dotfiles ↗ — Arch + Hyprland, ~70 links, ~30 commands, ~10 post-update hooks.

install

Every channel drops a krypt on your $PATH.

Arch via AUR, macOS via the Homebrew tap, Windows via Scoop, or the prebuilt binaries on the release page — those four track every tag. The krypt name on crates.io is held by an unrelated stale project, so the binary crate is published as krypt-cli, and that one channel is paused: the gix-stash plumbing krypt needs still lives on a fork, which cargo publish won't accept, so cargo install krypt-cli currently lands an older build. Publishing resumes when the upstream gitoxide PR merges.

krypt — package managers
# Arch (AUR)
$ paru -S krypt-bin

# macOS (Homebrew tap)
$ brew install kryptic-sh/tap/krypt

# Windows (Scoop)
$ scoop bucket add kryptic https://github.com/kryptic-sh/scoop-bucket
$ scoop install krypt

# any platform (crates.io — publishing paused, older build)
$ cargo install krypt-cli
krypt — first run
$ krypt init https://github.com/you/dotfiles
$ krypt setup
$ krypt deps
$ krypt link
# then, forever after:
$ krypt update