dotbins manages CLI tool binaries in your dotfiles repository, offering:
- ✅ Cross-platform binary management (macOS, Linux, Windows)
- ✅ No admin privileges required
- ✅ Version-controlled CLI tools
- ✅ Downloads from GitHub releases
- ✅ Perfect for dotfiles synchronization
No package manager, no sudo, no problem.
See this example .dotbins repository: basnijholt/.dotbins completely managed with dotbins.
Note
💡 What makes dotbins different? Unlike similar tools, dotbins uniquely integrates tool-specific shell configurations (aliases, completions, etc.) directly in your dotfiles workflow, not just binary downloads, and allows a Git workflow for managing binaries.
[ToC] 📚
- ⚡ Quick Start
- 🌟 Features
- 💡 Why I Created dotbins
- 📚 Usage
- 🛠️ Installation
- ⚙️ Configuration
- 💡 Examples
- 💻 Shell Integration
- 📚 Examples with 50+ Tools
- 🔧 Troubleshooting
- 🤔 Comparison with Alternatives
- ❤️ Support and Contributions
⚡ Quick Start
Using the amazing uv package manager (uv tool install dotbins):
# Create a sample configuration file to get started dotbins init # Install/update tools using a config file (to tools_dir, e.g., ~/.dotbins) dotbins sync # Install a single tool (defaults to ~/.local/bin) - No config needed! dotbins get junegunn/fzf # Install tools from a remote config (defaults to ~/.local/bin) dotbins get https://github.com/basnijholt/.dotbins/blob/main/dotbins.yaml
See it in action:
🌟 Features
- 🌐 Supports multiple platforms (macOS, Linux, Windows) and architectures (amd64, arm64, etc.)
- 📦 Downloads and organizes binaries from GitHub releases
- 🔄 Installs and updates tools to their latest versions with a single command
- 📌 Pin tools to specific versions with the
tagparameter - 📊 Tracks installed versions and update timestamps for all tools
- 🧩 Extracts binaries from various archive formats (zip, tar.gz)
- 📂 Organizes tools by platform and architecture for easy access
- 🐙 Easy integration with your dotfiles repository for version control
- ⚙️ Automatic PATH & Shell Code: Configures
PATHand applies custom shell snippets (shell_code).
💡 Why I Created dotbins
I frequently works across multiple environments where I clone my dotfiles repository with all my preferred configurations.
I faced a common frustration: some of my favorite tools (fzf, bat, zoxide, etc.) were not available on the new system and installing them with a package manager is too much work or even not possible.
dotbins was born out of this frustration.
It allows me to:
- Track pre-compiled binaries in a separate Git repository (using Git LFS for efficient storage)
- Include that repository as a submodule in my dotfiles
- Ensure all my essential tools are immediately available after cloning, regardless of system permissions
Now when I clone my dotfiles on any new system, I get not just my configurations but also all the CLI tools I depend on for productivity, ready to use with their specific aliases and shell initializations automatically configured.
No package manager, no sudo, no problem!
📚 Usage
Tip
Use uvx dotbins and create a ~/.config/dotbins/dotbins.yaml file to store your configuration.
To use dotbins, you'll need to familiarize yourself with its commands:
Usage: dotbins [-h] [-v] [--tools-dir TOOLS_DIR] [--config-file CONFIG_FILE]
{get,sync,init,list,status,readme,version} ...
dotbins - Download, manage, and update CLI tool binaries in your dotfiles
repository
Positional Arguments:
{get,sync,init,list,status,readme,version}
Command to execute
get Download and install a tool directly without
configuration file
sync Install and update tools to their latest versions
init Initialize directory structure and generate shell
integration scripts
list List all available tools defined in your configuration
status Show installed tool versions and when they were last
updated
readme Generate README.md file with information about
installed tools
version Print dotbins version information
Options:
-h, --help show this help message and exit
-v, --verbose Enable verbose output with detailed logs and error
messages
--tools-dir TOOLS_DIR
Tools directory to use (overrides the value in the
config file)
--config-file CONFIG_FILE
Path to configuration file (default: looks in standard
locations)Commands
- sync - Install and update tools to their latest versions
- get - Download and install a tool directly without using a configuration file
- init - Initialize the tools directory structure and generate a sample configuration file
- list - List available tools defined in your configuration
- version - Print version information
- status - Show detailed information about available and installed tool versions
Update Process with dotbins sync
The sync command is the core of dotbins, keeping your tools up-to-date across platforms.
Here's what happens during dotbins sync:
-
Version Detection:
- Checks each tool's current version in
manifest.json - Queries GitHub API for the latest release of each tool
- Checks each tool's current version in
-
Smart Updates:
- Only downloads tools with newer versions available
- Skips up-to-date tools (unless
--forceis used) - Reports which tools were updated, skipped, or failed
-
Multi-Platform Management:
- Processes each platform/architecture combination configured
- Can be filtered to specific platforms:
dotbins sync -p linux - Can be limited to current system only:
dotbins sync -c
-
File Generation:
- Updates
manifest.jsonwith new version information - Regenerates shell integration scripts with PATH and tool configurations
- Creates a README in the tools directory with installation status
- Updates
-
Pinning to Manifest:
- Use the
dotbins sync --pin-to-manifestCLI flag to forcesyncto use the tags already recorded inmanifest.json. - This ignores the latest release information from GitHub and ensures that the installed versions match exactly what's in your manifest, which is useful for reproducibility or if your manifest file is version-controlled.
- Use the
Example update workflow:
# Update all tools for all configured platforms dotbins sync # Update only specific tools dotbins sync fzf bat # Update tools only for current platform dotbins sync --current # Force reinstall everything, even if up to date dotbins sync --force # Update tools using only the versions recorded in manifest.json dotbins sync --pin-to-manifest # See what is installed dotbins status
After updating, a summary is displayed showing what was installed, skipped, or had errors.
Quick Install with dotbins get
The get command allows you to quickly download and install tools directly from GitHub or from a remote configuration file:
# Install fzf to the default location (~/.local/bin) dotbins get junegunn/fzf # Install ripgrep with a custom binary name dotbins get BurntSushi/ripgrep --name rg # Install bat to a specific location dotbins get sharkdp/bat --dest ~/bin # Install multiple tools from a remote config URL/local path dotbins get https://example.com/my-tools.yaml --dest ~/.local/bin
This is perfect for:
- Quickly installing tools on a new system
- One-off installations without needing a configuration file
- Adding tools to PATH in standard locations like
~/.local/bin - Bootstrapping with a pre-configured set of tools using a remote configuration URL or local config
The get command automatically detects whether you're providing a GitHub repository or a configuration URL/path.
When using a URL/path, it will download all tools defined in the configuration for your current platform and architecture.
Initializing with dotbins init
The fastest way to get started with dotbins is to use the init command:
This command:
- Creates the directory structure for all configured platforms and architectures
- Generates shell integration scripts for your system
- If no config exists, creates a sample
dotbins.yamlwith sensible defaults
The generated sample config includes popular tools like fzf, bat, and zoxide, with support for multiple platforms:
Sample config generated by dotbins init:
# dotbins sample configuration # Generated by `dotbins init` # See https://github.com/basnijholt/dotbins for more information # Directory where tool binaries will be stored tools_dir: ~/.dotbins # Target platforms and architectures for which to download binaries # These determine which system binaries will be downloaded and managed platforms: linux: - amd64 # x86_64 - arm64 # aarch64 macos: - arm64 # Apple Silicon windows: - amd64 # 64-bit Windows # Tool definitions # Format: tool_name: owner/repo or detailed configuration tools: # Essential CLI tools with minimal configuration bat: sharkdp/bat # Syntax-highlighted cat replacement fzf: junegunn/fzf # Fuzzy finder for the terminal zoxide: ajeetdsouza/zoxide # Smarter cd command with frecency # Example with shell customization # starship: # repo: starship/starship # shell_code: | # eval "$(starship init bash)" # Change to your shell # For more configuration options, visit: # https://github.com/basnijholt/dotbins#gear-configuration
This provides a good starting point that you can customize with your preferred tools and configurations.
🛠️ Installation
We highly recommend to use uv to install/run dotbins:
or install as a global command:
Otherwise, simply use pip:
You'll also need to create or update your dotbins.yaml configuration file either in the same directory as the script or at a custom location specified with --tools-dir.
⚙️ Configuration
dotbins uses a YAML configuration file to define the tools and settings. The configuration file is searched in the following locations (in order):
- Explicitly provided path (using
--config-fileoption) ./dotbins.yaml(current directory)~/.config/dotbins/dotbins.yaml(XDG config directory)~/.config/dotbins.yaml(XDG config directory, flat)~/.dotbins.yaml(home directory)~/.dotbins/dotbins.yaml(default dotfiles location)
The first valid configuration file found will be used. If no configuration file is found, default settings will be used.
Tip
To create a starter configuration file, run dotbins init. This will generate a sample config with common tools in your tools directory.
Basic Configuration
# Basic settings tools_dir: ~/.dotbins # (optional, ~/.dotbins by default) # Target platforms and architectures (optional, current system by default) platforms: linux: - amd64 - arm64 macos: - arm64 # Only arm64 for macOS # Tool definitions tools: # Tool configuration entries
Directory Structure
When you run dotbins sync, it creates a directory structure that organizes binaries by platform and architecture, and generates shell integration scripts.
Here's what gets created:
~/.dotbins/ # Root tools directory (configurable) ├── README.md # Auto-generated documentation ├── dotbins.yaml # Your configuration file (if copied) ├── linux/ # Platform-specific directories │ ├── amd64/bin/ # Architecture-specific binaries │ │ ├── bat │ │ ├── fzf │ │ └── ... │ └── arm64/bin/ │ ├── bat │ ├── fzf │ └── ... ├── macos/ │ └── arm64/bin/ │ ├── bat │ ├── fzf │ └── ... ├── shell/ # Shell integration scripts │ ├── bash.sh │ ├── fish.fish │ ├── nushell.nu │ ├── powershell.ps1 │ └── zsh.sh └── manifest.json # Version tracking information
Tool Configuration
Each tool must be configured with at least a GitHub repository. Many other fields are optional and can be auto-detected.
The simplest configuration is:
tools: # tool-name: owner/repo zoxide: ajeetdsouza/zoxide fzf: junegunn/fzf
dotbins will auto-detect the latest release, choose the appropriate asset for your platform, and install binaries to the specified tools_dir (defaults to ~/.dotbins).
Note
dotbins excels at auto-detecting the correct assets and binary paths for many tools. Always try the minimal configuration first!
When auto-detection isn't possible or you want more control, you can provide detailed configuration:
tool-name: repo: owner/repo # Required: GitHub repository tag: v1.2.3 # Optional: Specific release tag to use (defaults to latest) api_url: https://gitea.com/api/v1 # Optional: API base URL for non-GitHub forges (Gitea, Forgejo, Gogs) binary_name: executable-name # Optional: Name of the resulting binary(ies) (defaults to tool-name) extract_archive: true # Optional: Whether to extract from archive (true) or direct download (false) (auto-detected if not specified) path_in_archive: path/to/binary # Optional: Path to the binary within the archive (auto-detected if not specified) # Asset patterns - Optional with auto-detection # Option 1: Platform-specific patterns asset_patterns: # Optional: Asset patterns for each platform linux: pattern-for-linux.tar.gz macos: pattern-for-macos.tar.gz # Option 2: Single pattern for all platforms asset_patterns: pattern-for-all-platforms.tar.gz # Global pattern for all platforms # Option 3: Explicit platform patterns for different architectures asset_patterns: linux: amd64: pattern-for-linux-amd64.tar.gz arm64: pattern-for-linux-arm64.tar.gz macos: amd64: pattern-for-macos-amd64.tar.gz arm64: pattern-for-macos-arm64.tar.gz
Asset patterns support variables like {version}, {platform}, and {arch} that are automatically replaced with the appropriate values (see Pattern Variables section for details).
Pattern Variables
In asset patterns, you can use special variables that get replaced with actual values when dotbins searches for the correct asset to download:
{version}- Release version (without 'v' prefix){platform}- Platform name (after applying platform_map){arch}- Architecture name (after applying arch_map)
For example, if a tool release has version v2.4.0 and you're on linux/amd64:
mytool: repo: owner/mytool asset_patterns: mytool-{version}-{platform}_{arch}.tar.gz
This would search for an asset named: mytool-2.4.0-linux_amd64.tar.gz
With platform and architecture mapping:
mytool: repo: owner/mytool platform_map: macos: darwin # Convert "macos" to "darwin" in patterns arch_map: amd64: x86_64 # Convert "amd64" to "x86_64" in patterns asset_patterns: mytool-{version}-{platform}_{arch}.tar.gz
For macOS/amd64, this would search for: mytool-2.4.0-darwin_x86_64.tar.gz
Real-world example:
ripgrep: repo: BurntSushi/ripgrep binary_name: rg arch_map: amd64: x86_64 arm64: aarch64 asset_patterns: linux: ripgrep-{version}-{arch}-unknown-linux-musl.tar.gz macos: ripgrep-{version}-{arch}-apple-darwin.tar.gz
For Linux/amd64, this would search for: ripgrep-14.1.1-x86_64-unknown-linux-musl.tar.gz
For macOS/arm64, this would search for: ripgrep-14.1.1-aarch64-apple-darwin.tar.gz
Platform and Architecture Mapping
If the tool uses different naming for platforms or architectures:
tool-name: # Basic fields... platform_map: # Optional: Platform name mapping macos: darwin # Converts "macos" to "darwin" in patterns arch_map: # Optional: Architecture name mapping amd64: x86_64 # Converts "amd64" to "x86_64" in patterns arm64: aarch64 # Converts "arm64" to "aarch64" in patterns
Asset auto-detection defaults
When multiple compatible assets are available for your platform and architecture, dotbins uses these settings to determine which one to select:
# Global defaults for all tools defaults: prefer_appimage: true # Prioritize AppImage format when available libc: musl # Prefer musl over glibc on Linux windows_abi: msvc # Prefer MSVC over GNU ABI on Windows
These are also the built-in defaults if no custom settings are provided.
Why these defaults?
-
musl libc: Statically linked musl binaries offer maximum portability across all Linux distributions regardless of the system's native C library. They eliminate glibc version conflicts (the notorious
GLIBC_X.YZ not founderrors), work on both glibc and musl-based distributions (like Alpine Linux), and generally provide a more reliable user experience. -
AppImage: AppImage bundles all dependencies in a single, self-contained file that works across different Linux distributions without installation, making it ideal for portable applications, (such as neovim, which requires extra runtime files.)
-
Windows ABI: The MSVC ABI is the default on Windows as it's the most widely used and generally more stable. However, if you're using MinGW or prefer GNU tools, you can set this to "gnu".
Example: libc selection
When requesting Linux amd64 and both of these assets are available:
ripgrep-13.0.0-x86_64-unknown-linux-gnu.tar.gz(uses glibc)ripgrep-13.0.0-x86_64-unknown-linux-musl.tar.gz(uses musl)
With libc="musl", dotbins selects the musl version.
With libc="glibc", dotbins selects the gnu version.
Example: AppImage preference
When both formats are available:
nvim-linux-x86_64.appimagenvim-linux-x86_64.tar.gz
With prefer_appimage=true, dotbins selects the AppImage version.
Example: Windows ABI
When requesting Windows x86_64 and both of these assets are available:
bat-v0.25.0-x86_64-pc-windows-gnu.zip(uses GNU ABI)bat-v0.25.0-x86_64-pc-windows-msvc.zip(uses MSVC ABI)
With windows_abi="msvc", dotbins selects the MSVC version.
With windows_abi="gnu", dotbins selects the GNU version.
Multiple Binaries
For tools that provide multiple binaries:
tool-name: # Other fields... binary_name: [main-binary, additional-binary] path_in_archive: [path/to/main, path/to/additional]
Configuration Examples
Minimal Tool Configuration
direnv: repo: direnv/direnv
or
ripgrep: repo: BurntSushi/ripgrep binary_name: rg # Only specify if different from tool name
Standard Tool
atuin: repo: atuinsh/atuin arch_map: amd64: x86_64 arm64: aarch64 asset_patterns: linux: atuin-{arch}-unknown-linux-gnu.tar.gz macos: atuin-{arch}-apple-darwin.tar.gz
Tool with Multiple Binaries
uv: repo: astral-sh/uv binary_name: [uv, uvx] path_in_archive: [uv-*/uv, uv-*/uvx]
Platform-Specific Tool
eza: repo: eza-community/eza arch_map: amd64: x86_64 arm64: aarch64 asset_patterns: linux: eza_{arch}-unknown-linux-gnu.tar.gz macos: null # No macOS version available
Version-Pinned Tool
bat: repo: sharkdp/bat tag: v0.23.0 # Pin to specific version instead of latest
Non-GitHub Forges (Gitea, Forgejo, Gogs)
dotbins can download tools from any forge with a GitHub-compatible releases API. Use api_url to point to the forge's API:
tea: repo: gitea/tea api_url: https://gitea.com/api/v1
This works with Gitea, Forgejo, Gogs, Codeberg, and self-hosted GitHub Enterprise instances.
Shell-Specific Configuration
The auto-generated shell scripts that add the binaries to your PATH will include the tool-specific shell code if provided.
For example, see the following configuration:
tools: fzf: repo: junegunn/fzf shell_code: | source <(fzf --zsh) zoxide: repo: ajeetdsouza/zoxide shell_code: | eval "$(zoxide init zsh)" eza: repo: eza-community/eza shell_code: | alias l="eza -lah --git"
If you want to make your config compatible with multiple shells (e.g., zsh, bash, fish), you can use the following syntax:
- Separate entries per shell: Define the code for each shell individually.
- Comma-separated shells: Define the same code for multiple shells by listing them separated by commas (e.g.,
bash,zsh:). - Placeholder: Use the
__DOTBINS_SHELL__placeholder within the shell code. This placeholder will be replaced by the actual shell name (bash,zsh, etc.) when the integration scripts are generated.
starship: repo: starship/starship shell_code: bash,zsh: eval "$(starship init __DOTBINS_SHELL__)" # Use placeholder for bash and zsh fish: starship init fish | source
Full Configuration Example
This is the author's configuration file (and resulting basnijholt/.dotbins repo):
Click to view author's full dotbins.yaml
tools_dir: ~/.dotbins platforms: linux: - amd64 - arm64 macos: - arm64 tools: delta: dandavison/delta duf: muesli/duf dust: bootandy/dust fd: sharkdp/fd hyperfine: sharkdp/hyperfine rg: BurntSushi/ripgrep yazi: sxyazi/yazi bat: repo: sharkdp/bat shell_code: bash,zsh: | alias bat="bat --paging=never" alias cat="bat --plain --paging=never" bun: repo: oven-sh/bun arch_map: amd64: x64 arm64: aarch64 asset_patterns: linux: bun-linux-{arch}.zip macos: bun-darwin-{arch}.zip shell_code: bash,zsh: | alias bunx="bun x" direnv: repo: direnv/direnv shell_code: bash,zsh: | eval "$(direnv hook __DOTBINS_SHELL__)" eza: repo: eza-community/eza shell_code: bash,zsh: | alias l="eza --long --all --git --icons=auto" fzf: repo: junegunn/fzf shell_code: zsh: | source <(fzf --zsh) bash: | eval "$(fzf --bash)" lazygit: repo: jesseduffield/lazygit shell_code: bash,zsh: | alias lg="lazygit" micromamba: repo: mamba-org/micromamba-releases shell_code: bash,zsh: | alias mm="micromamba" starship: repo: starship/starship shell_code: bash,zsh: | eval "$(starship init __DOTBINS_SHELL__)" zoxide: repo: ajeetdsouza/zoxide shell_code: bash,zsh: | eval "$(zoxide init __DOTBINS_SHELL__)" atuin: repo: atuinsh/atuin shell_code: bash,zsh: | eval "$(atuin init __DOTBINS_SHELL__ --disable-up-arrow)" keychain: repo: danielrobbins/keychain asset_patterns: keychain uv: repo: astral-sh/uv binary_name: [uv, uvx] path_in_archive: [uv-*/uv, uv-*/uvx]
💡 Examples
List all available tools in your configuration:
Install or update all tools for all configured platforms:
Install or update specific tools only:
dotbins sync fzf bat ripgrep
Install or update tools for a specific platform/architecture:
dotbins sync -p macos -a arm64
Install or update tools only for the current system's platform and architecture, skipping others defined in the config:
Force reinstall even if tools are up to date:
Install tools from a remote configuration:
dotbins get https://raw.githubusercontent.com/username/dotbins-config/main/tools.yaml --dest ~/binShow status (installed, missing tools, last updated) for all installed tools:
Show a compact view of installed tools (one line per tool):
Show tools only for the current platform/architecture:
Filter tools by platform or architecture:
dotbins status --platform macos dotbins status --architecture arm64
💻 Shell Integration
dotbins creates shell scripts that add binaries to your PATH and apply your custom tool configurations.
After running dotbins sync or dotbins init, shell integration scripts are created in ~/.dotbins/shell/ for various shells (Bash, Zsh, Fish, Nushell, and PowerShell)
What's in the Shell Scripts?
The generated shell scripts do two main things:
- Add binaries to PATH - Makes tool binaries available for your platform/architecture
- Apply your tool-specific shell_code - Sets up aliases, completions, and initializations
For example, with this configuration:
fzf: repo: junegunn/fzf shell_code: | source <(fzf --zsh) bat: repo: sharkdp/bat shell_code: | alias bat="bat --paging=never" alias cat="bat --plain --paging=never"
The generated zsh.sh will include:
#!/usr/bin/env zsh # dotbins - Add platform-specific binaries to PATH _os=$(uname -s | tr '[:upper:]' '[:lower:]') [[ "$_os" == "darwin" ]] && _os="macos" _arch=$(uname -m) [[ "$_arch" == "x86_64" ]] && _arch="amd64" [[ "$_arch" == "aarch64" || "$_arch" == "arm64" ]] && _arch="arm64" export PATH="$HOME/.dotbins/$_os/$_arch/bin:$PATH" # Tool-specific configurations # Configuration for fzf if command -v fzf >/dev/null 2>&1; then source <(fzf --zsh) fi # Configuration for bat if command -v bat >/dev/null 2>&1; then alias bat="bat --paging=never" alias cat="bat --plain --paging=never" fi
Shell Startup Integration
Add this line to your shell's startup file to integrate dotbins:
# For Zsh (~/.zshrc) source "$HOME/.dotbins/shell/zsh.sh" # For Bash (~/.bashrc) source "$HOME/.dotbins/shell/bash.sh" # For Fish (~/.config/fish/config.fish) source "$HOME/.dotbins/shell/fish.fish" # For Nushell source ~/.dotbins/shell/nushell.nu
📚 Examples with 50+ Tools
See the examples/examples.yaml file for a list of >50 tools that require no configuration.
tools_dir: ~/.dotbins-examples # List of tools that require no configuration tools: atuin: atuinsh/atuin # Shell history and recording tool bandwhich: imsnif/bandwhich # Terminal bandwidth utilization tool bat: sharkdp/bat # Cat clone with syntax highlighting and Git integration btm: ClementTsang/bottom # Graphical system monitor # Bitwarden CLI - demonstrates tag_pattern for filtering releases by tag bw: repo: bitwarden/clients tag_pattern: "^cli-" # Filter releases to only CLI (not web/desktop/browser) asset_patterns: linux: amd64: bw-linux-.*\.zip macos: arm64: bw-macos-arm64-.*\.zip amd64: bw-macos-.*\.zip windows: amd64: bw-windows-.*\.zip btop: aristocratos/btop # Resource monitor and process viewer caddy: caddyserver/caddy # Web server with automatic HTTPS choose: theryangeary/choose # Cut alternative with a simpler syntax croc: schollz/croc # File transfer tool with end-to-end encryption ctop: bcicen/ctop # Container metrics and monitoring curlie: rs/curlie # Curl wrapper with httpie-like syntax delta: dandavison/delta # Syntax-highlighting pager for git and diff output difft: Wilfred/difftastic # Structural diff tool that understands syntax direnv: direnv/direnv # Environment switcher for the shell dog: ogham/dog # Command-line DNS client like dig duf: muesli/duf # Disk usage analyzer with pretty output dust: bootandy/dust # More intuitive version of du (disk usage) eget: zyedidia/eget # Go single file downloader (similar to Dotbins) eza: eza-community/eza # Modern replacement for ls fd: sharkdp/fd # Simple, fast alternative to find fzf: junegunn/fzf # Command-line fuzzy finder git-lfs: git-lfs/git-lfs # Git extension for versioning large files glow: charmbracelet/glow # Markdown renderer for the terminal gping: orf/gping # Ping with a graph grex: pemistahl/grex # Command-line tool for generating regular expressions from user-provided examples gron: tomnomnom/gron # Make JSON greppable hexyl: sharkdp/hexyl # Command-line hex viewer hx: helix-editor/helix # Modern text editor hyperfine: sharkdp/hyperfine # Command-line benchmarking tool jc: kellyjonbrazil/jc # JSON CLI output converter jless: PaulJuliusMartinez/jless # Command-line JSON viewer jq: jqlang/jq # Lightweight JSON processor just: casey/just # Command runner alternative to make k9s: derailed/k9s # Kubernetes CLI to manage clusters lazygit: jesseduffield/lazygit # Simple terminal UI for git commands lnav: tstack/lnav # Log file navigator lsd: lsd-rs/lsd # Next-gen ls command with icons and colors mcfly: cantino/mcfly # Fly through your shell history micro: zyedidia/micro # Modern and intuitive terminal-based text editor micromamba: mamba-org/micromamba-releases # Conda-like distribution navi: denisidoro/navi # Interactive cheatsheet tool for the CLI neovim: neovim/neovim # Modern text editor nu: nushell/nushell # Modern shell for the GitHub era pastel: sharkdp/pastel # A command-line tool to generate, convert and manipulate colors procs: dalance/procs # Modern replacement for ps rg: BurntSushi/ripgrep # Fast grep alternative rip: MilesCranmer/rip2 # A safe and ergonomic alternative to rm sd: chmln/sd # Find & replace CLI sk: skim-rs/skim # Fuzzy finder for the terminal in Rust (similar to fzf) starship: starship/starship # Minimal, fast, customizable prompt for any shell tldr: tealdeer-rs/tealdeer # Fast tldr client in Rust topgrade: topgrade-rs/topgrade # Upgrade all your tools at once tre: dduan/tre # Tree command with git awareness xh: ducaale/xh # Friendly and fast tool for sending HTTP requests xplr: sayanarijit/xplr # Hackable, minimal, fast TUI file explorer yazi: sxyazi/yazi # Terminal file manager with image preview yq: mikefarah/yq # YAML/XML/TOML processor similar to jq zellij: zellij-org/zellij # Terminal multiplexer zoxide: ajeetdsouza/zoxide # Smarter cd command with learning keychain: funtoo/keychain # ssh-agent manager platforms: linux: - amd64 - arm64 macos: - arm64
🔧 Troubleshooting
Common Issues
GitHub API Rate Limits
Issue: Failed to fetch latest release: rate limit exceeded
Solution:
- Create a GitHub token with
public_reposcope - Use the token with:
dotbins sync --github-token YOUR_TOKEN - Or set the environment variable:
GITHUB_TOKEN=YOUR_TOKEN dotbins sync - Tip: Use
GITHUB_TOKEN=$(gh auth token) dotbins syncto use your existing GitHub CLI token
Windows-Specific Issues
Issue: PowerShell execution policy preventing script execution Solution:
- Run PowerShell as administrator
- Execute:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Getting Help
- Enable verbose logging with
-vflag:dotbins sync -v - Check all installed tool versions with:
dotbins status - Join GitHub Discussions for help: https://github.com/basnijholt/dotbins/discussions
🤔 Comparison with Alternatives
dotbins fills a specific niche in the binary management ecosystem. Here's how it compares to key alternatives:
| Tool | Version Management | Shell Integration | Dotfiles Integration | Primary Use Case |
|---|---|---|---|---|
| dotbins | Latest only | Built-in via shell_code |
First-class with Git (LFS) | Complete dotfiles solution |
| binenv | Multiple versions with constraints | Separate completion scripts | Not focused on | Development environments |
| eget | Latest or specific only | None | Not focused on | Quick one-off installs |
| asdf/aqua | Multiple plugins & versions | Plugin-specific | Not focused on | Development environments |
| apt/brew | System packages | None | Not possible | System-wide management |
Key Alternatives
Version Managers (e.g., binenv, asdf)
- Pros: Advanced version management (constraints like
>=1.2.3), multiple versions side-by-side - Cons vs.
dotbins:- Focus on version management rather than dotfiles integration
- Separate configuration needed for shell integration (aliases, completions)
- Often use shims or more complex architecture
- When to choose: For development environments where you need multiple versions of tools
Binary Downloaders (e.g., eget)
- Pros: Lightweight, fast for one-off downloads
- Cons vs.
dotbins:- No configuration for multiple tools
- No shell integration for aliases or environment setup
- No version tracking between sessions
- When to choose: For quick installation of individual tools without configuration needs
System Package Managers (apt, brew, etc.)
- Pros: System-wide installation, dependency management
- Cons vs.
dotbins:- Require admin privileges
- Not portable across systems
- Cannot be version-controlled in dotfiles
- When to choose: For system-wide software needed by multiple users
The dotbins Difference
dotbins uniquely combines:
- Binary management - Downloading from GitHub Releases
- Shell configuration - Defining aliases and shell setup in the same file:
bat: repo: sharkdp/bat shell_code: | alias cat="bat --plain --paging=never"
- Dotfiles integration - Designed to be version-controlled as a Git repository
- Cross-platform portability - Works the same across Linux, macOS, Windows
This makes it perfect for users who want to manage their complete shell environment in a version-controlled dotfiles repository that can be easily deployed on any system.
❤️ Support and Contributions
We appreciate your feedback and contributions! If you encounter any issues or have suggestions for improvements, please file an issue on the GitHub repository. We also welcome pull requests for bug fixes or new features.
Happy tooling! 🧰🛠️🎉