A lightweight yet powerful wrapper for your native package managers. Install, track, and restore without changing your tools.
Cross-platform: Linux ✅ · macOS ✅ · Windows ⏳
⚠️ Active Development:stampis currently in the MVP phase of active development. Features are being delivered incrementally. For a complete look at our progress, check the Implementation Plan.
stamp is a lightweight yet powerful wrapper for your native package managers. It lets you install, search, get info, and remove packages and repositories across multiple package managers through a single CLI — without conflicts, ecosystem lock-in, or changing your tools.
✔️ Multi-Manager Wrapper - Install, search, get info, and remove packages across multiple package managers through a single CLI. No conflicts, no ecosystem lock-in. See supported package managers →
✔️ Automatic Intent Tracking - Every intentional install is recorded in a portable manifest.toml. Dependency packages are not included — you only track what you chose.
✔️ One-Command Environment Rebuild - stamp restore reinstalls all repositories and packages on a new machine. Clone your dotfiles, run one command, done.
✔️ Unified Repository Management - Add, remove, and list third-party repositories (repos, taps, remotes) across all managers with the same interface.
✔️ Safety Net Reconciliation - Forgot to use stamp? stamp reconcile auto-detects packages installed outside the tool and adds them to your manifest without prompting. Preview with --dry-run first.
✔️ Self-Contained Documentation - Built-in man page generation (stamp man install), shell completions (stamp completion bash|zsh|fish|powershell), and auto-generated CLI reference docs.
✔️ Agnostic & Unopinionated - Doesn't dictate how you configure your software (that's the job of stow or chezmoi). It solely ensures the software exists on your machine.
✔️ Context Preservation (Notes) - Intent is easily forgotten. The --note flag on stamp install acts as a memory aid — you aren't just restoring libfoo, you're restoring why you needed it.
✔️ Built-in System Doctor - stamp doctor checks manager availability, manifest integrity, and UNIX compliance in a single command. JSON output for scripting.
✔️ UNIX Compliant - XDG Base Directory, POSIX syntax, NO_COLOR support, strict stdout/stderr separation, and BSD sysexits exit codes.
✔️ Predictable & Scriptable - Global --yes / -y flag enables deterministic non-interactive execution in CI, bootstrap scripts, and automation pipelines. Never hangs waiting for user input in headless environments.
✔️ Lightweight Yet Powerful - Thin wrapper layer, no language lock-in, no philosophical shift. Works with your existing tools, not instead of them.
✔️ Built with Go - Single static binary, fast startup, no runtime dependencies. Linux and macOS support (amd64 + arm64). Windows on the roadmap.
✔️ Extensible Architecture - Interface-driven adapter pattern. Adding a new package manager is implementing 7 methods.
✔️ Compatible with Popular Package Managers - Works with the package managers you already use on Linux and macOS, with more on the way. See full compatibility table →
✔️ Developer Toolchain Support (coming soon) - cargo, pipx, go install, and npm/bun for language-specific global tools. See full compatibility table →
| Method | Command |
|---|---|
| Go install | go install github.com/rossijonas/stamp/cmd/stamp@latest |
| Download binary | curl -sSL https://github.com/rossijonas/stamp/releases/latest/download/stamp_{{VERSION}}_{{OS}}_{{ARCH}}.tar.gz | tar xz && sudo mv stamp /usr/local/bin/ |
| From source | git clone https://github.com/rossijonas/stamp.git && cd stamp && go build -o bin/stamp ./cmd/stamp && sudo cp bin/stamp /usr/local/bin/ |
| Homebrew (future) | brew install rossijonas/tap/stamp |
Replace {{VERSION}}, {{OS}}, and {{ARCH}} with the appropriate values for your system (e.g., v0.1.0, linux, amd64). The archive name uses the full tag (e.g. stamp_v0.1.0_linux_amd64.tar.gz).
| Method | Command |
|---|---|
| Standard (binary only) | rm $(which stamp) |
| Hard (remove all data) | rm -rf ~/.config/stamp ~/.local/share/stamp && rm -f $(which stamp) && sudo rm -f /usr/local/share/man/man1/stamp.1 |
Standard uninstall removes just the binary. Hard uninstall also removes configuration, manifest, snapshots, and man pages.
stamp is designed to be flexible. You can use it actively as a unified wrapper, or passively as a safety net.
Before using stamp, run the setup wizard to initialize your environment:
stamp setup # Interactive wizard: completions, man pages, init, doctor
stamp setup -y # Non-interactive: runs all steps without prompts
⚠️ Note on Privilege Escalation: Package managers that require root (e.g.,dnf) automatically wrap their write operations withsudointernally. Always runstamp install htopas your normal user — do not usesudo stamp install. Sudo prompts for your password in a terminal and fails gracefully in non-interactive environments (CI/pipelines).
Use stamp as your primary package installer. This guarantees 100% traceability of your intent instantly. It will auto-detect the best package manager or allow you to specify one.
Search across all managers:
stamp search ripgrepInstall and track in one step (with aliases like add):
stamp install htop # auto-detects dnf on Fedora
stamp install spotify --manager flatpak # or: -m flatpak
stamp add lazygit -m brew # using the 'add' aliasRemove and untrack (with aliases like uninstall, rm, delete, del):
stamp remove htop
stamp uninstall lazygit # using the 'uninstall' alias
stamp rm htop # using the 'rm' alias
stamp del htop # using the 'del' aliasIf you or a script accidentally bypass stamp and use native tools directly, stamp acts as a safety net to retroactively capture your intent.
1. Install Normally (Bypassing stamp):
sudo dnf install ripgrep
brew install jq2. Reconcile:
Run reconcile periodically. stamp compares your current system against its snapshot, detects newly installed ripgrep and jq, and auto-tracks them to your manifest — no prompts, no decisions. Preview drift with --dry-run before committing:
stamp reconcile --dry-run # preview only
stamp reconcile # auto-track detected changesNote: Only packages installed after your last snapshot are detected. Pre-existing packages (installed before
stamp init) are not visible to reconcile. To track a pre-existing package, usestamp reinstall <pkg>instead.
stamp reconcile uses snapshot diffing: it compares the current system state against the last saved snapshot. This edge case only applies when you bypass stamp and use native package manager commands (dnf, brew, flatpak) directly, then rely on reconcile as a safety net. If a package is removed and then reinstalled between two reconcile runs, the snapshot shows no net change — the package is present in both old and new snapshots, so reconcile reports no drift.
1. Snapshot: [htop, gcc, systemd, …]
2. dnf remove htop → system: [gcc, systemd, …]
3. dnf install htop → system: [htop, gcc, systemd, …]
(reconcile NOT run between remove and install)
4. stamp reconcile → snapshot [htop,…] vs system [htop,…]
→ identical → "No drift detected"
Mitigation — Option A: Always Use Stamp (Recommended)
The edge case never occurs if you manage packages through stamp:
stamp install htop # tracks automatically
stamp remove htop # untracks automaticallyUse Workflow A (stamp install/stamp remove) as your primary package manager. Stamp records every install and removal in the manifest instantly — no snapshot diffing needed. Only packages installed outside stamp via native tools are subject to the reinstall gap.
Mitigation — Option B: Regular Reconciliation
If you do use native package manager commands directly, remember to run stamp reconcile after each uninstall operation to keep snapshots in sync:
sudo dnf remove htop && stamp reconcile
sudo dnf install htopMitigation — Option C: Automated Timer
Set up a daily timer to run stamp reconcile automatically. The stamp auto-reconcile command (planned) will handle this setup. In the meantime, timer files are available in contrib/:
Linux (systemd):
cp contrib/systemd/stamp-reconcile.* ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now stamp-reconcile.timermacOS (launchd):
cp contrib/launchd/com.rossijonas.stamp.reconcile.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/com.rossijonas.stamp.reconcile.plistWhen you get a new laptop, clone your dotfiles (containing your manifest.toml) and run:
stamp restore -ystamp will read the manifest and execute the appropriate native install commands concurrently. The -y / --yes flag ensures any safety confirmations are auto-accepted.
To keep everything fresh, run a unified update across all your managers at once:
stamp updateTo update stamp itself to the latest released version:
stamp self-updateYou can annotate why you installed a specific package directly in the CLI, which saves it to your manifest. This is incredibly useful for remembering why you needed an obscure tool 6 months later.
stamp install lazygit --note "better git TUI than default"Or add a note to an existing tracked package:
stamp edit lazygit --note "Required for the backend build script"stamp is configured via a simple, human-editable TOML file located at ~/.config/stamp/config.toml. This file governs how stamp resolves ambiguity when a package exists in multiple package managers.
Example configuration:
# ~/.config/stamp/config.toml
# Global package manager priority (highest to lowest)
precedence = ["dnf", "flatpak", "brew"]
# Fine-grained pattern-based matching rules
[[rules]]
pattern = "^com\\..*|^org\\..*" # Force reverse-DNS names to Flatpak
prefer = "flatpak"
[[rules]]
pattern = "^lib.*|-devel$" # Force libraries and dev headers to DNF
prefer = "dnf"If you run stamp install htop, and htop is available in both DNF and Homebrew, stamp will automatically select DNF because dnf has higher priority than brew in your precedence config.
While stamp currently targets Red Hat-based systems, our goal is to become the universal intent tracker across all major Linux distributions and macOS.
- [ ] Extend MacOS Support
- Implement support for MacPorts.
- [ ] Arch Linux Ecosystem Support
- Implement support for
pacman.
- Implement support for
- [ ] Developer Toolchains
- Track language-specific global installs (
cargo,pipx,go install,npm).
- Track language-specific global installs (
stamp aims to be the universal intent tracker across all major operating systems and developer toolchains. Below is the current support matrix and architectural context for the package managers we track (or plan to track).
✅ = Implemented · ⏳ = Planned · N/A = Not available on this OS · (blank) = Not implemented or not planned
| Manager | Ubuntu | Debian | Fedora | CentOS | Rocky | Arch | openSUSE | macOS | Windows |
|---|---|---|---|---|---|---|---|---|---|
| DNF | - | - | ✅ | ✅ | ✅ | - | - | - | - |
| APT | ✅ | ✅ | - | - | - | - | - | - | - |
| Zypper | - | - | - | - | - | - | ✅ | - | - |
| Snap | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | - | - |
| Flatpak | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | - | - |
| Brew | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | - |
| Pacman | ✅ | ||||||||
| MacPorts | - | - | - | - | - | - | - | ✅ | |
| Winget | - | - | - | - | - | - | - | - | |
| Chocolatey | - | - | - | - | - | - | - | - | |
| Scoop | - | - | - | - | - | - | - | - | |
| Language Toolchains | |||||||||
go |
⏳ | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ | |
cargo |
⏳ | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ | |
pipx |
⏳ | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ | |
npm |
⏳ | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ |
Read the Project Vision to understand the "why" behind the project, or check out the Technical Specs and Architecture Decisions.
This project is licensed under the Apache License, Version 2.0 (Apache-2.0) - see the LICENSE file for details.