← Stories

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?

  1. 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.
  2. 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.
  3. 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.
  4. 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-fns

When 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-fns

This 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 dev

Your 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