# How to Configure Zsh Aliases and Functions in the dotfiles Repository

> Learn to configure Zsh aliases and functions in your dotfiles repository. Discover a powerful three-layer architecture using Zgen for efficient customization and automatic sourcing.

- Repository: [Ivan Smirnov/dotfiles](https://github.com/issmirnov/dotfiles)
- Tags: how-to-guide
- Published: 2026-03-04

---

**The dotfiles repository organizes Zsh customizations through a three-layer architecture using Zgen for plugin management, followed by automatic sourcing of all `*.zsh` files in `zsh/config` and `zsh/aliases`, plus an optional local override file.**

This guide walks through the configuration system in the `issmirnov/dotfiles` repository, showing exactly where to place aliases and functions, how the loading mechanism works, and how to extend the setup without breaking existing conventions.

## Overview of the Three-Layer Architecture

The `zsh/zshrc` file implements a strict loading order that separates concerns between external plugins and custom code:

1. **Plugin Manager (Zgen)** – Loads Oh-My-Zsh, plugins, and syntax highlighting first (lines 20–48)
2. **Custom Configuration** – Sources every `*.zsh` file from `zsh/config` and `zsh/aliases` directories in alphabetical order (lines 52–58)
3. **Local Overrides** – Sources `~/.zshrc.local` last for machine-specific tweaks without version control (line 66)

This structure ensures that your custom aliases in `zsh/aliases/` always override plugin defaults, while maintaining a clean separation between shared and private configuration.

## Where Aliases Live

All alias definitions reside in the `zsh/aliases/` directory as plain Zsh statements. The repository ships with several categorized files:

### Utility Aliases

The [`zsh/aliases/utilities.zsh`](https://github.com/issmirnov/dotfiles/blob/main/zsh/aliases/utilities.zsh) file contains general-purpose shortcuts:

```zsh
alias o='open'
alias gurl='curl --compressed'
alias week='date +%V'
alias zsh-reload='source ~/.zshrc'

```

### System-Specific Aliases

Platform-aware definitions live in [`zsh/aliases/system.zsh`](https://github.com/issmirnov/dotfiles/blob/main/zsh/aliases/system.zsh) and platform-specific files like [`ubuntu.zsh`](https://github.com/issmirnov/dotfiles/blob/main/ubuntu.zsh) or [`osx.zsh`](https://github.com/issmirnov/dotfiles/blob/main/osx.zsh):

```zsh
alias sudo='sudo '
alias ll='ls -lha --color'
alias open='xdg-open'

```

### Suffix Aliases

Special "suffix aliases" defined in [`zsh/aliases/suffixes.zsh`](https://github.com/issmirnov/dotfiles/blob/main/zsh/aliases/suffixes.zsh) automatically invoke commands based on file extensions:

```zsh
alias -s pdf='open'
alias -s html='open'

```

When you type `report.pdf`, Zsh automatically expands it to `open report.pdf`.

## Where Functions Live

Reusable shell functions are defined alongside aliases, primarily in [`zsh/aliases/utilities.zsh`](https://github.com/issmirnov/dotfiles/blob/main/zsh/aliases/utilities.zsh). These are automatically available because the `zshrc` loader sources every `*.zsh` file found in the directories.

Example functions from the source:

```zsh
function to {
    if [[ -z "$1" ]]; then
        echo "Usage: to <file name>"
    else
        echo "Now writing out to $1. Type ^D to finish."
        cat >| "$1"
    fi
}

function pdfsearch() {
    [ -z "$1" ] && echo "Error: No search term supplied" && exit 1
    find . -name '*.pdf' | xargs -I {} sh -c "pdftotext \"{}\" - | grep --with-filename --label=\"{}\" --color $1"
}

```

## Adding New Aliases and Functions

To extend the configuration, create or edit files in the `zsh/aliases/` directory:

1. **Create a new file** (e.g., [`zsh/aliases/docker.zsh`](https://github.com/issmirnov/dotfiles/blob/main/zsh/aliases/docker.zsh)) or edit an existing one like [`utilities.zsh`](https://github.com/issmirnov/dotfiles/blob/main/utilities.zsh)
2. **Add your definitions** using standard Zsh syntax:

```zsh

# zsh/aliases/git_custom.zsh

alias gco='git checkout'
alias gl='git log --oneline --graph'

function mkcd() {
    mkdir -p "$1" && cd "$1"
}

```

3. **Reload the shell** using the provided alias:

```zsh
zsh-reload

```

Or source a specific file directly:

```zsh
source ~/.dotfiles/zsh/aliases/git_custom.zsh

```

## Understanding the Loading Order

The sourcing mechanism in `zsh/zshrc` (lines 52–58) uses a deterministic alphabetical loading strategy:

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

```

**Key implementation details:**
- **Alphabetical ordering** – `sort -z` ensures files load predictably regardless of filesystem order
- **Null-terminated strings** – `-print0` and `-d $'\0'` handle filenames with spaces safely
- **Sourcing scope** – Each file executes in the current shell context via `source`, making aliases and functions immediately available

Because this block executes after Zgen initializes plugins, any definitions in `zsh/aliases/` automatically override plugin defaults of the same name.

## Best Practices for Organizing Zsh Configuration

When extending the dotfiles repository, follow these patterns established in the source code:

- **Group logically** – Create separate files for different concerns (e.g., [`docker.zsh`](https://github.com/issmirnov/dotfiles/blob/main/docker.zsh), [`kubernetes.zsh`](https://github.com/issmirnov/dotfiles/blob/main/kubernetes.zsh)) rather than dumping everything into [`utilities.zsh`](https://github.com/issmirnov/dotfiles/blob/main/utilities.zsh)
- **Use descriptive filenames** – The alphabetical sort means [`10-utils.zsh`](https://github.com/issmirnov/dotfiles/blob/main/10-utils.zsh) loads before [`99-local.zsh`](https://github.com/issmirnov/dotfiles/blob/main/99-local.zsh) if you need explicit ordering
- **Check for collisions** – Run `alias | grep 'your-alias'` before adding new shortcuts to avoid unexpected overwrites
- **Prefer functions for complexity** – When logic requires conditionals or loops, defined a function in [`utilities.zsh`](https://github.com/issmirnov/dotfiles/blob/main/utilities.zsh) rather than a complex alias
- **Leverage suffix aliases** – For file types you frequently open, use `alias -s ext='command'` syntax in [`zsh/aliases/suffixes.zsh`](https://github.com/issmirnov/dotfiles/blob/main/zsh/aliases/suffixes.zsh)

## Summary

- The **three-layer architecture** loads plugins first, then custom `*.zsh` files from `zsh/config` and `zsh/aliases`, finally `~/.zshrc.local`
- **Aliases** belong in `zsh/aliases/*.zsh` files, categorized by purpose (utilities, system, suffixes)
- **Functions** are defined in the same `*.zsh` files and sourced automatically by the `find` loop in `zsh/zshrc`
- The loading mechanism uses **alphabetical sorting** (`sort -z`) to ensure deterministic behavior
- Use `zsh-reload` to refresh configuration after making changes

## Frequently Asked Questions

### How do I override a plugin alias with my own definition?

Add the conflicting alias to any file in `zsh/aliases/` (such as [`system.zsh`](https://github.com/issmirnov/dotfiles/blob/main/system.zsh)). Because these files source after Zgen loads Oh-My-Zsh and plugins, your definition wins. For example, if a plugin defines `alias ll='ls -l'`, add `alias ll='ls -lha --color'` to override it.

### Can I organize aliases into subdirectories within zsh/aliases?

The current `find` command in `zsh/zshrc` searches only for `*.zsh` files within the top-level directories `zsh/config` and `zsh/aliases`. While `find` traverses subdirectories, keep aliases in the root of `zsh/aliases/` to ensure predictable loading order and prevent naming collisions.

### What is the difference between zsh/config and zsh/aliases?

**`zsh/config/`** contains environment settings, prompt configuration, bindkeys, and tool integrations (like fzf). **`zsh/aliases/`** contains command shortcuts, suffix aliases, and function definitions. Both directories are sourced identically, but the separation helps maintain organization as the configuration grows.

### How do I temporarily disable an alias without deleting the file?

Add an unalias command to your `~/.zshrc.local` file, which sources last. For example, `unalias ll` removes the alias for that session. Alternatively, prepend the command with `\` (backslash) to bypass alias expansion for a single execution: `\ll` runs the original binary regardless of aliases.