Sep 24, 20253 min readEnglish
Patching Packages With PNPM: A Practical Guide
A practical guide to patching third-party packages locally without maintaining a fork or waiting for an upstream release.
When working with third-party packages, you’ll sometimes find yourself wanting to tweak their behavior; maybe to fix a bug, apply a quick security patch, or test a feature before it gets merged upstream. Normally, you’d fork the repo, publish your own version, and install that. But there’s a more elegant way: patching packages locally with pnpm.
In this post, we’ll walk through why this is important and how to do it effectively.
Why Patch a Package?
- Urgent Fixes Imagine you’ve hit a bug that blocks development. The maintainers already have a fix pending, but you can’t wait for the next release. Patching lets you apply the fix instantly and keep moving.
- Security UpdatesSecurity vulnerabilities can’t wait. If a dependency has a known vulnerability and the fix isn’t published yet, you can apply the patch yourself while waiting for the official release.
- Experimentation Maybe you want to try an alternative implementation or tweak the behavior of a function. Patching lets you validate your idea quickly without committing to a permanent fork.
- Better Developer ExperienceWith pnpm’s patching system, your changes live neatly in a patches/ folder. There’s no need to juggle forks or maintain extra GitHub repos.
How pnpm Patching Works
pnpm offers two key commands:
pnpm patch <package> Opens up the package in a temporary directory where you can edit files.
pnpm patch-commit <package> Finalizes your changes into a .patch file stored in your project’s patches/ directory.
These patches are automatically applied every time you install dependencies.
Step-by-Step Example
Let’s say you’re using the popular date utility library date-fns, and you notice that a function isn’t behaving quite as expected. For example, maybe formatDistanceStrict doesn’t handle rounding the way you need.
1. Start a Patch
pnpm patch date-fnsWhen you run this, pnpm will tell you where the editable package lives. This is helpful because node_modules is huge, and it can be hard to find the file manually. Example output:
Patch: You can now edit the package at: /Users/mithatakbulut/Desktop/cresta/node_modules/.pnpm_patches/date-fns@4.1.0To commit your changes, run: pnpm patch-commit '/Users/mithatakbulut/Desktop/cresta/node_modules/.pnpm_patches/date-fns@4.1.0'This is the directory where you’ll make your edits.
2. Make Your Edits
Navigate to the relevant file (formatDistanceStrict.js) and adjust the default value of the rounding method:
// Original lineconst roundingMethod = getRoundingMethod(options?.roundingMethod ?? "round");// Patched line: default to "ceil"const roundingMethod = getRoundingMethod(options?.roundingMethod ?? "ceil");This change ensures that, unless specified otherwise, all rounding is always upwards.
3. Commit the Patch
After saving your edits, run:
pnpm patch-commit date-fnsThis generates a file like patches/date-fns.patch.
4. Verify in package.json
Your package.json will now include:
"pnpm": { "patchedDependencies": { "date-fns": "patches/date-fns.patch" }}5. Restart Your Dev Server
pnpm devYour patched version is now active.
Why This Approach Rocks
- Reproducibility: Every teammate and CI run applies the same patch automatically.
- Transparency: The patches/ folder makes it clear what changes were made to third-party code.
- Maintainability: You can drop the patch as soon as the official package is updated.
- Simplicity: No forks, no custom registries. There is just one command to patch, one to commit.
When Not to Patch
- Major Features: If you’re adding significant features or custom business logic, maintaining a fork is cleaner.
- Long-Term Maintenance: Patches are best for short-term fixes. For permanent changes, push upstream or fork.
Patching with pnpm is an incredibly useful tool in a developer’s toolkit. It bridges the gap between waiting on upstream changes and maintaining your own forks. Whether you’re fixing a bug, securing your app, or testing a tweak, it empowers you to move fast without compromising reproducibility.
The next time you hit a bug in a dependency, don’t stall your progress; patch it and keep shipping. 🚀
Originally published on Medium.
View on Medium