460

I have an application which has the usual set of dependencies on third party modules (e.g. 'express') specified in the package.json file under dependencies. E.g.

"express"     : "3.1.1"

I would like to structure my own code modularly and have a set of local (meaning on the file system I am currently in) modules be installed by the package.json. I know that I can install a local module by running:

npm install path/to/mymodule

However, I don't know how to make this happen via the package.json dependencies structure. Using the --save option in this command is simply putting "mymodule": "0.0.0" into my package.json (doesn't reference the filepath location). If i then remove the installed version from node_modules, and try to re-install from the package.json, it fails (because it looks for "mymodule" in the central registry, and doesn't look locally).

I'm sure the is a way of telling the "dependencies": {} structure that I want it to be installed from a file system path, but don't know how.

Anyone else had this problem? Thanks.

Sajad Torkamani
  • 544
  • 1
  • 7
  • 18
Sam Adams
  • 5,327
  • 2
  • 18
  • 17
  • 2
    A really good question. Sad to realise that there is no feature equivalent for `package.json` to what we have in `Gemfile`s. – Jarl Jun 06 '14 at 05:35
  • 4
    possible duplicate of [Local dependency in package.json](http://stackoverflow.com/questions/14381898/local-dependency-in-package-json) – Kelly Jul 28 '15 at 17:47

9 Answers9

728

npm install now supports this

npm install --save ../path/to/mymodule

For this to work mymodule must be configured as a module with its own package.json. See Creating NodeJS modules.

As of npm 2.0, local dependencies are supported natively. See danilopopeye's answer to a similar question. I've copied his response here as this question ranks very high in web search results.

This feature was implemented in the version 2.0.0 of npm. For example:

{
  "name": "baz",
  "dependencies": {
    "bar": "file:../foo/bar"
  }
}

Any of the following paths are also valid:

../foo/bar
~/foo/bar
./foo/bar
/foo/bar

syncing updates

Since npm install <folder> adds the package in the directory as a symlink in the current project any changes to the local package are automatically synced.

Anjum....
  • 4,086
  • 1
  • 35
  • 45
Randy the Dev
  • 25,810
  • 6
  • 43
  • 54
  • 3
    This worked for me. (I just did a local relative path like `"mymodule":"file:mymoduledir"` – Don Rhummy Nov 14 '16 at 20:18
  • 77
    ```npm install --save ../my-local-repo``` – Ivan Rave Jun 26 '17 at 10:39
  • 36
    And how to use it in the project? I'm trying to call it like `import { HelloWorld } from "my-test-lib";`, but i receive "Cant find module" error. Please, take a look at https://stackoverflow.com/questions/46818083/use-a-local-module-using-local-dependency/46818152 – Vitalii Vasylenko Oct 18 '17 at 21:52
  • 10
    @LucioMollinedo can you share the syntax of how you imported the local module? As with Vitallii, I'm getting "Can't fine module" error with `import { HelloWorld } from "my-test-lib";` – Stan James Dec 23 '17 at 21:17
  • 13
    This doesn't work the same as referencing a package as dependencies won't be installed to the project – Glass Cannon Oct 04 '18 at 13:36
  • 10
    Same as everyone here, I don't understand how to import the module? Can someone please share that crucial bit of info, and maybe update the answer? Referencing the local module is pointless without also being able to use it??? – lonix Feb 26 '19 at 07:02
  • 3
    If I include the module baz in another module (say main-module), the bar module is not found when I run npm install on main-module. Any solutions for this? – vibhu Mar 01 '19 at 12:52
  • 2
    I tried the same, but it throws the error npm ERR! code ENOLOCAL npm ERR! Could not install from "../../../../../WebstormProjects/project-name" as it does not contain a package.json file. – pradyumnad Apr 07 '19 at 04:54
  • This works for me. But IDE navigates me to node_modules instead of the actual project file while trying to access the source of import. How do I fix this? – Edison D'souza Dec 10 '19 at 14:18
  • This works great when I am running locally. However, when I do a "sam build" it fails with "npm ERR! Could not install from "..\dependencies\nodejs" as it does not contain a package.json file." What is so special about AWS's sam build command that it breaks? – Brandon Mar 04 '20 at 18:30
  • The problem is if using Docker you need to list all local dependencies in the Dockerfile – user210757 Jun 23 '20 at 17:34
  • 3
    @inigo why did you add the caveat about syncing updates? I just tried this with npm 6.14.8 on macOS and it creates a symlink therefore updates do propagate automatically. – steinybot Dec 16 '20 at 06:51
  • 2
    This doesn't work in npm any more. There is an [npm issue and repro](https://github.com/npm/cli/issues/2339#issuecomment-904748108) demonstrating that this doesn't work due to an intentional breaking change starting in version 7. – Wyck Sep 26 '22 at 14:49
  • 1
    For the `can't find module` error don't forget to run `npm build` in the linked package's folder. – loc Nov 17 '22 at 11:39
57

See: Local dependency in package.json

It looks like the answer is npm link: https://docs.npmjs.com/cli/link

gman
  • 100,619
  • 31
  • 269
  • 393
jasoncrawford
  • 2,713
  • 2
  • 21
  • 20
16

I couldn't find a neat way in the end so I went for create a directory called local_modules and then added this bashscript to the package.json in scripts->preinstall

#!/bin/sh
for i in $(find ./local_modules -type d -maxdepth 1) ; do
    packageJson="${i}/package.json"
    if [ -f "${packageJson}" ]; then
        echo "installing ${i}..."
        npm install "${i}"
    fi
done
Sam Adams
  • 5,327
  • 2
  • 18
  • 17
7

You can just add to your package.json file in your project

"package-name" : "path/to/package"

and then run npm i in your project

6

After struggling much with the npm link command (suggested solution for developing local modules without publishing them to a registry or maintaining a separate copy in the node_modules folder), I built a small npm module to help with this issue.

The fix requires two easy steps.

First:

npm install lib-manager --save-dev

Second, add this to your package.json:

{  
  "name": "yourModuleName",  
  // ...
  "scripts": {
    "postinstall": "./node_modules/.bin/local-link"
  }
}

More details at https://www.npmjs.com/package/lib-manager. Hope it helps someone.

Clay Bridges
  • 11,602
  • 10
  • 68
  • 118
Anurag Dutta
  • 61
  • 1
  • 3
4

At work we have a common library that is used by a few different projects all in a single repository. Originally we used the published (private) version (npm install --save rp-utils) but that lead to a lot of needless version updates as we developed. The library lives in a sister directory to the applications and we are able to use a relative path instead of a version. Instead of "rp-utils": "^1.3.34" in package.json it now is:

{ 
  "dependencies": { ...
    "rp-utils": "../rp-utils",
   ...

the rp-utils directory contains a publishable npm package

  • 1
    do you need to perform `npm install` every time you make changes to `rp-utils`? – inside Nov 21 '20 at 18:06
  • 1
    Any time you change the imported package you will need to rebuild it and then in the application that uses it `npm update rp-utils` update that dependency. – Joshua Goldstein Nov 23 '20 at 20:38
4

The following should help (assuming the library and the app share the same the parent folder)

In the library:

npm pack // this will pack the library in a .tgz file

In the app that needs the library

npm i ../mylibrary/../library-package-X.X.tgz

This will make the following changes in your app

package.json will now have

 "@mylibrary": "file:../mylibrary/library-package-X.X.tgz",
Taranjeet Singh
  • 159
  • 1
  • 10
2

use install-local

I had issues with conflicting react installations from the local dependency. I solved the error by using install-local npm package. This package does not create symlinks, which solved my issue.

Steps:

  1. run npm i -g install-local
  2. run npx install-local --save <local-path> inside the target repository to install the local dependency

Further reading: https://www.npmjs.com/package/install-local

The error I received, when trying to install the local package with npm install --save <local-directory>:

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app
Irfan wani
  • 4,084
  • 2
  • 19
  • 34
wasserholz
  • 1,960
  • 2
  • 20
  • 26
0

If it's acceptible to simply publish your modules preinstalled in node_modules alongside your other files, you can do it like this:

// ./node_modules/foo/package.json
{ 
  "name":"foo",
  "version":"0.0.1",
  "main":"index.js"
}

// ./package.json
...
"dependencies": {
  "foo":"0.0.1",
  "bar":"*"
}

// ./app.js
var foo = require('foo');

You may also want to store your module on git and tell your parent package.json to install the dependency from git: https://npmjs.org/doc/json.html#Git-URLs-as-Dependencies

Plato
  • 10,812
  • 2
  • 41
  • 61
  • 6
    Unfortunately that would involve node_modules having my local modules and third party/contributed modules installed from the registry (e.g. connect) in the same directory. Besides that being confusing from a Git/VCS perspective (i.e. would have to ignore all in node_modules except those i created), it's also bad practice (those I have written and aren't published should be kept separate from those others have written and published). – Sam Adams Apr 08 '13 at 08:12
  • When I add a local module then make changes these are not seen by my main app. Why is this the case? – Mark Tyers Mar 28 '16 at 19:06