nvm: Fix "command not found" in CI Shells
nvm is defined as a shell function by nvm.sh, so it lives in no binary on PATH; CI shells must source nvm.sh before any nvm call.
The single most common nvm-in-CI failure is "command not found", and it is never a broken install. It is that the job shell never ran the init script that defines the function.
What it does
The nvm installer appends export NVM_DIR=...; [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" to your ~/.bashrc or ~/.bash_profile. Interactive login shells read those files; the bare bash shells CI uses for each step do not, so the function is undefined.
Common usage
- name: Use nvm
shell: bash
run: |
export NVM_DIR="$HOME/.nvm"
. "$NVM_DIR/nvm.sh"
nvm install 20
nvm use 20
node -v
# alternative: a login shell that sources the profile itself
- run: nvm use 20 && node -v
shell: bash -l {0}Options
| Approach | What it does |
|---|---|
| . "$NVM_DIR/nvm.sh" | Source the function definition in this step |
| shell: bash -l {0} | Run a login shell so it reads ~/.bash_profile |
| nvm.sh --no-use | Source nvm without selecting a version (faster) |
| $NVM_DIR/nvm-exec | A wrapper script that loads nvm then runs a command |
In CI
Each GitHub Actions run: block is a separate shell, so sourcing in one step does not carry to the next. Either source nvm.sh in every step, or prefer the actions/setup-node action when you do not specifically need nvm. Sourcing must happen before the first nvm call in each step.
Common errors in CI
"nvm: command not found": source nvm.sh first. "/usr/bin/env: bash: No such file" when using bash -l {0} on an image without a login profile means there is no profile to load; fall back to explicit sourcing. If nvm use runs but node -v is wrong in a later step, remember PATH changes do not persist across steps.