Patch NPM Dependencies

Patch NPM Dependencies


3 min read

To develop project with node.js, we usually use a lot of npm packages. Sooner or later, we will run into a problem with the packages. We need to use it but we also need to change its code for our own needs.

In this scenario, we may have some options. We can fork the project and change it directly. But in this way, we need to sync the fork version with the original one from time to time. This is a bit costly. For small changes, we can choose to change the source code in the node_modules folder and then figure out a way to save the results.

If we use npm, then the patch-package package can be used for this purpose. Let's use an example to see how this can be achieved.

First, let init a new project.

npm init -y

Then install the rimraf package, which is the target we need to change in this example.

npm i rimraf

Then let's install the patch-package package.

npm i patch-package

According to its documentation, we need to set up the postinstall hook.

"scripts": {
    "postinstall": "patch-package",

OK. Now let go to the entry file of the rimraf package, which is the file node_modules/rimraf/rimraf.js. Then we insert a print code as a test.

console.log("Haha, this is my changes.");

Then let's add a command for test.

"scripts": {
    "test": "touch 1.txt && rimraf 1.txt"

If we try to run npm run test, then we should see the print result. This is expected, because we just change the source code.

Now let run the patch command to save the changed result.

npx patch-package rimraf

This command means that we use patch-package command to process any changes in the package rimraf. Then the changes we made should be detected and saved in patches/rimraf+3.0.2.patch file. This file contains all the information about the changes.

diff --git a/node_modules/rimraf/rimraf.js b/node_modules/rimraf/rimraf.js
index 34da417..751b73c 100644
--- a/node_modules/rimraf/rimraf.js
+++ b/node_modules/rimraf/rimraf.js
@@ -2,6 +2,9 @@ const assert = require("assert")
 const path = require("path")
 const fs = require("fs")
 let glob = undefined
+console.log("Haha, this is my changes.");
 try {
   glob = require("glob")
 } catch (_err) {

This file should be committed into the repository so other team members could see the patch content.

Later, if we delete the node_modules and try to init the project again with npm i, then the postinstall hook will be triggered and this patches will be detected and applied.

So finally, run the test again, we should see the message we added be printed properly.

This is the whole process. It's pretty straightforward. First, we make changes, store the result. Then later we install the package again and apply the changes from the stored files.

Note that yarn and pnpm has native support for this patch functionality, so no need for patch-package if you are using yarn or pnpm.