Yarn (original) (raw)

Workspaces are a new way to set up your package architecture that’s available by default starting from Yarn 1.0. It allows you to setup multiple packages in such a way that you only need to run yarn install once to install all of them in a single pass.

Why would you want to do this?

How to use it?

Add the following in a package.json file. Starting from now on, we’ll call this directory the “workspace root”:

package.json

{
  "private": true,
  "workspaces": ["workspace-a", "workspace-b"]
}

Note that the private: true is required! Workspaces are not meant to be published, so we’ve added this safety measure to make sure that nothing can accidentally expose them.

After this file has been created, create two new subfolders named workspace-a and workspace-b. In each of them, create another package.json file with the following content:

workspace-a/package.json:

{
  "name": "workspace-a",
  "version": "1.0.0",

  "dependencies": {
    "cross-env": "5.0.5"
  }
}

workspace-b/package.json:

{
  "name": "workspace-b",
  "version": "1.0.0",

  "dependencies": {
    "cross-env": "5.0.5",
    "workspace-a": "1.0.0"
  }
}

Finally, run yarn install somewhere, ideally inside the workspace root. If everything works well, you should now have a similar file hierarchy:

/package.json
/yarn.lock

/node_modules
/node_modules/cross-env
/node_modules/workspace-a -> /workspace-a

/workspace-a/package.json
/workspace-b/package.json

Note: don’t look for /nodemodules/workspace-b. It won’t be there unless some other package use it as a dependency.

And that’s it! Requiring workspace-a from a file located in workspace-b will now use the exact code currently located inside your project rather than what is published on npm, and the cross-env package has been correctly deduped and put at the root of your project to be used by both workspace-a and workspace-b.

Please note the fact that /workspace-a is aliased as /node_modules/workspace-a via a symlink. That’s the trick that allows you to require the package as if it was a normal one! You also need to know that the /workspace-a/package.json#name field is used and not the folder name. This means that if the /workspace-a/package.json name field was "pkg-a", the alias will be the following:/node_modules/pkg-a -> /workspace-a and you will be able to import code from /workspace-a with const pkgA = require("pkg-a"); (or maybe import pkgA from "pkg-a";).

How does it compare to Lerna?

Yarn’s workspaces are the low-level primitives that tools like Lerna can (and do!) use. They will never try to support the high-level feature that Lerna offers, but by implementing the core logic of the resolution and linking steps inside Yarn itself we hope to enable new usages and improve performance.

Tips & Tricks

workspaces-experimental false  

Limitations & Caveats