A lightweight dotfiles manager that generates self-contained shell scripts. No submodules, no dependencies on the target system—just pure bash. Heavily inspired by dotbot.
Unlike dotbot which requires installation on each machine, dotbash generates a single install.sh script that contains everything needed to set up your dotfiles. This makes it perfect for quick system setup without external dependencies.
- Zero Dependencies - Generated scripts are pure bash with no external dependencies
- JSON Schema Validation - Full schema support for IDE autocomplete and validation
- Symlink Management - Create, relink, or force-replace symlinks with configurable defaults
- Package Management - Automatic Homebrew installation and package setup
- Shell Commands - Execute custom setup commands with error handling
- Simple Configuration - Clean YAML or JSON config format
Install globally with Bun:
bun install -g dotbashOr run directly:
bun src/cli.ts -i dotbash.yaml -o install.shCreate dotbash.yaml in your dotfiles directory:
# yaml-language-server: $schema=https://raw.githubusercontent.com/alinalihassan/dotbash/refs/heads/main/schema.json
defaults:
link:
relink: true
force: true
create: true
link:
~/.gitconfig: git/.gitconfig
~/.config/nvim: nvim
~/.config/fish: fish
packageManager:
installSelf: true
dependenciesFile: brew/Brewfile
shell:
- description: Set Fish as default shell
command: |
FP=$(command -v fish)
grep -Fxq "$FP" /etc/shells || echo "$FP" | sudo tee -a /etc/shells
[ "$SHELL" = "$FP" ] || chsh -s "$FP" "$USER"
- description: Install Fish Plugins
command: fish -c "fisher update"dotbash -i dotbash.yaml -o install.shOr use defaults (looks for dotbash.yaml, outputs to install.sh):
dotbashgit clone <your-dotfiles-repo>
cd <your-dotfiles>
./install.shThat's it! No need to install dotbash on the target system.
Set default behavior for links and shell commands:
defaults:
link:
create: true # Create parent directories if they don't exist
relink: true # Remove old symlinks before creating new ones
force: true # Force remove old files/directories
shell:
quiet: false # Show output from shell commandsMap destination paths to source files/directories:
link:
~/.gitconfig: git/.gitconfig
~/.config/nvim: nvim
~/.config/fish: fish
~/Library/Application Support/lazygit/config.yml: lazygit/config.ymlThe source paths are relative to your dotfiles directory. Destination paths support ~ for home directory expansion.
Automatically install Homebrew and packages from a Brewfile:
packageManager:
installSelf: true # Install Homebrew if not present
dependenciesFile: brew/Brewfile # Path to your BrewfileCreate a brew/Brewfile:
brew "git"
brew "fish"
brew "neovim"
brew "ripgrep"
Execute custom setup commands with optional descriptions:
shell:
- description: Set Fish as default shell
command: chsh -s $(command -v fish)
- description: Clone a repository
command: git clone https://github.com/user/repo ~/projects/repo
quiet: true # Suppress output for this commandCommands are executed sequentially and stop on the first error.
The install.sh script generated by dotbash:
- Creates symlinks - Sets up all configured links with proper error handling
- Installs packages - Installs Homebrew (on macOS) and packages from Brewfile
- Runs commands - Executes all shell commands in order with error reporting
- Handles errors - Exits on first error with clear error messages
Example output:
$ ./install.sh
Setting up: ~/.gitconfig -> git/.gitconfig
✓ Linked ~/.gitconfig
Setting up: ~/.config/nvim -> nvim
✓ Linked ~/.config/nvim
All symlinks created successfully!
Package Manager Setup
Checking for Homebrew...
✓ Homebrew already installed
Installing packages from brew/Brewfile...
✓ Packages installed successfully
Set Fish as default shell...
✓ Set Fish as default shell completed
Install Fish Plugins...
✓ Install Fish Plugins completed
All shell commands completed successfully!
link:
~/.gitconfig: .gitconfig
~/.config/nvim: .config/nvimdefaults:
link:
create: true
relink: true
force: true
link:
~/.gitconfig: git/.gitconfig
~/.gitignore_global: git/.gitignore_global
~/.config/nvim: nvim
~/.config/fish: fish
~/.config/bat: bat
~/.config/ghostty: ghostty
packageManager:
installSelf: true
dependenciesFile: brew/Brewfile
shell:
- description: Set Fish as default shell
command: chsh -s $(command -v fish)
- description: Install Fisher
command: fish -c "curl -sL https://git.io/fisher | source && fisher install jorgebucaran/fisher"Clone and develop locally:
git clone <this-repo>
cd dotbash
bun install
bun src/cli.ts -i dotbash.yaml -o install.shMIT