How to patch a javascript library using pnpm

In this article we’ll explore how we can fix a broken javascript library quickly and efficiently with pnpm built-in feature. Due to its efficiency and speed, I use pnpm
package manager for every new project I start.
If you would like to find out more, please refer to this article or to their official documentation.
Problem
It’s not possible to find a javascript project with no dependencies. Almost every application or even library has a bunch of items in dependencies
or devDependencies
in its package.json
file. And it’s no surprise, bacause using libraries saves us lots of efforts, time, and of course money.
However, there are times when we install or update a particular library, and then suddenly we realize that it breaks our application.
It happens for multiple reasons. For example, developers don’t always test every edge case, they might incorrectly follow Semantic Versioning rules or they just made a mistake (after all, we are humans rather than robots, we all make mistakes).
Possible solutions
There are at least a few solutions to our problem. Each of them (as everything else) has its own pros and cons.
Find an alternative
The easiest way is to throw away this shitty library and find something new. Voila 😅
But if you’ve already been there, you probably know that finding a new library is not as simple as it might seem. Sometimes there is just no good alternatives, and sometimes there are so many alternatives that you are not able to pick one to cover your needs.
Downgrade a library version
If the issue arises after upgrading a library version, first of all, you need to check if there were any breaking changes and adjust your code accordingly. If there’s no changes that might expectedly break your app, then you can downgrade the library back if it had worked as expected before. It’s not always an option though. The new version might include some important security fixes or new features that your project requires.
Ask maintainers to fix the issue
Another way to get a library fixed is to open a library repository and create an issue under the Issues tab, and then wait for a new version. This is a reliable and common way for at least two reasons:
-
the maintainers know their code better than anyone else and can fix the code quickly and release a new version;
-
other users probably experience the same issue and they might’ve already found a solution, so someone will reply and help you to find a temporary workaround.
However, this method might require a considerable amount of time, maintainers might have other priorities.
Fork a library repo, fix the issue, create PR
This method is similar to the one above, but in this case you are the one who finds and fixes the issue. The exact process might vary from library to library, depending on the repository rules, but the overall idea is:
- Fork the repository and clone it to your local machine.
- Explore the code and find where the issues comes from.
- Fix the issue and test operability.
- Push the changes to the remote.
- Go to the original repository and create a pull request.
- Wait untill it’s approved and merged.
This way might be a little faster than the previous one, yet it requires some time for maintainers to review and merge your PR.
Patch a library on your own
But what if the release is planned for tommorow or even worse, it’s in a few hours? Obviously, you don’t have the time to wait for the fix. Your last option is to fix the library on your own.
Begginer’s approach
If you’re a beginner you might be tempted to fix a library right in your node_modules
folder. There is still a problem. How would your colleagues or production environment get the same fix?
Of course you could create a guide how to apply your fix and repeat the same process on every fresh pnpm install
, but doesn’t it look too tedious and unreliable?
Professional approach using pnpm built-in feature
For this section I’ve created and published a very simple library for adding two numbers. However, it has a little error that you will see further.
Setup
To start, let’s initialize a project locally where we’ll be installing our library. To do so we need to run the following command in the terminal:
pnpm init
Pnpm will only generate the package.json
file for us with the following structure:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"name": "pnpm-patch-example",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {}
}
Please, make sure you have "type": "module"
in the package.json
file.
Let’s now install the library into our newly created project. The following command will generate pnpm-lock.yaml
file, add the library into dependencies
object in the package.json
, create node_modules
folder, and add the actual library there.
pnpm add wijione-add-two-numbers
Once everything is set up, we can start utilizing the library in our project. Let’s create our main index.js
file with very simple program.
1
2
3
4
5
6
// index.js
import addNumbers from "wijione-add-two-numbers";
const sum = addNumbers(20, 10);
console.log(sum);
Bug
The program we’ve written is supposed to print 30 in the terminal. Let’s run the application and see what happens.
Unexpectedly, we get 10 instead of 30. Hmm, seems like the library does subtraction instead of addition. Let’s open the source code of the library inside node_modules
and find our why we’re getting a wrong result.
As you can see, we were right, a wrong operator has been used. Let’s fix it together.
Patch
To start patching process we need to run the command below, which creates a draft folder and copies the source code of the library so that we can edit it:
pnpm patch wijione-add-two-numbers@1.0.0
By default pnpm creates the folder in a special path like in the screenshot below. The path is instantly printed to the terminal. However, using --edit-dir
flag you can specify the folder as you see fit.
Once the folder is created, we can open it and edit the source code however we like. In our example we must replace subtraction operator (-) with addition operation (+) in /<generated_path_to_the_patch_folder>/index.js
file.
Final result should look like this:
1
2
3
4
5
// <generated_path_to_the_patch_folder>/index.js
export default (a, b) => {
return a + b;
}
Once we’ve done editing the source code, we need to commit the changes we’ve made. To do so we have to run command below. As an argument we pass a path to the folder that was generated by pnpm patch
command:
pnpm patch-commit <generated_path_to_the_patch_folder>
When you commit the changes, pnpm enters the information about the patched package into package.json
and pnpm-lock.yaml
files, creates a special file wijione-add-two-numbers@1.0.0.patch
under patches
folder in the root of your project and applies changes to the library source code in node_modules
. In the screenshot below you can see what information the patch file contains.
In general, every time you run pnpm install
, pnpm add
, pnpm update
and so on, pnpm will automatically traverse patches
folder and apply changes on top of the installed packages based on patch files contents.
Now, to test the theory, remove the node_modules
folder and run pnpm install
. Eventually, in the node_modules
you will see addition operator in the library source code according to our patch.
Let’s also run the application to make sure that it works correctly now.
As you can see, the issue has been fixed and now we can see the correct result.
Note that if you update the library version (for example to 1.0.1
), changes from patch won’t be applied, since the patch is associated with a particular version. In our case it’s 1.0.0
.
Also, don’t forget to commit and push patches
folder to the remote. This way your colleagues will have access to the patch as well.
Patch deletion
Once the library maintainers have fixed the issue, we can upgrade the version and get rid of the patch we’ve created.
Simply deleting the patch file is not enough, because like I said earlier, pnpm also adds some information into package.json
and pnpm-lock.yaml
files.
Don’t worry, removing a patch is much simpler than creating it. To delete the patch just type the following command into the terminal and it will do everything for you:
pnpm patch-remove wijione-add-two-numbers@1.0.0
Voila! The patch has been completely removed from the project.
Conclusion
That’s basically it. Although the article turned out to be a little longer than I’d been planning, now you know what to do when you run into a broken library. I’ll try to keep my future posts as short as possible to include only necessary information.