Patch an NPM dependency with yarn

Alexandru Bereghici

Alexandru Bereghici / May 26, 2022

3 min read50 views

A bug

When you have a bug in a third party dependency, usually you have a limited set of options to fix it.

You can modify directly the local code of the dependency and make a new build. This works if it's a critical bug and you have to fix it as soon as possible. But, this is not the best option, because you'll lose the fix on the next yarn or npm install. Also, you won't be able to share the fix with your team.

Another option is to fork the package, fix the bug and create a pull request. At this point, you can update your project dependencies and use your fork until the maintainers of the package approve it and publish a new version.

"dependencies": {
  "buggy-package": "your_user/buggy-package#bugfix"
}

This looks like a good option, now your team members will get the fix when they will update the project dependencies. The downside is that you'll have to maintain the fork and make sure it's up to date.

Do we have a better option? Yes, we have. We can use the yarn patch command that was introduced in yarn v2.0.0. This allows you to instantly make and keep fixes to your dependencies without having to fork the packages.

Let's take as an example the remix-run package. During the development I found an issue with the session storage. I opened a pull request to fix it, then I patched the package directly in the project using the command:

  yarn patch @remix-run/node@npm:1.5.1

➤ YN0000: Package @remix-run/node@npm:1.5.1 got extracted with success!
➤ YN0000: You can now edit the following folder: /private/var/folders/xm/qntd4h_97zn6w88tc95bsvxc0000gp/T/xfs-bfc9a229/user
➤ YN0000: Once you are done run yarn patch-commit -s /private/var/folders/xm/qntd4h_97zn6w88tc95bsvxc0000gp/T/xfs-bfc9a229/user and Yarn will store a patchfile based on your changes.
➤ YN0000: Done in 0s 68ms

Once the package is extracted, we can open the created folder and make our changes there. One drawback is that you have to modify the production code, which might be minified and hard to debug. In my case was a simple change to the fileStorage module.

The next step is to commit the patch using the command displayed earlier in the console

yarn patch-commit -s /private/var/folders/xm/qntd4h_97zn6w88tc95bsvxc0000gp/T/xfs-bfc9a229/user

At this point we should see the following change in package.json

"resolutions": {
    "@remix-run/node@1.5.1": "patch:@remix-run/node@npm:1.5.1#.yarn/patches/@remix-run-node-npm-1.5.1-51061cf212.patch"
  }

and in .yarn/patches you'll find the patch file.

The benefits of using this approach are that the patch can be reviewed by your team and it doesn't require additional work to be applied compared to the fork. This should be used for critical fixes, if you need a new feature I would suggest to fork it instead. Also, do not forget to open an issue and create a pull request in the actual package.

Discussion

You must be logged in to post a comment

Your information is only used to display your name and reply by email.