⚡️ Installation
Automated setup
- Verify the sha256 checksum for file: public/sh/install.sh
- If required append -b <tag> or -b <branch> e.g:
sh -c "$(curl -fsSL get.zshell.dev)" -- -b main
The normal default command runs the guided loader profile. The install.sh script is standalone: when sibling assets are unavailable, it downloads setup.sh, profiles.tsv, init.zsh, and checksum.txt from the selected ZI_SRC_REF (defaulting to main), then verifies every companion asset against that matching checksum manifest before plan/apply. The repository does not need to be cloned.
- Loader
- Install-only (-i skip)
- Annex
- ZUnit
- Agent
Install and include the guided loader configuration in .zshrc:
sh -c "$(curl -fsSL get.zshell.dev)" --
Passing -a loader is equivalent because the loader profile is the default.
The installer creates the loader configuration under $XDG_CONFIG_HOME/zi (defaulting to ~/.config/zi) and adds only this managed block to .zshrc:
# >>> zi setup >>>
source '/absolute/config/zi/setup.zsh'
# <<< zi setup <<<
The generated setup.zsh entrypoint owns pre-settings (setup/pre.zsh), loader/zzinit (init.zsh and zzinit), recipes (setup/shell.zsh), and diagnostics.
Then reload the shell with: exec zsh. All done!
Clone the repository into its data directory and prepare configuration files, leaving .zshrc untouched:
sh -c "$(curl -fsSL get.zshell.dev)" -- -i skip
Use this profile when you manage your dotfiles manually or integrate Zi later. The checkout is placed in $XDG_DATA_HOME/zi/bin (defaulting to ~/.local/share/zi/bin), a recognized legacy ~/.zi/bin, or an explicit ZI_HOME.
Install and configure Zi with recommended annexes:
sh -c "$(curl -fsSL get.zshell.dev)" -- -a annex
Recipe installation (z-shell/z-a-meta-plugins @annexes) is deferred to the first shell start.
Install and configure Zi with recommended annexes and setup z-shell/zunit:
sh -c "$(curl -fsSL get.zshell.dev)" -- -a zunit
Recipe installation (z-shell/z-a-meta-plugins @annexes @zunit) is deferred to the first shell start.
Let an AI coding agent install Zi through the official installer, never by editing .zshrc by hand. The zi-install skill in z-shell/.github is the machine-readable authority for this tab: agents with skill support install a reviewed commit of it with gh skill install z-shell/.github .github/skills/zi-install --pin <commit> --dir .github/skills, and every other agent gets the instruction block at the end of this tab.
The host requires zsh, git, and curl or wget. Fetch the installer to a file, verify the file, then run it. Do not use sh -c "$(curl ...)" on a user's behalf: a failed fetch inside the substitution becomes an empty script that still exits 0, and an existing installation then passes verification although nothing ran.
tmp="$(mktemp -d)" && curl -fsSL https://get.zshell.dev -o "$tmp/install.sh" && curl -fsSL https://raw.githubusercontent.com/z-shell/src/main/public/checksum.txt -o "$tmp/checksum.txt"
With wget, replace each curl -fsSL <url> -o <file> with wget -qO <file> <url>. The public/sh/install.sh line of the published checksum must equal the digest of the fetched file. The command uses sha256sum and falls back to shasum -a 256 where it is absent, as on macOS; with neither tool, or on a mismatch or a missing line, it prints nothing and the agent must stop:
expected="$(awk '$2 == "public/sh/install.sh" { print $1 }' "$tmp/checksum.txt")" && actual="$({ sha256sum "$tmp/install.sh" 2>/dev/null || shasum -a 256 "$tmp/install.sh"; } | awk '{ print $1 }')" && [ -n "$expected" ] && [ "$expected" = "$actual" ] && echo 'checksum ok'
Run only after checksum ok, selecting one of the two supported profiles. Both run without a terminal and read nothing from standard input.
Loader profile (default): installs Zi, sets up configuration files, and appends the managed block to .zshrc:
sh "$tmp/install.sh" -a loader
Install-only profile: clones Zi into its home and leaves .zshrc untouched:
sh "$tmp/install.sh" -i skip
Rules the agent must follow:
- Drive the installer with its flags (
-a loader,-i skip,-b <branch>). Do not write to .zshrc or to the Zi configuration home yourself. The installer owns the integration block, detects an existing one, and a rerun updates the checkout and appends nothing. - Respect the user's environment. The installer manages
${ZDOTDIR:-$HOME}/.zshrc. When set,ZDOTDIRandZI_HOMEmust be absolute paths (starting with/); the installer rejects relative paths before making changes.XDG_CONFIG_HOMEandXDG_DATA_HOMEmust be absolute paths; relative values fall back to specification defaults (~/.configand~/.local/share). ExplicitZI_HOMEandZI_BIN_DIR_NAMEvalues are supported and carried into configuration. - Run as the user who owns the shell. Never run the installer as root or through sudo: the checkout then lands in root's home or leaves root-owned files that the user's shell cannot update.
- Do not start an interactive shell while installing (
exec zsh,zsh -i, orzsh -l). The installer needs none, and a shell that waits for a prompt blocks the agent. - For annex and zunit profiles, recipe installation is deferred to the first shell start and executed when
setup.zshruns. - Read the result instead of assuming it. Exit 0 and the line
Successfully installed at <path>confirms success. Stop and report on these refusal messages verbatim without editing files:unrecognised Zi integration remains in .zshrc; refusing to initialise Zi twice: an unrecognised integration exists;checkout cannot be fast-forwarded; local state was left untouched: the checkout has local commits or changes;refusing symlink target <path>; apply the printed patch to its target manually:.zshrcis a symlink;managed .zshrc block changed outside Zi setup; apply the printed patch manually or restore the receipt state: the managed block was modified outside setup;-- ERROR -- ZDOTDIR must be an absolute path when set: <path>or-- ERROR -- ZI_HOME must be an absolute path when set: <path>.
Verify the loader profile in two steps; neither applies to install-only, which leaves .zshrc untouched. A fresh interactive shell proves that the user's own startup loads Zi:
zsh -ic 'zi -h' >/dev/null && echo 'zi ok'
A clean shell verifies that the generated setup.zsh entrypoint sources correctly and makes zi available:
zsh -f -c '
if [[ -n ${XDG_CONFIG_HOME:-} && $XDG_CONFIG_HOME == /* ]]; then d="$XDG_CONFIG_HOME/zi"; else d="$HOME/.config/zi"; fi
source "$d/setup.zsh" && zi -h >/dev/null && echo "setup ok"
'
Verify the install-only profile with this check only, using the checkout directory the installer printed after Successfully installed at :
zsh -f -c 'builtin source "$1" && zi -h' zsh "<printed directory>/zi.zsh" >/dev/null && echo 'zi ok'
Hand this block to an agent that cannot load the skill:
Install the Zi plugin manager for Zsh on this machine by following the zi-install skill:
https://github.com/z-shell/.github/blob/main/.github/skills/zi-install/SKILL.md
- Profile: loader ("-a loader"). Use "-i skip" instead if I asked for install-only. Add "-b <branch>" only if I named a branch.
- Fetch the installer from https://get.zshell.dev to a file, verify its sha256 against the public/sh/install.sh line of https://raw.githubusercontent.com/z-shell/src/main/public/checksum.txt, and only then run the file. Never run sh -c "$(curl ...)".
- Never write to ~/.zshrc, $ZDOTDIR/.zshrc, or the Zi configuration home yourself. The installer owns them.
- Run as my user, never as root or with sudo. Keep my ZDOTDIR, XDG_CONFIG_HOME, and XDG_DATA_HOME as they are; do not set ZI_HOME unless I asked. When set, ZDOTDIR and ZI_HOME must be absolute paths.
- Do not start an interactive shell (exec zsh, zsh -i, zsh -l) while installing.
- If the installer refuses, stop and show me its message. Do not edit files to work around it.
- When done, verify exactly as described and show me the output:
Loader: zsh -ic 'zi -h', then clean-shell source of setup.zsh.
Install-only: verify zi.zsh exists under the exact printed directory; the loader checks do not apply.
:::info Compatibility and migration
- Direct profile deprecation: The legacy direct
zi.zshprofile (-a direct) is deprecated ininstall.sh. Passing-a directemits a warning and uses the guided loader profile instead. - Automatic migration: If .zshrc contains an existing legacy direct, loader, or annex/zunit block, the installer automatically detects and migrates it to the managed
setup.zshblock without evaluating untrusted shell code. - Unrecognised integrations: If an unrecognised Zi integration remains in .zshrc, the installer safely refuses to proceed to avoid duplicate initialization.
:::
:::note Automation and TUI
For automation or terminal interfaces driving setup.sh, the additive setup.sh apply --events DIR option is optional. It creates a private new absolute directory and publishes atomic numbered zi-setup-event-v1 event directories with started and terminal state for active operations. Human stdout/stderr remains for people rather than machine decisions. Consumers must treat process completion as authoritative and tolerate a missing terminal event if a cancellation signal interrupts event publication itself; staging cleanup and exit 6 still apply.
:::
Manual Setup
Prepare
Set up the install location and create a directory:
The assignment below explicitly selects a fresh XDG-style home. It does not
migrate an existing $HOME/.zi installation. For automatic legacy detection,
use the loader above or source your existing Zi checkout without overriding
ZI[HOME_DIR].
typeset -Ag ZI
if [[ -n ${XDG_DATA_HOME:-} && $XDG_DATA_HOME == /* ]]; then
ZI[HOME_DIR]="$XDG_DATA_HOME/zi"
else
ZI[HOME_DIR]="$HOME/.local/share/zi"
fi
ZI[BIN_DIR]="${ZI[HOME_DIR]}/bin"
command mkdir -p -- "${ZI[BIN_DIR]}"
For security reasons run function compaudit to check if the completion system would use files owned by root or by the current user, or files in directories that are world or group-writable.
If failed, then set the current user as the owner of directories, then remove group/others write permissions, and clone the repository:
compaudit | xargs chown -R "$(whoami)" "${ZI[HOME_DIR]}"
compaudit | xargs chmod -R go-w "${ZI[HOME_DIR]}"
command git clone https://github.com/z-shell/zi.git "${ZI[BIN_DIR]}"
Enable
To enable Zi, source the zi.zsh from the previously set up directory placing the following snippet in the .zshrc file:
typeset -A ZI
: ${ZI[HOME_DIR]:="${XDG_DATA_HOME:-${HOME}/.local/share}/zi"}
: ${ZI[BIN_DIR]:="${ZI[HOME_DIR]}/bin"}
source "${ZI[BIN_DIR]}/zi.zsh"
Completions
Enable Zi completions by placing the following snippet in the .zshrc file:
The snippet below must be placed after after enabling Zi.
autoload -Uz _zi
(( ${+_comps} )) && _comps[zi]=_zi
Post-install
After a fresh install, it is recommended to reload the shell and recompile Zi with:
- exec zsh -il
- zi self-update
Run zi -h for available commands or explore wiki to extend, customize and create 👍 🎉.
If you have any issue or need help 🤦♂️, lets discuss it or open an issue on GitHub.
It helps us to improve and make Zi better. Don't forget to help the project: share, contribute, or translate 🌐 🥰 🤓.
Let's glue a toolchain that works for us 🚀.
Have ideas?
Suggest or request at playground
sh -c "$(curl -fsSL get.zshell.dev)" -- -a ???
Need warm-up?
Docker Alpine
docker run --rm -it ghcr.io/z-shell/zd:latest
Turbo Zi in Docker
If you create a Docker image that uses Zi, install Turbo-loaded plugins before the shell starts interactively, with the @zi-scheduler function in such a way, that it:
- Install plugins without waiting for the prompt (i.e. it's script friendly).
- Install all plugins instantly, without respecting the wait argument.
To accomplish this, use burst argument and call the @zi-scheduler function:
RUN zsh -i -c -- '@zi-scheduler burst || true'
- An example: Dockerfile
- In action: Playground
Zi Module: zpmod
The module transparently and automatically compiles sourced scripts and lists of all sourced files with the time the sourcing took in milliseconds on the left.
Available links
Installer
| Service | URL |
|---|---|
| Short URL | https://get.zshell.dev |
| GitHub RAW | https://raw.githubusercontent.com/z-shell/src/main/public/sh/install.sh |
Loader
| Service | URL |
|---|---|
| Short URL | https://init.zshell.dev |
| GitHub RAW | https://raw.githubusercontent.com/z-shell/src/main/public/zsh/init.zsh |