Skip to content

The Zsh Module System

Gerrrt edited this page Jun 14, 2026 · 1 revision

The Zsh Module System

The zsh configuration is the heart of Core. Rather than one monolithic .zshrc, Core ships a set of focused modules under zsh/, and each OS repo's .zshrc loader sources them in a specific order. That order is load-bearing — getting it wrong silently breaks completion, keybindings, or the prompt.

The load order

Each OS repo's .zshrc sources the modules in exactly this sequence:

tools → ui → options → history → aliases → git → functions → fzf →
bindings → plugins → op → maint → update → os → local

The last two (os, local) are not in this repo — they're the OS repo's own native layer and your machine-local untracked overrides. Everything before them is Core. (dotfiles-Kali inserts an extra offensive stage: … os offensive local.)

Why the order matters

The dependencies between modules are real, not cosmetic:

  • tools is first because it initializes atuin (which registers its zle widget), sets the HAVE_* detection flags every later module reads, and puts ~/.local/bin on PATH before anything probes for tools.
  • ui loads right after tools because it only defines the _core_* UX helpers (_core_err, _core_warn, _core_confirm, _core_spin, …) that every later module may call.
  • options runs compinit (the completion system) — both fzf-tab and carapace need it to already have run.
  • fzf defines its zle widgets before plugins loads zsh-vi-mode, whose init fires the keybinding hook in bindings.
  • bindings registers the keymap via zsh-vi-mode's zvm_after_init hook, so it must be defined before plugins sources vi-mode.

The canonical order lives in core.manifest.

Module-by-module

tools.zsh — detection + single init point (load FIRST)

The one place the modern-CLI stack is detected and the shell-hook tools (zoxide, starship, atuin, mise) are initialized. It:

  • Probes each tool with command -v and sets HAVE_* flags (HAVE_EZA, HAVE_BAT, HAVE_FD, …) that aliases.zsh, functions.zsh, and fzf.zsh guard on.
  • Resolves binaries that ship under alternate names on some distros — Debian/ Ubuntu ship fd as fdfind and bat as batcat, so it sets $FD_BIN and $BAT_BIN to the real name.
  • Caches the four init scripts (zoxide init, starship init, etc.) under $XDG_CACHE_HOME/zsh/*.zsh via _cache_eval, regenerating only when the binary is newer than its cache. This turns an eval-of-subprocess into a plain source, removing per-shell subprocess spawns from the startup hot path.

ui.zsh — terminal-UX primitives

Defines Core's voice: _core_err / _core_warn / _core_ok / _core_hint / _core_confirm / _core_spin. These are gum-aware (prettier when gum is installed) and respect NO_COLOR and non-TTY output. _core_confirm declines when there's no TTY, which is what makes functions like extract and please safe to run non-interactively.

options.zsh — setopts + completion system

Sets the setopt flags, runs compinit (cached), and configures zstyle completion styling. Because it runs compinit, it must come before fzf-tab and carapace (both in plugins.zsh).

history.zsh — history config

HISTFILE / HISTSIZE / SAVEHIST, the history setopts, and a secret-ignore pattern so credentials don't land in history.

aliases.zsh — modern-CLI aliases (guarded)

Every alias touching an optional tool is guarded by its HAVE_* flag, so on a bare box you transparently get the classic command. See Tools, Aliases & Functions for the full list.

git.zsh — curated git aliases + helpers

A hand-picked subset of the oh-my-zsh git plugin with the framework stripped out — naming matches OMZ so muscle memory transfers. Includes git_main_branch and git_current_branch helpers so branch-aware aliases work whether the trunk is main, master, trunk, etc. Two deliberate safety upgrades over OMZ: gpf uses --force-with-lease (raw force is the explicit gpf!).

functions.zsh — cross-OS shell functions

mkcd, cdup, extract (with tarbomb + clobber guards), fcd, please, mkbak, serve, plus the discoverability commands core-help / core-doctor / core-version. All POSIX-ish so they behave the same on macOS zsh, Linux zsh, and Alpine's busybox-adjacent environment.

fzf.zsh — fzf env + zle widgets

fzf defaults plus the custom zle widgets (Ctrl-F file picker, Ctrl-R history, Alt-Z zoxide jump, Ctrl-G session picker) and the fif / fbr functions. Loads before bindings and plugins so the widgets exist when the keybinding hook fires. Preview commands resolve $BAT_BIN so they don't print "command not found" on Debian where bat is batcat.

bindings.zsh — vi-mode keybindings

Registers the keymap via zsh-vi-mode's zvm_after_init hook, because vi-mode resets all bindings on init. Sets cursor shapes per mode and binds the fzf widgets, atuin (Ctrl-E), and autosuggest-toggle (Ctrl-\).

plugins.zsh — lightweight plugin loader

No Oh My Zsh, no Zinit. Plugins are auto-cloned on first launch and pinned to specific commits (supply-chain safety — these are the only third-party code running in every interactive shell across all nine repos). zsh-defer async-loads the two heaviest plugins (autosuggestions + fast-syntax-highlighting) after the first prompt paints. The pinned set:

Plugin Role
romkatv/zsh-defer async-load the heavy plugins
jeffreytse/zsh-vi-mode vi-mode (loaded synchronously; fires the hook)
zsh-history-substring-search Up/Down history substring match
zsh-autosuggestions inline suggestion from history (deferred)
fast-syntax-highlighting command-line syntax highlighting (deferred)
Aloxaf/fzf-tab fzf-driven tab completion
zsh-you-should-use nudges you toward your aliases

make update-plugins (via scripts/update-plugins.sh) is the only thing that moves a pin — the runtime never floats.

op.zsh — 1Password CLI helpers

opsecret / openv / optoken / opssh wrappers around the op CLI.

maint.zsh — daily-maintenance control surface

maint-install / maint-run / maint-log — schedule and inspect the daily safe-update job (the runner itself is maint/dotfiles-maint.sh).

update.zsh — the up updater + nudge

The up package-updater and a once-per-day "updates available" nudge.

completions/ — autoloaded completions

zsh completion files for Core's own verbs (up, extract, mkcd, core-doctor, …), added to fpath by options.zsh.

Performance note

Two things keep startup fast: tools.zsh caches the four shell-hook init scripts so they're a plain source rather than a subprocess, and plugins.zsh defers the two heaviest plugins until after the first prompt. Measure Core's contribution with:

hyperfine 'zsh -i -c exit'
# or, from the repo:
make bench

See also

Clone this wiki locally