How to Include Custom Scripts in a Dotfiles Repository: A Complete Guide

You can add custom scripts to the issmirnov/dotfiles repository by placing executables in the bin/ directory for command-line tools or *.zsh files in zsh/config/ for Zsh functions, then running ./install to create symlinks via Dotbot.

Managing a personal dotfiles repository requires an extensible system for custom utilities. The issmirnov/dotfiles repository provides two distinct mechanisms for including your own scripts without modifying core configuration files. Whether you need standalone command-line tools or shell-specific functions, the repository's Dotbot-based architecture automatically exposes your scripts to the system after installation.

Understanding the Two Mechanisms for Custom Scripts

The repository implements a dual-path approach to script management. Based on how you intend to use your code, you can choose between system-wide executables or Zsh-specific helpers.

The bin/ Directory for Executable Scripts

Any file placed in the bin/ directory becomes a system command after installation. According to the default.conf.yaml configuration, Dotbot creates a symlink from ~/bin/dotbin to the repository's bin/ folder. Because ~/bin is already included in your $PATH (as documented in bin/README.md), scripts placed here are instantly accessible from any shell session.

The Zsh Config Loader for Shell Functions

For Zsh-specific functionality, the repository loads all *.zsh files from zsh/config/ and zsh/aliases/ on startup. The zsh/zshrc file contains a loader loop (lines 52–57) that sources these files automatically. This mechanism is ideal for helper functions, aliases, and Zsh Line Editor (ZLE) widgets that don't need to be standalone executables.

Step-by-Step Guide to Adding Scripts

Adding custom scripts requires no configuration file edits—just proper placement and execution permissions.

Adding a Command-Line Tool to bin/

Place your script in the bin/ directory (or a subdirectory) and make it executable:


# Create the script

cat > bin/hello-world.sh << 'EOF'
#!/usr/bin/env bash
echo "Hello from my custom script!"
EOF

# Make it executable

chmod +x bin/hello-world.sh

Run the installer to create the symlink:

./install

Dotbot creates the link ~/bin/dotbin → <repo>/bin, making your script available as hello-world.sh from any terminal.

You can also organize tools into subdirectories:


# Structure

bin/
└─ mytools/
   └─ convert-img.sh

After installation, invoke it directly:

convert-img.sh

Adding a Zsh Helper Function

For functions that only need to exist inside Zsh sessions, create a .zsh file in the config directory:


# zsh/config/myutils.zsh

my_greet() {
  echo "Welcome, $USER!"
}

weather() {
  curl -s "wttr.in/${1:-$(hostname)}?0"
}

No installation step is required for Zsh functions—the loader in zsh/zshrc automatically sources these files on the next shell startup:

find ~/.dotfiles/zsh/config ~/.dotfiles/zsh/aliases -type f -name '*.zsh' -print0 |
  while IFS= read -r -d $'\0' line; do
    source "$line"
  done

How the Symlinking Works Under the Hood

The repository uses Dotbot to manage all file mappings. The critical configuration lives in default.conf.yaml, which defines the ~/bin/dotbin: bin mapping. This creates a symbolic link from your home directory to the repository, ensuring that any script added to the repository's bin/ folder immediately appears in your local ~/bin/dotbin path.

The install script serves as the entry point that executes Dotbot with the appropriate configuration files. When you run ./install (or minstall for minimal installation), Dotbot processes default.conf.yaml and establishes all necessary symlinks while preserving existing files.

Summary

  • Place executables in bin/ to create system-wide commands accessible via $PATH after running ./install
  • Place *.zsh files in zsh/config/ or zsh/aliases/ for Zsh-specific functions and aliases that load automatically
  • Run ./install after adding scripts to the bin/ directory to create the necessary symlinks via Dotbot
  • Reference default.conf.yaml to understand how Dotbot maps repository folders to your home directory
  • Check bin/README.md for documentation about the $PATH configuration

Frequently Asked Questions

Do I need to modify any configuration files to add a new script?

No. The repository uses convention-based loading. Simply drop executable files into bin/ or .zsh files into zsh/config/ and they will be picked up automatically. You only need to run ./install if you added files to bin/; Zsh config files are sourced dynamically on every shell startup.

The default.conf.yaml maps ~/bin/dotbin to the repository's bin/ folder rather than replacing your entire ~/bin directory. This approach preserves any existing binaries in your home directory while still exposing repository scripts through the $PATH, which typically includes ~/bin or can be configured to include ~/bin/dotbin specifically.

Can I organize scripts into subdirectories within bin/?

Yes. The Dotbot configuration symlinks the entire bin/ directory, so subdirectories like bin/mytools/ are preserved and accessible. You can invoke scripts within subdirectories directly if your $PATH includes the parent directory, or reference them explicitly as dotbin/mytools/script-name.

What's the difference between placing a script in bin/ versus zsh/config/?

Scripts in bin/ become standalone executables available to all shells (Bash, Zsh, etc.) and external processes, while files in zsh/config/ are sourced as shell code specific to Zsh. Use bin/ for complete programs and command-line tools; use zsh/config/ for functions, aliases, and widgets that depend on Zsh-specific features or variables.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →