Skip to main content

Keep updated binaries in your dotfiles

Project description

dotbins 🧰

Build Status Coverage GitHub PyPI License Downloads Open Issues

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] 📚

:zap: Quick Start

Using the amazing uv package manager (uv tool install dotbins):

# Install directly to ~/.local/bin (no configuration needed)
dotbins get junegunn/fzf

# Set up multiple tools with a config file (creates ~/.dotbins)
dotbins sync

# Bootstrap a collection of tools from a remote config
dotbins get https://github.com/basnijholt/.dotbins/blob/main/dotbins.yaml

See it in action:

asciicast

:star2: 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
  • 📊 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 PATH and applies custom shell snippets (shell_code).

:bulb: 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:

  1. Track pre-compiled binaries in a separate Git repository (using Git LFS for efficient storage)
  2. Include that repository as a submodule in my dotfiles
  3. 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!

:books: Usage

[!TIP] Use uvx dotbins and create a ~/.config/dotbins/config.yaml file to store your configuration.

To use dotbins, you'll need to familiarize yourself with its commands:

dotbins --help
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

  1. sync - Install and update tools to their latest versions
  2. get - Download and install a tool directly without using a configuration file
  3. init - Initialize the tools directory structure
  4. list - List available tools defined in your configuration
  5. version - Print version information
  6. status - Show detailed information about available and installed tool versions

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.

:hammer_and_wrench: Installation

We highly recommend to use uv to run dotbins:

uvx dotbins

or install as a global command:

uv tool install dotbins

Otherwise, simply use pip:

pip install dotbins

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.

:gear: Configuration

dotbins uses a YAML configuration file to define the tools and settings. The configuration file is searched in the following locations (in order):

  1. Explicitly provided path (using --config-file option)
  2. ./dotbins.yaml (current directory)
  3. ~/.config/dotbins/config.yaml (XDG config directory)
  4. ~/.config/dotbins.yaml (XDG config directory, flat)
  5. ~/.dotbins.yaml (home directory)
  6. ~/.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.

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

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).

When auto-detection isn't possible or you want more control, you can provide detailed configuration:

tool-name:
  repo: owner/repo                 # Required: GitHub repository
  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

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

You can specify defaults for handling multiple assets that work on your architecture.

# Global defaults for all tools
defaults:
  prefer_appimage: true   # Set to true to prefer AppImage when available
  libc: musl              # Use 'glibc' or 'musl'

These are the actual defaults too.

Why musl and AppImage?

  • 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 found errors), 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.)

Pattern Variables

In asset patterns, you can use these variables:

  • {version} - Release version (without 'v' prefix)
  • {platform} - Platform name (after applying platform_map)
  • {arch} - Architecture name (after applying arch_map)

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

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:

starship:
  repo: starship/starship
  shell_code:
    zsh: eval "$(starship init zsh)"
    bash: eval "$(starship init bash)"
    fish: starship init fish | source

Full Configuration Example

This is the author's configuration file:

tools_dir: ~/.dotbins

platforms:
  linux:
    - amd64
    - arm64
  macos:
    - arm64

tools:
  delta: dandavison/delta
  duf: muesli/duf
  dust: bootandy/dust
  fd: sharkdp/fd
  git-lfs: git-lfs/git-lfs
  hyperfine: sharkdp/hyperfine
  rg: BurntSushi/ripgrep
  yazi: sxyazi/yazi

  atuin:
    repo: atuinsh/atuin
    shell_code: |
      source <(atuin init zsh --disable-up-arrow)
  bat:
    repo: sharkdp/bat
    shell_code: |
      alias bat="bat --paging=never"
      alias cat="bat --plain --paging=never"
  direnv:
    repo: direnv/direnv
    shell_code: |
      eval "$(direnv hook zsh)"
  eza:
    repo: eza-community/eza
    shell_code: |
      alias l="eza -lah --git"
  fzf:
    repo: junegunn/fzf
    shell_code: |
      source <(fzf --zsh)
  lazygit:
    repo: jesseduffield/lazygit
    shell_code: |
      alias lg="lazygit"
  micromamba:
    repo: mamba-org/micromamba-releases
    shell_code: |
      alias mm="micromamba"
  starship:
    repo: starship/starship
    shell_code: |
      eval "$(starship init zsh)"
  zoxide:
    repo: ajeetdsouza/zoxide
    shell_code: |
      eval "$(zoxide init zsh)"

  uv:
    repo: astral-sh/uv
    binary_name: [uv, uvx]
    path_in_archive: [uv-*/uv, uv-*/uvx]
    shell_code: |
      eval "$(uv generate-shell-completion zsh)"

:bulb: Examples

List all available tools in your configuration:

dotbins list

Install or update all tools for all configured platforms:

dotbins sync

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 tools only for your current system:

dotbins sync -c

Force reinstall even if tools are up to date:

dotbins sync --force

Install tools from a remote configuration:

dotbins get https://raw.githubusercontent.com/username/dotbins-config/main/tools.yaml --dest ~/bin

Show status (installed, missing tools, last updated) for all installed tools:

dotbins status

Show a compact view of installed tools (one line per tool):

dotbins status --compact

Show tools only for the current platform/architecture:

dotbins status --current

Filter tools by platform or architecture:

dotbins status --platform macos
dotbins status --architecture arm64

:computer: Shell Integration

dotbins creates shell scripts that you can source to automatically add the correct binaries to your PATH.

After running dotbins sync or dotbins init, shell integration scripts are created in ~/.dotbins/shell/ for various shells.

Check the output of dotbins init to see which shell scripts were created and how to add them to your shell configuration file:

 Loading configuration from: ~/work/dotbins/dotbins/dotbins.yaml
🛠️ dotbins initialized tools directory structure in `tools_dir=~/.dotbins`
📝 Generated shell scripts in ~/.dotbins/shell/
🔍 Add this to your shell config:
👉   Bash:       source $HOME/.dotbins/shell/bash.sh
👉   Zsh:        source $HOME/.dotbins/shell/zsh.sh
👉   Fish:       source $HOME/.dotbins/shell/fish.fish
👉   Nushell:    source $HOME/.dotbins/shell/nushell.nu
👉   PowerShell: . $HOME/.dotbins/shell/powershell.ps1
ℹ️ To see the shell setup instructions, run `dotbins init`
📝 Generated README at ~/.dotbins/README.md

:books: 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
  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

platforms:
  linux:
    - amd64
    - arm64
  macos:
    - arm64

:thinking: 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:

  1. Binary management - Downloading from GitHub Releases
  2. Shell configuration - Defining aliases and shell setup in the same file:
    bat:
      repo: sharkdp/bat
      shell_code: |
        alias cat="bat --plain --paging=never"
    
  3. Dotfiles integration - Designed to be version-controlled as a Git repository
  4. 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.

:heart: 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! 🧰🛠️🎉

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dotbins-0.37.0.tar.gz (81.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dotbins-0.37.0-py3-none-any.whl (47.9 kB view details)

Uploaded Python 3

File details

Details for the file dotbins-0.37.0.tar.gz.

File metadata

  • Download URL: dotbins-0.37.0.tar.gz
  • Upload date:
  • Size: 81.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for dotbins-0.37.0.tar.gz
Algorithm Hash digest
SHA256 5e6d9ff4344607a0bb4748d49b162cdfcd1076d80127f3ee5760f766628f4f22
MD5 4ea86609a51a4eb594e7d2258fde96ff
BLAKE2b-256 1e7493d5ff7dcb8e25a40f6605c960468086fcd1bc3a4844165ee1e502378e47

See more details on using hashes here.

Provenance

The following attestation bundles were made for dotbins-0.37.0.tar.gz:

Publisher: release.yml on basnijholt/dotbins

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dotbins-0.37.0-py3-none-any.whl.

File metadata

  • Download URL: dotbins-0.37.0-py3-none-any.whl
  • Upload date:
  • Size: 47.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for dotbins-0.37.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c8357a3e19f68ddc670e5d4bffda21685eb1be8d5186d5167a05e7c50cfe24fb
MD5 7fae4e03e082f59e0a7c3ffcc25b4fbc
BLAKE2b-256 c52f32cd686045f6919f8db6ce34d869563bc328af0df0cb69f805d4ebecd6b4

See more details on using hashes here.

Provenance

The following attestation bundles were made for dotbins-0.37.0-py3-none-any.whl:

Publisher: release.yml on basnijholt/dotbins

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page