1.4 · npm: package.json, dependencies, scripts, versions

Level 1 · JavaScript & Node basics

1.4npm: package.json, dependencies, scripts, versions

Goal: manage a Node project with npm: package.json, dependencies (prod vs dev), scripts, semantic versioning and security (audit) — the foundation of every project.
Estimated time: 12 min · self-paced reading · If you only have 5 min: read “The essentials in 30s” + the diagram.

The essentials in 30 seconds

  • package.json = the manifest: name, version, dependencies, scripts — created with npm init, the reference point of every project.
  • The recipe, not the result: version package.json + package-lock.json (exact versions), never node_modules (regenerable via npm install).
  • Semver + scripts + audit: MAJOR.MINOR.PATCH (^ and ~), standard commands via npm run, vulnerabilities via npm audit.

Running mini-case — Salim sets up his project in Algiers

Salim receives the startup's project: a folder with code but no package.json, and a colleague sends him node_modules as an attachment. He restarts cleanly: npm init to create the manifest, installing packages (dependencies vs devDependencies), start/dev/test scripts, .gitignore excluding node_modules, and a first npm audit revealing a vulnerable dependency to update. The project becomes installable with one command: npm install.

Last episode of case 1.1-1.3 — Salim equips his project after the language, asynchrony and modules.

1. package.json & dependencies: the manifest

npm gives access to the world's largest open-source registry: you install packages instead of coding everything. The heart of the project is package.json (name, version, dependencies, scripts), created with npm init. npm install express downloads into node_modules and adds to dependencies. Distinguish dependencies (production) from devDependencies (dev only, -D). package-lock.json locks exact versions (reproducibility); node_modules is not versioned (regenerable).

Salim runs npm init -y, installs the framework as a dependency and the restart tool as a devDependency: the project now installs with one npm install on any machine.

2. Semver, scripts & security

Semantic versioning (semver) follows MAJOR.MINOR.PATCH: major = breaking changes, minor = compatible new features, patch = bugs. ^4.18.2 allows minor/patch updates, ~4.18.2 patch only. Scripts (start, dev, test) run with npm run <nom> and standardise commands. And npm audit reports dependency vulnerabilities — to watch, since dependency flaws are a real risk.

Salim defines start, dev and test in his scripts and makes npm audit his reflex before each production release.

3. Choose packages without exposing yourself

The huge ecosystem is a strength (don't reinvent the wheel) and a risk (flaws, varying quality, abandoned packages). To choose: popularity (downloads, adoption), active maintenance (recent updates, handled issues), serious documentation, minimal scope (no big package for a trivial function). And for Git: version package.json + lock, never node_modules nor secrets (.env).

Salim checks downloads and the latest update before installing, and adds node_modules/ and .env to .gitignore from the first commit.

Common misinterpretation: “You must send node_modules to colleagues / version it” or “^ and ~ are decorative”. No. node_modules is huge, regenerable with npm install and sometimes platform-specific: share package.json + lock, never the folder. And ^ / ~ really control accepted updates — ignoring them exposes you to surprise version bumps (or conversely to never-fixed flaws).
Managing an npm project The recipe, not the result package.json Manifest:dependencies, scriptspackage-lock.json Exactversions (reproducibility)node_modules Installedpackages (not versioned)
The recipe, not the result
Text version of the diagram (SEO / screen readers / translation): 1) Initialise: Salim creates the manifest with npm init and declares dependencies (prod) and devDependencies (dev, -D). 2) Lock: the lock pins exact versions so each machine installs the same thing; node_modules stays out of Git. 3) Standardise and secure: start/dev/test scripts run via npm run, and npm audit before each release. Lesson: share the recipe (json + lock), regenerate the result (npm install).

🔎 Concrete example — 🔎 Concrete example — Initialise and install

The basic commands, in order.

npm init -y            # creates package.json
npm install express    # dependency (production)
npm install -D nodemon # devDependency (dev)
npm run dev            # runs the "dev" script
npm audit              # known vulnerabilities

Reading: -D marks dev tools; npm run launches the manifest's scripts.

Lesson: ignore node_modules and .env in .gitignore — a reflex from the first commit.

Section vocabulary

npm & the registry
Node's package manager, giving access to the world's largest open-source registry (hundreds of thousands of reusable libraries).

Simple example: The web framework installed by Salim instead of being recoded.

What it is not: recoding an HTTP router or database client yourself.

Reflex: look for the proven package before recoding.

package.json
The project manifest: name, version, dependencies, scripts, metadata. Created with npm init; the reference point of every Node project.

Simple example: Salim's package.json with start, dev and test.

What it is not: a code folder with no manifest, not cleanly installable.

Reflex: npm init from day one of the project.

dependencies vs devDependencies
dependencies: needed in production. devDependencies: useful in dev only (installed with -D). node_modules: folder of installed packages, not versioned, regenerable.

Simple example: The framework in dependencies, the restart tool in devDependencies in Salim's project.

What it is not: sending node_modules as an attachment to a colleague.

Reflex: -D for tools, Git ignores node_modules.

package-lock.json
File locking the EXACT installed versions; guarantees everyone installs rigorously the same versions (reproducibility).

Simple example: The lock making Salim's machine and production install the same thing.

What it is not: “it works on my machine” with different versions everywhere.

Reflex: version the lock, never edit it by hand.

semver & npm scripts
MAJOR.MINOR.PATCH versioning (^ allows minor/patch, ~ patch only). Scripts define reusable commands (npm run ).

Simple example: The ^ letting security patches through for Salim, and his npm run dev.

What it is not: versions frozen forever or different commands per developer.

Reflex: understand ^ / ~, standardise via scripts.

In practice — Hands-on — Manage a project with npm

  1. Initialise a project with npm init -y and examine the generated package.json (name, version, scripts).
  2. Install a package (npm install express) and a devDependency (npm install -D nodemon); observe node_modules, package.json and package-lock.json.
  3. Add scripts to package.json ("start", "dev") and run them with npm start / npm run dev.
  4. Understand semver (^ vs ~), ignore node_modules (.gitignore), and run npm audit to spot vulnerabilities.
You manage a Node project with npm: package.json, installing dependencies (prod vs dev), scripts, semantic versioning and security (audit) — the foundation of every project.

Ready-to-say script — set npm hygiene as a team (30 s)

“We version package.json and the lock, never node_modules — everyone regenerates with npm install. Dev tools go in -D, commands in scripts, and we run npm audit before each release.”

To say when starting the project; check .gitignore at the first commit.

Copy-paste template — minimal package.json + .gitignore

{
  "name": "projet-salim",
  "version": "1.0.0",
  "scripts": {
    "start": "node app.js",
    "dev": "nodemon app.js",
    "test": "jest"
  },
  "dependencies": {},
  "devDependencies": {}
}
// .gitignore:
// node_modules/
// .env

Project with no manifest

Like Salim: npm init -y, reinstall packages one by one distinguishing prod and -D, recreate scripts — never take someone else's node_modules.

Team in Algiers

Same start/dev/test scripts for everyone: each developer runs the same commands, no more “I used to do it differently”.

Careful version bump

Read what ^ and ~ allow before updating; test after each minor bump, lock via the lockfile.

Imminent release

npm audit before releasing: fix reported vulnerabilities, check that .env and node_modules are properly out of Git.

Caution: Never version secrets (.env, API keys, passwords): they stay out of Git via .gitignore. Before each release, run npm audit and fix reported vulnerabilities — dependencies are a real attack vector.

✓ Best practices

  • Version json + lock, never node_modules.
  • Dev tools in -D, commands in scripts.
  • npm audit before each release.

✗ Common pitfalls

  • Versioning node_modules.
  • Forgetting .env in .gitignore.
  • Ignoring npm audit alerts.

Key takeaways

  • npm gives access to the world's largest open-source registry: install packages instead of coding everything — a major accelerator.
  • package.json = manifest (dependencies, scripts); package-lock.json locks EXACT versions. node_modules NOT versioned (regenerable).
  • dependencies (production) vs devDependencies (dev, -D); SEMVER MAJOR.MINOR.PATCH (^ minor/patch, ~ patch).
  • npm SCRIPTS standardise commands; npm audit reports vulnerabilities (to watch).

48h challenge — apply tomorrow

Initialise a real project (template above): npm init -y, 1 package + 1 devDependency (-D), 2 scripts, .gitignore (node_modules, .env), then npm audit. 25 minutes is enough.

Section exit checklist
  • I can explain package.json, lock and node_modules.
  • I can tell dependencies, devDependencies and semver ^ / ~ apart.
  • I have a project installable via npm install + audited.
Self-assessment 1-5: does my project install with one command on another machine?are secrets and node_modules properly out of Git?

Frequently asked questions

What should be versioned (Git) in a Node project, and why not node_modules?

Version your code, package.json (the “recipe”: dependencies, scripts) and package-lock.json (exact versions, including sub-dependencies) — plus .gitignore, README and configs. Never version node_modules: it's huge (thousands of files), regenerable with npm install from both manifests, and sometimes platform-specific. Like Salim: share the recipe (json + lock), everyone regenerates the result. Also exclude secrets (.env), logs and temp files.

The npm ecosystem is huge: how to choose good packages?

Not reinventing the wheel is a major asset — but dependencies are also a risk (flaws, varying quality, abandonment). To choose: popularity (downloads, stars — a good signal), active maintenance (recent updates, handled issues), serious documentation, minimal scope (no big package for a trifle). Then manage: keep dependencies up to date (semver understood), watch npm audit, and prefer few proven dependencies over a myriad of unknowns.

Check your understanding

What should be versioned in Git for a Node project?

Additional resources (optional, to go further)

Level 1 examFresh, harder questions to test what you've learned