Docs: init.sh nvm example only solves PATH, not shell function availability in hook subprocesses
Problem
The nvm how-to docs recommend placing nvm initialisation in ~/.config/husky/init.sh to fix nvm: command not found. The example given:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"This only partially solves the problem. It fixes the PATH issue for GUI apps (VS Code, Tower, etc.) that launch hooks with a minimal environment. However, it does not make the nvm shell function available inside hook scripts.
Why
Looking at the husky shell wrapper (node_modules/husky/husky):
i="${XDG_CONFIG_HOME:-$HOME/.config}/husky/init.sh"
[ -f "$i" ] && . "$i" # nvm function defined HERE in this shell
sh -e "$s" "$@" # hook runs in a NEW subprocessinit.sh is sourced in the husky wrapper process. The hook script is then executed via sh -e, which spawns a subprocess. Environment variables (like PATH) are inherited by subprocesses — which is why the PATH fix works. Shell functions are not inherited, so the nvm function is unavailable inside the hook even after init.sh runs correctly.
This can be confirmed: after following the docs, the PATH in the hook error output will already contain the nvm node directory (proving init.sh ran and set PATH), yet nvm: command not found still occurs if the hook calls nvm directly.
Workaround
Source nvm directly inside the hook file:
export NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" && nvm install && nvm use
pnpm installThis works for both GUI apps (no PATH issue) and terminal users (nvm function available). The init.sh approach is not needed alongside this.
An alternative that avoids touching hook files is to put nvm use in init.sh itself (after sourcing nvm.sh), since the function IS available there. This sets PATH correctly before the subprocess starts, so the hook gets the right node without needing to call nvm directly. But this approach is not obvious from the docs.
Suggestion
The docs should clarify:
- What init.sh actually solves (PATH inheritance for GUI apps)
- That calling
nvmdirectly from within a hook requires sourcing nvm.sh inside the hook itself, or runningnvm usefrom init.sh before the subprocess starts - The distinction between environment variables (inherited by subprocesses) and shell functions (not inherited)
Related closed issue with the same root cause but no docs fix: #1579
Source: typicode/husky