How zflash Works
Understanding the moving parts makes zflash easy to maintain: you will know which file to edit, when a rebuild happens, and why something loads when it does.
Build time vs. start time
zflash splits its work into two very different moments:
| Build time | Shell start | |
|---|---|---|
| Triggered by | zflash build, update, reset, or zflash boot noticing a stale init | Every new interactive shell |
| Reads | Your spec | The compiled init only |
| Does | Clones repos, finds plugin files, runs zflash eval commands, collects completion dirs, writes and byte-compiles init.zsh | Sources init.zsh.zwc |
| Cost | Seconds (network, git) | Milliseconds |
What happens when a shell starts
- Bootstrap.
.zshrcsourceszflash.zsh, about twenty lines that define a stubzflashfunction and a few variables. - Boot.
zflash boot <spec>checks whether the init needs rebuilding (see below), then sources~/.cache/zflash/init.zsh(its byte-compiled.zwcform). - Stage 1, before the prompt. The init sets
fpath(all completion dirs, hoisted), installs acompdefstub that queues calls, sources everyloaditem and inlinedevalsnippet, and loads zsh-defer. - The prompt is drawn.
- Stage 2, after the prompt. When the line editor is idle, a few milliseconds later, zsh-defer runs the queue: cached
compinitfirst, then the queuedcompdefcalls, then everydeferitem in spec order. Finally the prompt is redrawn once and precmd hooks run. - Background update check. Every
ZFLASH_AUTO_UPDATEdays, stage 2 startszflash update --quietin the background. See Updating plugins.
The manager code in lib/core.zsh is loaded only when you run a zflash command or a rebuild is needed. It is never parsed during a normal start.
When does zflash rebuild?
zflash boot rebuilds automatically when any of these is true:
- The init file (
~/.cache/zflash/init.zsh) is missing or empty. - The spec file is newer than the init.
- zflash's own
lib/core.zshis newer than the init, which happens after you upgrade zflash.
It does not rebuild when:
- A tool used by
zflash eval(starship, zoxide, fzf…) is upgraded. Runzflash buildyourself. - A plugin repo changes on disk.
zflash updaterebuilds for you.
Your own files (zflash load ~/.zsh/exports) don't need a rebuild either. They are recompiled on the fly whenever they are newer than their .zwc.
Completions and compinit
compinit is the slowest part of most zsh startups. zflash:
- Hoists every directory containing
_*completion files, from every spec line, to the front offpathbefore compinit runs, whatever the line's stage. - Defers compinit to stage 2 (when anything is deferred) and queues
compdefcalls made before it, replaying them afterwards. - Caches the dump: it stores a signature (zsh version, full
fpath, and the count of generated oh-my-zsh completions) next to the dump. While the signature matches and the dump is younger thanZFLASH_COMPINIT_TTLhours (24), it runscompinit -C, which just loads the byte-compiled dump.
A Tab pressed in the first few milliseconds, before stage 2 has run, falls back to zsh's built-in completion. See Completions to change this behavior.