11cb0ef41Sopenharmony_ci---
21cb0ef41Sopenharmony_cititle: workspaces
31cb0ef41Sopenharmony_cisection: 7
41cb0ef41Sopenharmony_cidescription: Working with workspaces
51cb0ef41Sopenharmony_ci---
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci### Description
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci**Workspaces** is a generic term that refers to the set of features in the
101cb0ef41Sopenharmony_cinpm cli that provides support for managing multiple packages from your local
111cb0ef41Sopenharmony_cifile system from within a singular top-level, root package.
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ciThis set of features makes up for a much more streamlined workflow handling
141cb0ef41Sopenharmony_cilinked packages from the local file system. It automates the linking process
151cb0ef41Sopenharmony_cias part of `npm install` and removes the need to manually use `npm link` in
161cb0ef41Sopenharmony_ciorder to add references to packages that should be symlinked into the current
171cb0ef41Sopenharmony_ci`node_modules` folder.
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ciWe also refer to these packages being auto-symlinked during `npm install` as a
201cb0ef41Sopenharmony_cisingle **workspace**, meaning it's a nested package within the current local
211cb0ef41Sopenharmony_cifile system that is explicitly defined in the [`package.json`](/configuring-npm/package-json#workspaces)
221cb0ef41Sopenharmony_ci`workspaces` configuration.
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ci### Defining workspaces
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ciWorkspaces are usually defined via the `workspaces` property of the
271cb0ef41Sopenharmony_ci[`package.json`](/configuring-npm/package-json#workspaces) file, e.g:
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ci```json
301cb0ef41Sopenharmony_ci{
311cb0ef41Sopenharmony_ci  "name": "my-workspaces-powered-project",
321cb0ef41Sopenharmony_ci  "workspaces": [
331cb0ef41Sopenharmony_ci    "packages/a"
341cb0ef41Sopenharmony_ci  ]
351cb0ef41Sopenharmony_ci}
361cb0ef41Sopenharmony_ci```
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ciGiven the above `package.json` example living at a current working
391cb0ef41Sopenharmony_cidirectory `.` that contains a folder named `packages/a` that itself contains
401cb0ef41Sopenharmony_cia `package.json` inside it, defining a Node.js package, e.g:
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci```
431cb0ef41Sopenharmony_ci.
441cb0ef41Sopenharmony_ci+-- package.json
451cb0ef41Sopenharmony_ci`-- packages
461cb0ef41Sopenharmony_ci   +-- a
471cb0ef41Sopenharmony_ci   |   `-- package.json
481cb0ef41Sopenharmony_ci```
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ciThe expected result once running `npm install` in this current working
511cb0ef41Sopenharmony_cidirectory `.` is that the folder `packages/a` will get symlinked to the
521cb0ef41Sopenharmony_ci`node_modules` folder of the current working dir.
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ciBelow is a post `npm install` example, given that same previous example
551cb0ef41Sopenharmony_cistructure of files and folders:
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci```
581cb0ef41Sopenharmony_ci.
591cb0ef41Sopenharmony_ci+-- node_modules
601cb0ef41Sopenharmony_ci|  `-- a -> ../packages/a
611cb0ef41Sopenharmony_ci+-- package-lock.json
621cb0ef41Sopenharmony_ci+-- package.json
631cb0ef41Sopenharmony_ci`-- packages
641cb0ef41Sopenharmony_ci   +-- a
651cb0ef41Sopenharmony_ci   |   `-- package.json
661cb0ef41Sopenharmony_ci```
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci### Getting started with workspaces
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ciYou may automate the required steps to define a new workspace using
711cb0ef41Sopenharmony_ci[npm init](/commands/npm-init). For example in a project that already has a
721cb0ef41Sopenharmony_ci`package.json` defined you can run:
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci```
751cb0ef41Sopenharmony_cinpm init -w ./packages/a
761cb0ef41Sopenharmony_ci```
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ciThis command will create the missing folders and a new `package.json`
791cb0ef41Sopenharmony_cifile (if needed) while also making sure to properly configure the
801cb0ef41Sopenharmony_ci`"workspaces"` property of your root project `package.json`.
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_ci### Adding dependencies to a workspace
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ciIt's possible to directly add/remove/update dependencies of your workspaces
851cb0ef41Sopenharmony_ciusing the [`workspace` config](/using-npm/config#workspace).
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ciFor example, assuming the following structure:
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ci```
901cb0ef41Sopenharmony_ci.
911cb0ef41Sopenharmony_ci+-- package.json
921cb0ef41Sopenharmony_ci`-- packages
931cb0ef41Sopenharmony_ci   +-- a
941cb0ef41Sopenharmony_ci   |   `-- package.json
951cb0ef41Sopenharmony_ci   `-- b
961cb0ef41Sopenharmony_ci       `-- package.json
971cb0ef41Sopenharmony_ci```
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ciIf you want to add a dependency named `abbrev` from the registry as a
1001cb0ef41Sopenharmony_cidependency of your workspace **a**, you may use the workspace config to tell
1011cb0ef41Sopenharmony_cithe npm installer that package should be added as a dependency of the provided
1021cb0ef41Sopenharmony_ciworkspace:
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci```
1051cb0ef41Sopenharmony_cinpm install abbrev -w a
1061cb0ef41Sopenharmony_ci```
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ciNote: other installing commands such as `uninstall`, `ci`, etc will also
1091cb0ef41Sopenharmony_cirespect the provided `workspace` configuration.
1101cb0ef41Sopenharmony_ci
1111cb0ef41Sopenharmony_ci### Using workspaces
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ciGiven the [specifics of how Node.js handles module resolution](https://nodejs.org/dist/latest-v14.x/docs/api/modules.html#modules_all_together) it's possible to consume any defined workspace
1141cb0ef41Sopenharmony_ciby its declared `package.json` `name`. Continuing from the example defined
1151cb0ef41Sopenharmony_ciabove, let's also create a Node.js script that will require the workspace `a`
1161cb0ef41Sopenharmony_ciexample module, e.g:
1171cb0ef41Sopenharmony_ci
1181cb0ef41Sopenharmony_ci```
1191cb0ef41Sopenharmony_ci// ./packages/a/index.js
1201cb0ef41Sopenharmony_cimodule.exports = 'a'
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci// ./lib/index.js
1231cb0ef41Sopenharmony_ciconst moduleA = require('a')
1241cb0ef41Sopenharmony_ciconsole.log(moduleA) // -> a
1251cb0ef41Sopenharmony_ci```
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ciWhen running it with:
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ci`node lib/index.js`
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ciThis demonstrates how the nature of `node_modules` resolution allows for
1321cb0ef41Sopenharmony_ci**workspaces** to enable a portable workflow for requiring each **workspace**
1331cb0ef41Sopenharmony_ciin such a way that is also easy to [publish](/commands/npm-publish) these
1341cb0ef41Sopenharmony_cinested workspaces to be consumed elsewhere.
1351cb0ef41Sopenharmony_ci
1361cb0ef41Sopenharmony_ci### Running commands in the context of workspaces
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_ciYou can use the `workspace` configuration option to run commands in the context
1391cb0ef41Sopenharmony_ciof a configured workspace.
1401cb0ef41Sopenharmony_ciAdditionally, if your current directory is in a workspace, the `workspace`
1411cb0ef41Sopenharmony_ciconfiguration is implicitly set, and `prefix` is set to the root workspace.
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ciFollowing is a quick example on how to use the `npm run` command in the context
1441cb0ef41Sopenharmony_ciof nested workspaces. For a project containing multiple workspaces, e.g:
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_ci```
1471cb0ef41Sopenharmony_ci.
1481cb0ef41Sopenharmony_ci+-- package.json
1491cb0ef41Sopenharmony_ci`-- packages
1501cb0ef41Sopenharmony_ci   +-- a
1511cb0ef41Sopenharmony_ci   |   `-- package.json
1521cb0ef41Sopenharmony_ci   `-- b
1531cb0ef41Sopenharmony_ci       `-- package.json
1541cb0ef41Sopenharmony_ci```
1551cb0ef41Sopenharmony_ci
1561cb0ef41Sopenharmony_ciBy running a command using the `workspace` option, it's possible to run the
1571cb0ef41Sopenharmony_cigiven command in the context of that specific workspace. e.g:
1581cb0ef41Sopenharmony_ci
1591cb0ef41Sopenharmony_ci```
1601cb0ef41Sopenharmony_cinpm run test --workspace=a
1611cb0ef41Sopenharmony_ci```
1621cb0ef41Sopenharmony_ci
1631cb0ef41Sopenharmony_ciYou could also run the command within the workspace.
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_ci```
1661cb0ef41Sopenharmony_cicd packages/a && npm run test
1671cb0ef41Sopenharmony_ci```
1681cb0ef41Sopenharmony_ci
1691cb0ef41Sopenharmony_ciEither will run the `test` script defined within the
1701cb0ef41Sopenharmony_ci`./packages/a/package.json` file.
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_ciPlease note that you can also specify this argument multiple times in the
1731cb0ef41Sopenharmony_cicommand-line in order to target multiple workspaces, e.g:
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_ci```
1761cb0ef41Sopenharmony_cinpm run test --workspace=a --workspace=b
1771cb0ef41Sopenharmony_ci```
1781cb0ef41Sopenharmony_ci
1791cb0ef41Sopenharmony_ciOr run the command for each workspace within the 'packages' folder:
1801cb0ef41Sopenharmony_ci```
1811cb0ef41Sopenharmony_cinpm run test --workspace=packages
1821cb0ef41Sopenharmony_ci```
1831cb0ef41Sopenharmony_ci
1841cb0ef41Sopenharmony_ciIt's also possible to use the `workspaces` (plural) configuration option to
1851cb0ef41Sopenharmony_cienable the same behavior but running that command in the context of **all**
1861cb0ef41Sopenharmony_ciconfigured workspaces. e.g:
1871cb0ef41Sopenharmony_ci
1881cb0ef41Sopenharmony_ci```
1891cb0ef41Sopenharmony_cinpm run test --workspaces
1901cb0ef41Sopenharmony_ci```
1911cb0ef41Sopenharmony_ci
1921cb0ef41Sopenharmony_ciWill run the `test` script in both `./packages/a` and `./packages/b`.
1931cb0ef41Sopenharmony_ci
1941cb0ef41Sopenharmony_ciCommands will be run in each workspace in the order they appear in your `package.json`
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_ci```
1971cb0ef41Sopenharmony_ci{
1981cb0ef41Sopenharmony_ci  "workspaces": [ "packages/a", "packages/b" ]
1991cb0ef41Sopenharmony_ci}
2001cb0ef41Sopenharmony_ci```
2011cb0ef41Sopenharmony_ci
2021cb0ef41Sopenharmony_ciOrder of run is different with:
2031cb0ef41Sopenharmony_ci
2041cb0ef41Sopenharmony_ci```
2051cb0ef41Sopenharmony_ci{
2061cb0ef41Sopenharmony_ci  "workspaces": [ "packages/b", "packages/a" ]
2071cb0ef41Sopenharmony_ci}
2081cb0ef41Sopenharmony_ci```
2091cb0ef41Sopenharmony_ci
2101cb0ef41Sopenharmony_ci### Ignoring missing scripts
2111cb0ef41Sopenharmony_ci
2121cb0ef41Sopenharmony_ciIt is not required for all of the workspaces to implement scripts run with the `npm run` command.
2131cb0ef41Sopenharmony_ci
2141cb0ef41Sopenharmony_ciBy running the command with the `--if-present` flag, npm will ignore workspaces missing target script.
2151cb0ef41Sopenharmony_ci
2161cb0ef41Sopenharmony_ci```
2171cb0ef41Sopenharmony_cinpm run test --workspaces --if-present
2181cb0ef41Sopenharmony_ci```
2191cb0ef41Sopenharmony_ci
2201cb0ef41Sopenharmony_ci### See also
2211cb0ef41Sopenharmony_ci
2221cb0ef41Sopenharmony_ci* [npm install](/commands/npm-install)
2231cb0ef41Sopenharmony_ci* [npm publish](/commands/npm-publish)
2241cb0ef41Sopenharmony_ci* [npm run-script](/commands/npm-run-script)
2251cb0ef41Sopenharmony_ci* [config](/using-npm/config)
2261cb0ef41Sopenharmony_ci
227