Aliases that work in one Zsh terminal but disappear in another usually point to startup-file placement, not the alias itself. Zsh startup files decide which settings load for login shells, interactive terminals, and every shell process.

Zsh reads ~/.zshenv for every shell, ~/.zprofile for login shells before interactive setup, ~/.zshrc for interactive shells, and ~/.zlogin for login-shell commands that run after ~/.zshrc. Most prompt, alias, option, completion, and terminal behavior belongs in ~/.zshrc, while login-session environment setup belongs in ~/.zprofile.

When ZDOTDIR is set, Zsh reads the same per-user filenames from that directory instead of the home directory. Keep ~/.zshenv quiet and small so scripts and noninteractive shell commands do not inherit extra startup cost or unexpected output. Fresh zsh processes make the file split visible without depending on the current terminal session.

Steps to configure Zsh startup files:

  1. Check the startup-file directory for the account.
    $ zsh -ic 'print -r -- "${ZDOTDIR:-$HOME}"'
    /home/operator

    If this command prints a path other than the home directory, edit $ZDOTDIR/.zprofile and $ZDOTDIR/.zshrc instead of the files under ~.

  2. Back up an existing login startup file.
    $ cp -p ~/.zprofile ~/.zprofile.bak

    Skip this command if ~/.zprofile does not exist yet. Use the matching file under $ZDOTDIR when the startup-file directory check showed a custom path.

  3. Back up an existing interactive startup file.
    $ cp -p ~/.zshrc ~/.zshrc.bak

    Skip this command if ~/.zshrc does not exist yet. Use the matching file under $ZDOTDIR when the startup-file directory check showed a custom path.

  4. Add login-shell environment setup to ~/.zprofile.
    ~/.zprofile
    # Login shells only
    export PROJECT_ROOT="$HOME/projects"

    Use ~/.zprofile for login-session values that should be available before interactive shell setup runs. Keep interactive aliases and prompt code out of this file.

  5. Add interactive terminal settings to ~/.zshrc.
    ~/.zshrc
    # Interactive shells
    alias ll='ls -lah'
    export ZSH_INTERACTIVE_READY=1

    Use ~/.zshrc for aliases, prompt settings, completion setup, shell options, and functions that only make sense in an interactive terminal.

  6. Check the login startup file for syntax errors.
    $ zsh -n ~/.zprofile

    No output from zsh -n means Zsh parsed the file without finding a syntax error.

  7. Check the interactive startup file for syntax errors.
    $ zsh -n ~/.zshrc

    No output from zsh -n means Zsh parsed the file without finding a syntax error.

  8. Start a login interactive shell and verify that both login and interactive settings loaded.
    $ zsh -lic 'typeset -p PROJECT_ROOT ZSH_INTERACTIVE_READY'
    export PROJECT_ROOT=/home/operator/projects
    export ZSH_INTERACTIVE_READY=1
  9. Start a non-login interactive shell and verify that ~/.zshrc still loads by itself.
    $ zsh -ic 'typeset -p ZSH_INTERACTIVE_READY'
    export ZSH_INTERACTIVE_READY=1
  10. Check that the login-only value does not come from a clean non-login shell.
    $ env -u PROJECT_ROOT zsh -ic 'print -r -- "PROJECT_ROOT=${PROJECT_ROOT:-unset}"'
    PROJECT_ROOT=unset

    If PROJECT_ROOT appears in the non-login check, it may already be exported by the parent environment, ~/.zshenv, or another startup file.