# npm packages, semver ranges and lockfiles

*JavaScript Developer Study Guide · Server Side JavaScript · Last updated October 16, 2026 · https://www.certifyforce.com/study-guide/javascript-developer/server-side-javascript/npm-packages-semver-and-lockfiles*

Where npm saves a package (dependencies, devDependencies, --no-save, -g), what the caret, tilde and exact ranges let npm install, why package-lock.json is committed and npm ci used in CI, how npx and npm scripts reach local binaries, and what causes 'Cannot find module' in production.

- Certification: Salesforce JavaScript Developer
- Exam section: Server Side JavaScript
- Study guide: https://www.certifyforce.com/study-guide/javascript-developer

**Official exam objective:**

> Given a scenario and requirements, distinguish which Node.Js Package Management solution is the most fitting.

## What the exam expects

- Choose the `npm install` flag that records a package in the right place: `dependencies`, `devDependencies`, nowhere (`--no-save`) or globally (`-g`).
- Work out which published version a caret (`^`), tilde (`~`), exact or open (`>=`) range lets npm install.
- Explain why package-lock.json is committed and why CI should run `npm ci`.
- Run a locally installed CLI tool with `npx` or an npm script.
- Diagnose `Cannot find module` in production, and place npm next to its alternatives Yarn and pnpm.

Key terms: **dependencies** (packages required by your application in production); **devDependencies** (packages only needed for local development and testing); **semver range** (a version descriptor such as `^1.4.2` that npm resolves to a concrete version); **package-lock.json** (the record of the exact dependency tree that was installed); **`npm ci`** (a clean, frozen install for automated environments).

## Key facts

| Fact | Detail | Source |
|---|---|---|
| Default save target | `dependencies` (`-P, --save-prod` is the default) | [npm install](https://docs.npmjs.com/cli/v12/commands/npm-install) |
| `-D, --save-dev` | Saves to `devDependencies` | [npm install](https://docs.npmjs.com/cli/v12/commands/npm-install) |
| `--no-save` | Prevents saving to package.json | [npm install](https://docs.npmjs.com/cli/v12/commands/npm-install) |
| Default range prefix | `save-prefix` defaults to `"^"` | [npm config](https://docs.npmjs.com/cli/v12/using-npm/config) |
| Patch-only range | `1.0`, `1.0.x` or `~1.0.4` | [About semantic versioning](https://docs.npmjs.com/about-semantic-versioning) |
| Minor-and-patch range | `1`, `1.x` or `^1.0.4` | [About semantic versioning](https://docs.npmjs.com/about-semantic-versioning) |
| Lock file | Exact generated tree; intended to be committed | [package-lock.json](https://docs.npmjs.com/cli/v12/configuring-npm/package-lock-json) |
| `npm ci` mismatch | Exits with an error; never writes package.json or the lock | [npm ci](https://docs.npmjs.com/cli/v12/commands/npm-ci) |
| `NODE_ENV=production` | `devDependencies` are not installed | [npm install](https://docs.npmjs.com/cli/v12/commands/npm-install) |
| `npm run` PATH | Adds `node_modules/.bin` | [npm run](https://docs.npmjs.com/cli/v12/commands/npm-run) |

## Check yourself

- Why does a package installed with `--save-dev` disappear in a container that sets `NODE_ENV=production`?
- When should a pipeline run `npm ci` instead of `npm install`?
- Which range accepts 1.0.5 but not 1.1.0 when starting from 1.0.4?
- How can a script call a locally installed binary such as `eslint` by name?

## Sources

- [npm install](https://docs.npmjs.com/cli/v12/commands/npm-install)
- [About semantic versioning](https://docs.npmjs.com/about-semantic-versioning)
- [package-lock.json](https://docs.npmjs.com/cli/v12/configuring-npm/package-lock-json)
- [npm ci](https://docs.npmjs.com/cli/v12/commands/npm-ci)
- [npx](https://docs.npmjs.com/cli/v12/commands/npx)
- [npm run](https://docs.npmjs.com/cli/v12/commands/npm-run)
- [package.json](https://docs.npmjs.com/cli/v12/configuring-npm/package-json)
- [Specifying dependencies and devDependencies](https://docs.npmjs.com/specifying-dependencies-and-devdependencies-in-a-package-json-file)
- [npm update](https://docs.npmjs.com/cli/v12/commands/npm-update)
- [npm config](https://docs.npmjs.com/cli/v12/using-npm/config)
- [About npm](https://docs.npmjs.com/about-npm)
- [An introduction to the npm package manager](https://nodejs.org/learn/getting-started/an-introduction-to-the-npm-package-manager)
- [Modules: CommonJS modules](https://nodejs.org/api/modules.html)
- [Modules: Packages](https://nodejs.org/api/packages.html)

## About the full unit

The "Core concepts", "Exam traps" and "Worked scenario" sections of this unit, its 6 linked practice questions, and unlimited timed mock exams are included with the JavaScript Developer pack (USD $19): https://www.certifyforce.com/practice-exams
