When Urgent Fixes Can’t Wait: How to Patch Packages in Production

There’s a special kind of panic that hits developers right before a big release.
You’ve checked everything, your tests are passing, the staging environment is stable, and the business team is counting on you to go live today. Then, at the last minute, you discover something you didn’t expect: a bug, a missing feature, or an unexpected behaviour inside a third-party npm package you rely on.

If you’ve been building with open source tools for a while, you know this scenario too well.
One small line of code buried deep inside someone else’s package — can block your entire release.

The Usual Solutions — And Why They Fall Short

When this happens, your first instinct is to do the right thing. Maybe you find the issue on GitHub and see that other people have run into it too. So you do the responsible thing — fork the repository, make a pull request, and wait for the maintainers to merge it.

But reality hits hard. Maybe the maintainer is on vacation. Maybe your PR sits in review for days. Maybe it never gets merged at all. Meanwhile, your team is stuck because your app can’t ship with this blocker in place.

So you consider the next logical option: forking the entire package under your own organisation. This works technically but it means you’re now responsible for maintaining and syncing your fork with the original. That’s a burden for one tiny fix. Worse, the next update of the package might conflict with your fork, forcing you into extra merge work every time.

Or maybe you search for a replacement library altogether. Sometimes this works too if there’s a well-maintained alternative. But switching a dependency last minute is risky. APIs change. Edge cases break. Suddenly you’re swapping one uncertainty for another.

The Need for a Practical, Safe Shortcut

Sometimes, you don’t have time for a perfect fix.
You just need a safe, traceable way to patch the dependency, unblock your release, and get back to building features that actually matter to your users.

That’s where patch-package comes in.
It’s a tiny tool with a big impact and if you’ve never used it, you’re about to discover a simple trick that can save you hours of headaches.

What is patch-package?

patch-package does exactly what its name promises: it lets you patch an npm package, keep that patch in your version control, and ensure it gets reapplied every time someone installs dependencies.

In short, instead of waiting for an upstream fix or managing a fork, you change the library code inside node_modules directly, then tell patch-package to generate a diff file for you. That diff lives in your repository, so your team always gets the fix too. The postinstall script runs after every npm install and reapplies your patch automatically.

No manual re-edits. No accidental overwrites when someone deletes node_modules.
Just a simple, versioned patch that lives alongside your code.

In this guide, I’ll walk you through it step by step, using a simple example with the popular date-fns library.

The goal here is not to fix a real bug in date-fns, but to demonstrate how you can safely patch any npm library when you face a real bug or urgent change in your own projects. That’s why this example uses a simple functional tweak so you can focus on learning the process you’ll use for real fixes when it matters.

Lets get stated

1️⃣ Install patch-package

Start by adding patch-package to your project as a dev dependency:

npm install patch-package --save-dev

Add a postinstall script in your package.json so that your patches are automatically re-applied every time someone installs dependencies:

"scripts": {
// keep existing scripts as it is.
"postinstall": "patch-package"
}

2️⃣ Run Install Once — Check That No Patch Exists

Run your normal install once:

npm install

You’ll notice there’s no patches/ folder yet, that’s expected.
You haven’t made or saved any patch yet.

3️⃣ Find the Code to Patch

For this demo, suppose your team needs to tweak the lastDayOfYear function in date-fns.

Navigate to the file:

node_modules/date-fns/lastDayOfYear.js

4️⃣ Apply the Change

Open that file.
Suppose the original function looks like this:

export function lastDayOfYear(date, options) {
const date_ = toDate(date, options?.in);
const year = date_.getFullYear();
date_.setFullYear(year + 1, 0, 0);
date_.setHours(0, 0, 0, 0);
return date_;
}

For this demo, you’ll add a simple custom tweak adding a console log and an early return if the input is a number:

export function lastDayOfYear(date, options) {
/**
* Custom error handling for invalid date input
*/
if (typeof date === "number") {
console.log(`Custom error handling ${date}`);
// Consider: We want undefined instead of default behaviour i.e. "Invalid Date"
return;
}

const date_ = toDate(date, options?.in);
const year = date_.getFullYear();
date_.setFullYear(year + 1, 0, 0);
date_.setHours(0, 0, 0, 0);
return date_;
}

5️⃣ Verify the Local Fix Works

Run your project and test the updated function.
Confirm that when you pass a number, it logs the message and returns undefined exactly as you mocked it to do.

  const result: Date | undefined = lastDayOfYear(5);
console.log(result);

6️⃣ Why You Need to Create the Patch and How

At this point, you’ve made a local change directly inside your node_modules folder.
This works for your machine right now, but there’s a catch:

Every time you (or anyone else) runs npm install or yarn install, your node_modules folder is re-created from scratch based on your package.json and package-lock.json.
When that happens, your manual changes inside node_modules will be wiped out — and you’ll lose your fix.

Also, if you push this code to your repository, your teammates or your CI/CD pipeline won’t see your local edit — because node_modules is not version-controlled.

This is exactly where patch-package shines:
It takes your local edits and generates a .patch file that records exactly what changed inside the package.
This .patch file is saved inside your project and committed to your version control — so your whole team, your build servers, and any future installs always apply your fix automatically.

To create that patch file, run:

npx patch-package date-fns

Note: Replace date-fns with the library name you are applying the fix for. In this case it is date-fns.

This will create a patches/ folder in your project with a new file like

patches/
└── date-fns+3.6.0.patch

This patch file safely stores the difference between the original library code and your custom change — so you never have to manually edit node_modules again!!!

7️⃣ Commit the Patch

git add patches/
git commit -m "patch-package"

Your Fix Is Now Safe and Shared

Now, whenever someone runs npm install, your postinstall script will run patch-package which automatically reapplies your patch to the library, every single time.

No more forgotten local hacks.
No more “why did this break again?” moments.

And when the upstream library eventually releases a proper fix, you can just remove the patch and move on.

Best Practices for Using patch-package

Keep patches small and focused. They’re easier to maintain and less likely to conflict when the dependency updates.

Open an upstream PR anyway. Share your fix so everyone benefits once merged, you can remove your patch.

Document your patches. A short comment in your README or commit message will help future you and your teammates understand why it exists.

Check your patches on upgrades. If the package updates, your patch might fail to apply patch-package will tell you if it does.

Wrapping Up

When you work with open source libraries, urgent bugs can and do appear at the worst times. patch-package is the safety net that keeps you moving forward without reckless local hacks or maintaining a full fork for one line of code.

So next time you hit that last-minute dependency blocker before release, remember:
Patch it. Commit it. Ship it.

Have you used patch-package before?
Share your own tips, pitfalls, or stories below and help other developers keep their releases smooth, even when upstream fixes are out of reach.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.