pnpm Patches
pnpm's patching feature lets you modify third-party packages directly. Useful for applying fixes before upstream releases or customizing package behavior.
Creating a Patch
Step 1: Initialize Patch
pnpm patch <pkg>@<version>
# Example
pnpm patch [email protected]This creates a temporary directory with the package source and outputs the path:
You can now edit the following folder: /tmp/abc123...Step 2: Edit Files
Navigate to the temporary directory and make your changes:
cd /tmp/abc123...
# Edit files as neededStep 3: Commit Patch
pnpm patch-commit <path-from-step-1>
# Example
pnpm patch-commit /tmp/abc123...This creates a .patch file in patches/ and updates package.json:
patches/
└── [email protected]{
"pnpm": {
"patchedDependencies": {
"[email protected]": "patches/[email protected]"
}
}
}Patch File Format
Patches use standard unified diff format:
diff --git a/lib/router/index.js b/lib/router/index.js
index abc123..def456 100644
--- a/lib/router/index.js
+++ b/lib/router/index.js
@@ -100,6 +100,7 @@ function createRouter() {
// Original code
- const timeout = 30000;
+ const timeout = 60000; // Extended timeout
return router;
}Managing Patches
List Patched Packages
pnpm list --depth=0
# Shows (patched) marker for patched packagesUpdate a Patch
# Edit existing patch
pnpm patch [email protected]
# After editing
pnpm patch-commit <path>Remove a Patch
pnpm patch-remove <pkg>@<version>
# Example
pnpm patch-remove [email protected]Or manually:
- Delete the patch file from
patches/ - Remove entry from
patchedDependenciesinpackage.json - Run
pnpm install
Patch Configuration
Custom Patches Directory
{
"pnpm": {
"patchedDependencies": {
"[email protected]": "custom-patches/my-express-fix.patch"
}
}
}Multiple Packages
{
"pnpm": {
"patchedDependencies": {
"[email protected]": "patches/[email protected]",
"[email protected]": "patches/[email protected]",
"@types/[email protected]": "patches/@[email protected]"
}
}
}Workspaces
Patches are shared across the workspace. Define in the root package.json:
// Root package.json
{
"pnpm": {
"patchedDependencies": {
"[email protected]": "patches/[email protected]"
}
}
}All workspace packages using [email protected] will have the patch applied.
Best Practices
- Version specificity: Patches are tied to exact versions. Update patches when upgrading dependencies.
- Document patches: Add comments explaining why the patch exists:
# In patches/README.md
## [email protected]
Fixes timeout issue. PR pending: https://github.com/expressjs/express/pull/1234- Minimize patches: Keep patches small and focused. Large patches are hard to maintain.
- Track upstream: Note upstream issues/PRs so you can remove patches when fixed.
- Test patches: Ensure patched code works correctly in your use case.
Troubleshooting
Patch fails to apply
ERR_PNPM_PATCH_FAILED Cannot apply patchThe package version changed. Recreate the patch:
pnpm patch-remove [email protected]
pnpm patch [email protected]
# Reapply changes
pnpm patch-commit <path>Patch not applied
Ensure:
- Version in
patchedDependenciesmatches installed version exactly - Run
pnpm installafter adding patch configuration
<!-- Source references:
- https://pnpm.io/cli/patch
- https://pnpm.io/cli/patch-commit
- https://pnpm.io/package_json#pnpmpatcheddependencies
-->