An atomic dotfile switcher for ricing. Swap your whole setup in one command, get it back in one command.
Rewritten to be safer, simpler and truly atomic
Report Bug · Request Feature
Why Tapes?
If you stare at your desktop for longer than zero hours, you have personal configs of every app you use in ~/.config. Your desktop decorations and app settings all technically live in there, which means changing how your entire desktop looks is done the manual way... or with tapes.
A tape is someone's whole ~/.config setup — or just the parts they want to share — packed into one folder you can plug in with a single command.
Most dotfile managers (like GNU Stow or manual symlink managers) operate file-by-file. If something crashes midway, your ~/.config is left in a broken, half-swapped state.
Tapes does the opposite: it builds your new config tree off to the side, then swaps the old and new trees in one single kernel operation. That means:
- No half-states —
~/.configis either your old setup or the new one, never in between. - Instant rollback —
tapes-v2 ejectputs things back exactly how they were, atomically. - Your files are never touched — the original config is never modified, overwritten, or deleted.
That's the whole idea. If you want to know how the swap actually works, see INTERNALS.md.
In day-to-day terms: keep as many tapes in your library as you like and insert and eject them at will — the workflow is like running matugen, except instead of regenerating colors it swaps entire config trees. And insertion is not a full reset: only the configs a tape actually provides are overridden, everything else from your old ~/.config carries over. A tape that ships just a quickshell/ config swaps only that — your Chromium profile stays logged in and your nvim config stays yours, no re-login, no expenses.
Tapes in Action
https://github.com/user-attachments/assets/6791a91b-a3be-429b-9fd0-adc34fc93b08
Quickstart
Install a tape, insert it into your desktop, and eject when you want your old setup back:
# 1. Install downloads or copies a tape into the library (~/.tapes/). It doesn't touch anything else yet
# Or from a local folder:
# tapes-v2 install ~/my-dots --name demo
# 2. See what the tape contains and what it overrides
# 3. Insert the tape (swaps your config and runs reload hooks)
# 4. Check what's active
# 5. Revert back like nothing ever happened
Tip: add
alias tapes="tapes-v2"to your~/.bashrcor~/.zshrcto usetapesas a shortcut.
Before inserting a tape you didn't write, read it. Hooks are arbitrary shell commands that run as your user the moment a swap lands —
hyprctl reloadis the friendly example, but atape.tomlcan just as easily containrm -rf. The swap itself is reversible; a hook command is not.tapes-v2 show <name>prints every hook a tape runs, andinsert --no-hookslets you test a tape without executing any of its commands first.
Installation
Tapes is Linux-only — the whole trick is a kernel syscall, so macOS and BSD are out of scope.
Option 1: Install script (Arch and other Linux)
|
Option 2: Nix / NixOS
# or add it to your profile:
Option 3: cargo binstall
# it is required to specify the version until tapes leaves beta
Option 4: From source
Shell Completion
For shell completion, add the following to your .zshrc or .bashrc or other depending on your shell
tapes shell completion supports fish, zsh, bash, nushell and elvish
Commands
| Command | What it does |
|---|---|
tapes-v2 install <source> |
Downloads or copies a tape into your library (~/.tapes/) |
tapes-v2 show [name] |
Lists all installed tapes, or inspects one |
tapes-v2 insert [name] |
Swaps a tape into ~/.config and runs its insert hooks |
tapes-v2 eject |
Swaps your original config back and runs its eject hooks |
tapes-v2 status [-v] |
Shows the active tape, where it came from, and its targets |
Handy flags on top of the above:
The short version:
# Clone someone's rice and try it
# Don't like it? One command and nothing ever happened
Creating Your Own Tape
A tape is just a folder with your config overrides and a tape.toml manifest.
The top level of a tape mirrors the top level of ~/.config — a folder named hypr in the tape overrides ~/.config/hypr, and so on.
my-tape/
├── tape.toml # manifest
├── hypr/ # overrides ~/.config/hypr
│ └── hyprland.conf
├── waybar/ # overrides ~/.config/waybar
│ └── config.jsonc
└── nvim/ # overrides ~/.config/nvim
└── init.lua
tape.toml:
[]
= "neon-dream"
= "Vibrant synthwave theme for Hyprland + Waybar"
= ["hyprland", "waybar"]
[]
# Commands run right after the swap
= [
"hyprctl reload",
"qs kill",
"waybar &",
"notify-send 'Tapes' 'Switched to neon-dream!'",
]
# Commands run after the tape is ejected
= [
"hyprctl reload",
"pkll waybar",
# hooks run in the current shell session not in the background
"qs -c caelestia -d",
"notify-send 'Tapes' 'Back to caelestia'",
]
Any configs your tape doesn't provide (Chrome profiles, pulse, whatever else lives in ~/.config) stay exactly as they are.
Acknowledgements
Thanks to these wonderful individuals for
erotic-erox for calling out some lifecycle bugs on version 0.1.2-beta
LilaccFlowerr for providing the tapes-v2 showcase video and hopefully a gui in the future
saksham_kumar for being a contributor and writing the beloved install command
Mvk for providing words of encourgement and support
Clover for providing the most encourgement and support, without them tapes wouldn't have gotten a rewrite and would have been the broken mess it was in Cassette-tapes, so massive thanks to him
Roadmap
- A TUI or GUI
- Colored output
- More features
Contributing
Contributions are welcome. See Contributing.md for the guidelines.
The internals of how Tapes works live in INTERNALS.md — worth a read before you touch the code.
License
Distributed under the MIT License.