diff --git a/plugins/pnpm/README.md b/plugins/pnpm/README.md
new file mode 100644
index 000000000..6f8df38d5
--- /dev/null
+++ b/plugins/pnpm/README.md
@@ -0,0 +1,48 @@
+# pnpm plugin
+
+The pnpm plugin provides completion as well as adding many useful aliases.
+
+To use it, add pnpm to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... pnpm)
+```
+
+## Aliases
+
+| Alias    | Command                      | Description                                                     |
+| :------- | :--------------------------- | :-------------------------------------------------------------- |
+| `pnpmg`  | `pnpm add -g`                | Install dependencies globally                                   |
+| `pnpmS`  | `pnpm add -S`                | Install and save to dependencies in your package.json           |
+| `pnpmD`  | `pnpm add -D`                | Install and save to dev-dependencies in your package.json       |
+| `pnpmF`  | `pnpm add -f`                | Force install from remote registries ignoring local cache       |
+| `pnpmE`  | `PATH="$(pnpm bin)":"$PATH"` | Run command from node_modules folder based on current directory |
+| `pnpmO`  | `pnpm outdated`              | Check which pnpm modules are outdated                           |
+| `pnpmU`  | `pnpm update`                | Update all the packages listed to the latest version            |
+| `pnpmV`  | `pnpm -v`                    | Check package versions                                          |
+| `pnpmL`  | `pnpm list`                  | List installed packages                                         |
+| `pnpmL0` | `pnpm ls --depth=0`          | List top-level installed packages                               |
+| `pnpmst` | `pnpm start`                 | Run pnpm start                                                  |
+| `pnpmt`  | `pnpm test`                  | Run pnpm test                                                   |
+| `pnpmR`  | `pnpm run`                   | Run pnpm scripts                                                |
+| `pnpmP`  | `pnpm publish`               | Run pnpm publish                                                |
+| `pnpmI`  | `pnpm init`                  | Run pnpm init                                                   |
+| `pnpmi`  | `pnpm info`                  | Run pnpm info                                                   |
+| `pnpmSe` | `pnpm search`                | Run pnpm search                                                 |
+| `pnpmrd` | `pnpm run dev`               | Run pnpm run dev                                                |
+| `pnpmrb` | `pnpm run build`             | Run pnpm run build                                              |
+
+## `pnpm install` / `pnpm uninstall` toggle
+
+The plugin adds a function that toggles between `pnpm install` and `pnpm uninstall` in the current command or
+the last command, for up to 2 previous commands. **The default key binding is pressing <kbd>F2</kbd> twice**.
+
+You can change this key binding by adding the following line to your zshrc file:
+
+```zsh
+bindkey -M emacs '<seq>' pnpm_toggle_install_uninstall
+bindkey -M vicmd '<seq>' pnpm_toggle_install_uninstall
+bindkey -M viins '<seq>' pnpm_toggle_install_uninstall
+```
+
+where `<seq>` is a key sequence obtained by running `cat` and pressing the keyboard sequence you want.
diff --git a/plugins/pnpm/pnpm.plugin.zsh b/plugins/pnpm/pnpm.plugin.zsh
new file mode 100644
index 000000000..fd775e00b
--- /dev/null
+++ b/plugins/pnpm/pnpm.plugin.zsh
@@ -0,0 +1,123 @@
+(( $+commands[pnpm] )) && {
+  command rm -f "${ZSH_CACHE_DIR:-$ZSH/cache}/pnpm_completion"
+
+  _pnpm_completion() {
+    local si=$IFS
+    compadd -- $(COMP_CWORD=$((CURRENT-1)) \
+                 COMP_LINE=$BUFFER \
+                 COMP_POINT=0 \
+                 pnpm completion -- "${words[@]}" \
+                 2>/dev/null)
+    IFS=$si
+  }
+  compdef _pnpm_completion pnpm
+}
+
+# Install dependencies globally
+alias pnpmg="pnpm add -g "
+
+# pnpm package names are lowercase
+# Thus, we've used camelCase for the following aliases:
+
+# Install and save to dependencies in your package.json
+alias pnpmS="pnpm add -S "
+
+# Install and save to dev-dependencies in your package.json
+alias pnpmD="pnpm add -D "
+
+# Force pnpm to fetch remote resources even if a local copy exists on disk.
+alias pnpmF='pnpm add -f'
+
+# Execute command from node_modules folder based on current directory
+# i.e pnpmE gulp
+alias pnpmE='PATH="$(pnpm bin)":"$PATH"'
+
+# Check which pnpm modules are outdated
+alias pnpmO="pnpm outdated"
+
+# Update all the packages listed to the latest version
+alias pnpmU="pnpm update"
+
+# Check package versions
+alias pnpmV="pnpm -v"
+
+# List packages
+alias pnpmL="pnpm list"
+
+# List top-level installed packages
+alias pnpmL0="pnpm ls --depth=0"
+
+# Run pnpm start
+alias pnpmst="pnpm start"
+
+# Run pnpm test
+alias pnpmt="pnpm test"
+
+# Run pnpm scripts
+alias pnpmR="pnpm run"
+
+# Run pnpm publish
+alias pnpmP="pnpm publish"
+
+# Run pnpm init
+alias pnpmI="pnpm init"
+
+# Run pnpm info
+alias pnpmi="pnpm info"
+
+# Run pnpm search
+alias pnpmSe="pnpm search"
+
+# Run pnpm run dev
+alias pnpmrd="pnpm run dev"
+
+# Run pnpm run build
+alias pnpmrb="pnpm run build"
+
+pnpm_toggle_install_uninstall() {
+  # Look up to the previous 2 history commands
+  local line
+  for line in "$BUFFER" \
+    "${history[$((HISTCMD-1))]}" \
+    "${history[$((HISTCMD-2))]}"
+  do
+    case "$line" in
+      "pnpm uninstall"*)
+        BUFFER="${line/pnpm uninstall/pnpm install}"
+        (( CURSOR = CURSOR + 2 )) # uninstall -> install: 2 chars removed
+        ;;
+      "pnpm install"*)
+        BUFFER="${line/pnpm install/pnpm uninstall}"
+        (( CURSOR = CURSOR + 2 )) # install -> uninstall: 2 chars added
+        ;;
+      "pnpm remove"*)
+        BUFFER="${line/pnpm remove/pnpm add}"
+        (( CURSOR = CURSOR + 5 )) # remove -> add: 5 chars removed
+        ;;
+      "pnpm add"*)
+        BUFFER="${line/pnpm add/pnpm remove}"
+        (( CURSOR = CURSOR + 2 )) # add -> remove: 2 chars added
+        ;;
+      "pnpm un "*)
+        BUFFER="${line/pnpm un/pnpm add}"
+        (( CURSOR = CURSOR + 5 )) # un -> add: 5 chars added
+        ;;
+      "pnpm i "*)
+        BUFFER="${line/pnpm i/pnpm remove}"
+        (( CURSOR = CURSOR + 8 )) # i -> remove: 8 chars added
+        ;;
+      *) continue ;;
+    esac
+    return 0
+  done
+
+  BUFFER="pnpm install"
+  CURSOR=${#BUFFER}
+}
+
+zle -N pnpm_toggle_install_uninstall
+
+# Defined shortcut keys: [F2] [F2]
+bindkey -M emacs '^[OQ^[OQ' pnpm_toggle_install_uninstall
+bindkey -M vicmd '^[OQ^[OQ' pnpm_toggle_install_uninstall
+bindkey -M viins '^[OQ^[OQ' pnpm_toggle_install_uninstall