3 min read

How to use forked NPM dependencies

Syed Aslam

When using open-source NPM packages in your project, odds are you will run into a dependency that is missing a feature. This dependency doesn't do quite do what you want or has a bug that needs to be worked around for your use-case. What do you do in these situations, if your team doesn't have the time to create your custom solution to the problem?

Many times it is best to create a pull-request to the repo in question. However, this would work very well in projects that are actively maintained, but it can sometimes take months before your pull-request is merged into the project if at all your inputs aligns with the project's overall scope and direction.

One way to work around this limitation is to fork the project, make changes to add that feature you wanted, or fix the bug that needs fixing before you can use this project. And then use this fork in your project by altering package.json.

In package.json, dependencies are specified in a simple object that maps a package name to a version range. The version range is a string that has one or more space-separated descriptors. Dependencies can also be identified with a tarball or git URL.

  • version Must match version exactly
  • >version Must be greater than version
  • >=version etc
  • <version
  • <=version
  • ~version Approximately equivalent to version
  • ^version Compatible with version
  • 1.2.x 1.2.0, 1.2.1, etc., but not 1.3.0
  • http://... See 'Git URLs as Dependencies' below
  • * Matches any version
  • "" (just an empty string) Same as *
  • version1 - version2 Same as >=version1 <=version2.
  • range1 || range2 Passes if either range1 or range2 are satisfied.
  • git...
  • user/repo
  • tag A specific version tagged and published as tag
  • path/path/path Local path

For example, these are all valid:

{ "dependencies" :
  { "foo" : "1.0.0 - 2.9999.9999"
  , "bar" : ">=1.0.2 <2.1.2"
  , "baz" : ">1.0.2 <=2.3.4"
  , "boo" : "2.0.1"
  , "qux" : "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0"
  , "asd" : "http://asdf.com/asdf.tar.gz"
  , "til" : "~1.2"
  , "elf" : "~1.2.3"
  , "two" : "2.x"
  , "thr" : "3.3.x"
  , "lat" : "latest"
  , "dyl" : "file:../dyl"
  }
}

Git URL's as Dependencies

You may specify Git URL in place of a version range. Git URL's are of the form:

<protocol>://[<user>[:<password>]@]<hostname>[:<port>][:][/]<path>[#<commit-ish> | #semver:<semver>]

<protocol> is one of git, git+ssh, git+http, git+https, or git+file.

Examples:

git+ssh://git@github.com:npm/foo.git#v1.0.27
git+ssh://git@github.com:npm/bar#semver:^5.0
git+https://aslam@github.com/npm/baz.git
git://github.com/npm/boo.git#v1.0.27

Now, to use the custom dependency in your project all you've to do is change your package.json to point to your fork:

From:

{ "dependencies" :
  { "custom-dep" : "1.0.6"
    ...
  }
}

To:

{ "dependencies" :
  { "custom-dep" : "git+https://github.com/aslam/custom-dep.git"
    ...
  }
}

This configuration changes the version number of the custom-dep to a direct link to the source code. If the project in question is a library that is well set up with a prepublish command, this is all you will need to do.

And there you have it! Because NPM allows for direct downloading of packages from source control, you don't have to wait on pull requests to get merged, and your app can benefit from custom code changes now. This capability can allow your team to move fast to fix bugs coming from third-party dependencies.

For more information, check out the dependencies section of the NPM documentation.