There are times when you want to install a local package as a project dependency. You might be writing a package for general distribution; or maybe you are contributing to an open source package, or a private personal package, or something internal to your team. You are working on local changes and you need to test them out before you commit, let alone before you open a pull request or deploy an update. What is the best way to add the local copy of the package to a local project for real work testing?
(No time to be reading things? Scroll to the end for the tldr.)
You can push your updates to a remote, and add that version as a dependency. For example with a Github repo you can do
npm install or
yarn add a
<remote url>[#<ref>] (for Github repos there is the shorthand
<user or org>/<repo>[#<ref>]). But that requires an internet connection, and the time to push updates, and you will have to reinstall the package in the project with every change.
npm add relative/path and
yarn add file:relative/path, which copy the package directory over to the project’s node_modules. The npm command does not install dependencies. Neither responds to updates you make to the package. Plus using a relative path can get unwieldy with
npm link and
yarn link. Both add a dependency as local symlink. (
npm link docs,
yarn link docs.) But this solution has technical complications, and the npm and the yarn implimentations give people trouble (as of this writing there are about 40 open
npm link issues and over 150 open
yarn link issues). If you have tried to use symlinked dependencies while developing a package you’ve probably run into into a stumbling block, whether simply an unexpected
unlink behavior, trouble with peer dependencies, or something bigger.
So what to do? The answer for me is @whitecolor‘s yalc.
yalc maintains its own local “store”, at
~/.yalc. Publish a package with yalc, and a full copy of the package is copied to the store. Install a package from the yalc store, and the project will install that copy much like it would install a package from an external registry. Update a package published to the yalc store, and the update is now available in the dependent projects; you can even publish and automatically update dependent projects with a single command. To keep things from colliding, yalc signs each published version with a hash. And yalc can store as many versions of a package (that’s the
version) as you want.
yalc makes it easy to develop and test packages locally, in an intuitive way. It meets the common need you might expect
(npm|yarn) link to meet. yalc has a number of other useful features too — head over to its README to learn all about workspace-friendly
adding, advanced Git use, and more.
Here’s how to use yalc to manage local packages:
$ npm install -g yalc # or `yarn global add yalc`
$ is used to represent the command prompt)
Publish a package to your local yalc store
In the package you’re developing
# in the in-development package's directory
$ yalc publish
Add the package as a dependency from the yalc store
In the dependent project
# in the dependent project's directory
$ yalc add <dependency name>
If you look in your dependent project’s
package.json you will see that the dependency has been added, with a
file:.yalc/ path, e.g.
yalc also addes the
yalc.lock file, which lists the project dependencies added with yalc. After
yalc.lock in the dependent project’s root directory will look something like
"signature": "...", // a hash identifying the version of the dependency in yalc's store
"file": true // type of yalc connection
yalc does not install dependency packages, so if the package under development has its own
package.json dependencies they will need to be installed in the test project as a second step:
# in the dependent project's directory
$ npm install # or yarn
As of this writing, there is a bug where yalc dependencies are not given the correct permissions:
# in the dependent package's directory
$ <some command that relies on my-project>
/bin/sh: path/to/test-project/node_modules/.bin/my-package: Permission denied
error Command failed with exit code 126.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.