oh-my-zsh aliases for common pnpm commands.
- Clone the repository:
git clone --depth=1 https://github.com/ntnyq/omz-plugin-pnpm.git "${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/pnpm"- Include it in your
~/.zshrc:
plugins=(... pnpm)To install only pnpm.plugin.zsh, without cloning the repository, run:
Installation commands and update behavior
(
set -e
installer=$(mktemp "${TMPDIR:-/tmp}/omz-plugin-pnpm.XXXXXXXX")
trap 'rm -f -- "$installer"' 0
trap 'exit 1' HUP INT TERM
curl -fsSL --connect-timeout 10 --max-time 60 --output "$installer" \
https://raw.githubusercontent.com/ntnyq/omz-plugin-pnpm/main/install.sh
sh "$installer"
)The script requires curl and Zsh. It installs into
${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/pnpm, so you can enable it with
plugins=(... pnpm) in ~/.zshrc, as above. It does not edit your shell configuration.
You can also specify a directory:
(
set -e
installer=$(mktemp "${TMPDIR:-/tmp}/omz-plugin-pnpm.XXXXXXXX")
trap 'rm -f -- "$installer"' 0
trap 'exit 1' HUP INT TERM
curl -fsSL --connect-timeout 10 --max-time 60 --output "$installer" \
https://raw.githubusercontent.com/ntnyq/omz-plugin-pnpm/main/install.sh
sh "$installer" "$HOME/.local/share/zsh/plugins/pnpm"
)For that custom location, add this line to ~/.zshrc:
source "$HOME/.local/share/zsh/plugins/pnpm/pnpm.plugin.zsh"Run the same installation command again to update to the latest main version.
The commands run the installer only after its download succeeds. Each download
has a 10-second connection timeout and a 60-second total time limit. The script
checks the download's Zsh syntax before replacing the plugin; a failed or
interrupted download leaves the existing file intact and removes temporary files.
Git installations should use git pull.
Only the plugin file is installed; tests, CI configuration, and Git history are omitted.
Add this line to your ~/.zshrc:
zinit light ntnyq/omz-plugin-pnpmFor a single-file installation, use this instead:
zinit snippet https://raw.githubusercontent.com/ntnyq/omz-plugin-pnpm/main/pnpm.plugin.zshZinit caches the snippet locally. Run zinit update --all to update it alongside
your other plugins and snippets. See the Zinit snippet documentation.
PRs are always welcome!
This feature is copied from omz-plugin-yarn
On macOS and other Unix systems, the plugin configures PNPM_HOME and adds
pnpm's executable directories to $PATH without invoking pnpm at shell startup.
PNPM_HOME defaults and PATH behavior
A nonempty PNPM_HOME is preserved. Otherwise, the plugin uses pnpm's default
data directory, in this order:
$XDG_DATA_HOME/pnpm, whenXDG_DATA_HOMEis set.$HOME/Library/pnpmon macOS.$HOME/.local/share/pnpmon other Unix systems.
Both $PNPM_HOME/bin (pnpm 11/12) and $PNPM_HOME (pnpm 10) are added when
missing from $PATH. Existing PATH entries retain their order. Directories
need not exist yet, so installing pnpm or switching between these layouts
does not require reloading the plugin. The plugin does not create directories.
PNPM_HOME and additional bin paths must be absolute paths without :.
An existing readonly PNPM_HOME is supported. If its value is empty, environment
and PATH initialization is skipped and aliases are still loaded.
Paths containing symbolic links followed by .. retain their filesystem
meaning. The plugin also adds the lexically normalized paths used by pnpm 10/11;
duplicate entries are skipped, and existing PATH entries keep their priority.
Custom global bin directory and disabling initialization
If pnpm uses a custom global-bin-dir / globalBinDir, configure the same
directory separately, before loading this plugin:
zstyle ':omz:plugins:pnpm' global-bin-dir "$HOME/.local/bin"This style adds a directory to PATH. It does not configure pnpm itself and
does not change PNPM_HOME. The plugin does not read pnpm configuration files
or try to infer a home directory from a global bin directory.
To disable all environment and PATH initialization, set this style before loading the plugin:
zstyle ':omz:plugins:pnpm' global-path noUpgrading, preserving global packages, and PATH priority
If an older plugin version placed packages under an unintended PNPM_HOME,
set the desired data root explicitly before loading the plugin. This change
does not move existing packages or guess which historical directory to use.
Before upgrading, record these values and the names of your global packages in a shell where the old plugin is still loaded:
print -r -- "$PNPM_HOME"
pnpm root -g
pnpm store path
pnpm list -g --depth 0To keep using those packages with the same pnpm version, add
export PNPM_HOME="/your/recorded/old/home" before loading the plugin, and keep
any custom global bin configuration and matching zstyle. To use a different
data root, set it explicitly and reinstall the required global packages there.
A changed list -g result does not mean the old packages were deleted.
Changing pnpm's major version can also change its global package layout.
If both layouts contain an executable with the same name, normal PATH order
decides which executable runs. Newly added paths prefer the bin subdirectory;
existing entries retain their priority. This is layout compatibility, not an
automatic global-package migration or a package-manager version switcher.
If you want the new layout to take priority, explicitly put it first after
loading the plugin with path=("$PNPM_HOME/bin" "${path[@]}").
| Alias | Command | Description |
|---|---|---|
| p | pnpm |
The pnpm command |
| pex | pnpm exec |
Execute a shell command in scope of a project |
| pdx | pnpm dlx |
Fetch a package without installing, hotload and run it's command |
| pa | pnpm add |
Install a package in dependencies (package.json) |
| pad | pnpm add --save-dev |
Install a package in devDependencies (package.json) |
| prm | pnpm remove |
Remove installed packages |
| pls | pnpm list |
List installed packages |
| pap | pnpm add --save-peer |
Install a package in peerDependencies (package.json) |
| pga | pnpm add --global |
Install packages globally on your operating system |
| pgls | pnpm list --global |
List global installed packages |
| pgrm | pnpm remove --global |
Remove global installed packages from your OS |
| pgu | pnpm update --global |
Upgrade packages installed globally to their latest version |
| pi | pnpm init |
Interactively creates or updates a package.json file |
| pin | pnpm install |
Install dependencies defined in package.json |
| pinf | pnpm install --frozen-lockfile |
Install dependencies defined in package.json without touching lockfile |
| pr | pnpm run |
Run a defined package script |
| prun | pnpm run |
Run a defined package script |
| pst | pnpm start |
Run the start script defined in package.json |
| pln | pnpm run lint |
Run the lint script defined in package.json |
| pdocs | pnpm run docs |
Run the docs script defined in package.json |
| pfmt | pnpm run format |
Run the format script defined in package.json |
| pb | pnpm run build |
Run the build script defined in package.json |
| pd | pnpm run dev |
Run the dev script defined in package.json |
| psv | pnpm run serve |
Run the serve script defined in package.json |
| pt | pnpm test |
Run the test script defined in package.json |
| ptc | pnpm test --coverage |
Run the test script defined in package.json with coverage |
| pu | pnpm update |
Update packages to their latest version based on the specified range |
| pui | pnpm update --interactive |
Prompt for which outdated packages to their latest version based on the specified range |
| puil | pnpm update --interactive --latest |
Prompt for which outdated packages to upgrade to the latest available version |
| pc | pnpm create |
Create a project from a create-* start kit |
| ppub | pnpm publish |
Publish a package to the registry |
| pab | pnpm approve-builds |
Approve dependencies for running scripts during installation |
| pf | pnpm -r --filter |
Use filter in monorepo root directory |
Test commands, coverage, and CI
Run the shell and installer regression tests with Zsh; no Node.js or pnpm installation is needed. Installer tests use a local download stub:
zsh -f tests/global-path.zsh
zsh -f tests/install.zshRun the integration tests with Node.js 24 and an installed pnpm 10, 11, or 12 CLI:
zsh -f tests/integration.zsh "$(command -v pnpm)"Each case runs in a clean zsh -f process with a temporary HOME, PATH, and pnpm
configuration. Integration tests install and execute a dependency-free local
package offline. pnpm 12.0.0 rejects local tarballs in its global installer, so
that version checks CLI paths and executes a probe placed in the returned bin
directory instead. The tests do not run pnpm setup or use your global packages.
Temporary files are removed after the tests finish.
Regression cases also cover readonly homes with ERR_EXIT, symbolic links
followed by .., links created or retargeted after startup, and command priority
when the old home is already on PATH. The pnpm 12.4.2 symlink-home case checks
CLI paths and command lookup only: its installer misresolves local tarball
references with that home path. Other supported cases test actual bin linking.
GitHub Actions runs all suites on Linux and macOS, using Node.js 24 with pnpm pinned to 10.0.0, 11.0.0, 11.26.0, 12.0.0, and 12.4.2. CI downloads its tools outside the repository; the plugin has no additional runtime dependencies.
Release history
- Fix
PNPM_HOMEinitialization after #18: preserve an existing home while repairing PATH, handle empty values, and respect XDG and platform defaults. - Support pnpm 10 and pnpm 11/12 executable layouts without invoking pnpm at shell startup or deriving its home from a bin directory.
- Add the
global-bin-dirzstyle for explicitly configured global executable directories. - Add a lightweight single-file installer with safe updates and document Zinit snippet installation.
- Add isolated shell, installer, and real pnpm regression tests, plus Linux and macOS CI.
- New aliases
pabforpnpm approve-builds
- New aliases
pinfforpnpm install --frozen-lockfile
- Features
- Set
PNPM_HOMEenvironment variable to global bin dir
- Set
- New aliases
puiforpnpm update --interactive
- New aliases
pfmtforpnpm run format
- Features
- Add pnpm global scripts dir to
$PATH
- Add pnpm global scripts dir to
- New aliases
prforpnpm run
- New aliases
pfforpnpm -r --filter
- Removed aliases
punforpnpm uninstall. Useprminstead.pxforpnpx. It's deprecated. Usepexandpdxinstead.puiforpnpm update --interactive. Usepuandpuilinstead.pdocforpnpm run doc. Maybe rename your scripts todocsand usepdocsinstead.psvforpnpm server.phforpnpm help.poutforpnpm outdated.pauforpnpm audit.pwhyforpnpm why.
- Changed aliases
pupforpnpm updatehas been renamed topu.psforpnpm run servehas been renamed topsv. See issue #6
- New aliases
pexforpnpm exec.pdxforpnpm dlx.