-
Notifications
You must be signed in to change notification settings - Fork 74
Dependencies
In short:
- Because the development dependencies are stripped out, anything you need Express to access at runtime must be a production dependency; and
- To keep the build size small (e.g. Heroku has a slug size limit of 500Mb), anything that's not needed by Express at runtime should be a development dependency.
The intended deployments go through the following build process:
-
npm install
- install all dependencies, development and production -
npm run build
- build the output inapi/static/
-
npm prune --production
- strip out the development dependencies
At runtime, they just have to npm start
. The development dependencies aren't needed (or available!) at runtime.
When adding a new dependency, classify it as follows:
Needed by | At runtime | During development |
---|---|---|
Client only |
npm install --workspace web <thing> (examples: React, React Router) |
npm install --save-dev --workspace web <thing> (examples: Vite(st), Testing Library) |
E2E tests only | N/A |
npm install --save-dev --workspace e2e <thing> (examples: Playwright) |
Server only |
npm install --workspace api <thing> (examples: Express, Morgan) |
npm install --save-dev --workspace api <thing> (examples: Jest, SuperTest) |
Two or more workspaces |
npm install --workspace api --workspace web <thing> 1
|
npm install --save-dev <thing> (examples: Concurrently, ESLint) |
If you're not sure whether something is needed at runtime or not, consider: will you be importing it in a non-.test
file?
1 Avoid installing non-dev dependencies in the root package.json
, or you'll need to add --include-workspace-root
for the installations in the Dockerfile
.
When you install or update your dependencies, you may see a message like this:
63 moderate severity vulnerabilities
To address issues that do not require attention, run:
npm audit fix
To address all issues possible (including breaking changes), run:
npm audit fix --force
Some issues need review, and may require choosing
a different dependency.
Run `npm audit` for details.
Many of the dependencies are only used during development, and not exposed to any end-user inputs, so aren't such a big deal (see e.g. facebook/create-react-app#11174 for more discussion). To focus on the ones that are used at runtime (assuming you've categorised any new dependencies appropriately, see Dependencies#new-dependencies), which is where the greatest risk lies, omit the development dependencies from the audit report:
$ npm audit --omit=dev
found 0 vulnerabilities
npm provides some commands you can use to manage the dependency tree (and automatically update the package.json
"package file" and package-lock.json
"lock file" if needed):
-
npm audit fix
will update any packages in your dependency tree where:- there is a known vulnerability in a version you have installed; and
- there is a fixed version that's semver-compatible with what's in your package file;
-
npm explain <package>
/npm ls <package>
tell you why the package is in your dependency tree (vulnerabilities won't always be in direct dependencies likereact
, sometimes they're in transitive dependencies):$ npm ls word-wrap [email protected] path/to/starter-kit └─┬ [email protected] └─┬ [email protected] └─┬ [email protected] └─┬ [email protected] └── [email protected]
-
npm outdated
will show you a list of packages you have installed that have newer releases:$ npm outdated Package Current Wanted Latest Location Depended by cypress 12.14.0 12.16.0 12.16.0 node_modules/cypress starter-kit eslint-plugin-jest 27.2.1 27.2.2 27.2.2 node_modules/eslint-plugin-jest starter-kit react-router-dom 6.13.0 6.14.0 6.14.0 node_modules/react-router-dom starter-kit webpack 5.87.0 5.88.0 5.88.0 node_modules/webpack starter-kit
-
npm update
will update all packages in your dependency tree to the latest semver-compatible releases;-
npm update --save
will also update the package file so that the minimum version is the latest semver-compatible one; -
npm update <package>@<version>
will update to the specified version (e.g.npm update react@latest
would install the latest version) whether or not it's compatible with what's in the package file.
-
⚠️ Do not runnpm audit fix --force
. That will apply changes that are not compatible with the dependencies declared in the package file, which can break things outright or cause hard-to-debug errors. If you need to apply major-version updates, do them one at a time usingnpm update <package>@<version>
and test each one.
If it's a package you've added (i.e. one that's not required by the base starter kit), a final option is to look for alternatives if it's not a well-maintained dependency (e.g. infrequent releases, lots of reported bugs that don't get fixed).