Painless Patching
JavaScript developers benefit from a rich ecosystem of open-source libraries. However, one drawback of volunteer-maintained software is irregular updates. It is not infrequent to find a library with the desired functionality, but also with a well-documented bug. Despite — sometimes numerous — pull requests addressing the bug, the maintainer might take a long time to integrate the fix (or in case of abandoned packages, the fix is never merged).
Of course, the developer is able to apply the fix to his/her own codebase only. That introduces an issue, though, if an update does come and the developer applies it — the bug fix gets overwritten. If the update addresses the bug, then the fix is no longer necessary. However, if it doesn’t, then the developer needs to remember that the package needs a patch, and has to apply the fix to his/her codebase again.
Considering the fact that JavaScript projects usually rely on many libraries, and so several fixes might have been applied to the dependencies, it is easy to make a mistake. Managing patches is also time-consuming.
It is a good practice to keep dependencies up to date (especially with patch updates), so having used patches to dependencies should not be a reason not to update. Fortunately, the JavaScript ecosystem also offers an easy-to-use tool for managing dependencies patches: the library patch-package.
The set-up is straightforward. In most cases, it is sufficient to just install the package and add
“postinstall”: “patch-package”
to the scripts in the package.json file.
The usage is also straightforward. We make changes to the code in our dependencies, then run
npx patch-package package-name
for the dependencies that we have altered. This creates a diff file for the original and the developer’s version of the package.
Next step is to commit the diff files in the version control tool of choice.
To apply the patches (after dependencies update), we run:
npx patch-package
This simple recipe is sufficient for most users. The succinct documentation lists other options and configurations. Heroku users, for example, should set this environment variable:
NPM_CONFIG_PRODUCTION=false
The documentation lists the benefits of patching over forking, so I will not reiterate them here (it also suggests cases where forking might be better).
Overall, patch-package is a simple but handy tool that all JavaScript developers should be aware of.