JS Sketchbooksee JavaScript think ✏️
← back to phase 8

8.2 — npm & package.json

Yesterday your files shared code with each other. Today the walls come down further: npm lets your project import code written by strangers — about two million packages of it, including Playwright itself. One command installs a package; one small file, package.json, keeps the records.

This file is the first thing you’ll open in every project at work. By the end of this lesson — and the 8.6 checkpoint — you’ll read one like a mechanic reads an engine plate.

watch it happen
// in the terminal:
//   npm install @playwright/test

// package.json — the project's ID card
{
  "name": "shop-tests",
  "version": "1.0.0",
  "scripts": {
    "test": "playwright test"
  },
  "devDependencies": {
    "@playwright/test": "^1.44.2"
  }
}

The problem first: your test project needs a runner, readable console colors, maybe date handling. Writing all of that yourself would take months — and strangers have already written, tested, and polished each piece.

shop-testsname · version 1.0.0scripts: testdevDeps: ^1.44.2package-lock.jsonnode_modules/ 📦📦📦the npm registry@playwright/testvitestreactlodashchalkexpress…and ~2,000,000 moreyou need a test runner, a color tool, a date library… strangers alreadywrote each one
under the hood

The deeper story, with the real names for things — this part is what turns “I saw it” into “I can explain it.”

Semver is a promise, not physics: package authors sometimes ship a breaking change in a “minor” by accident. The lockfile is your seatbelt — nothing changes until you deliberately update.

On CI servers you’ll usually see npm ci instead of npm install: it installs exactly what the lockfile says and fails loudly if package.json and the lockfile disagree. Reproducible installs are the foundation reproducible test runs stand on.

Your two devDependencies quietly pull in dozens of packages of their own — the dependency graph from 8.1 again, now stretching across the internet. That’s also the caution: anyone can publish to npm, so professionals install well-known names and watch for typos (playwrite is not playwright).

And the running joke you’ll meet on day one: node_modules as “the heaviest object in the universe” — the meme exists because a modest project can easily download hundreds of megabytes of dependency code. Now you know exactly which file to blame, and why it’s regenerable.

your turn

⌨️ read a package.json like a tool would

npm itself is just a program reading this file. Build a tiny reader: count the dev tools, then list the available script names.

requirements:

  • Create pkg: an object with name set to "shop-tests", a scripts object holding test: "playwright test" and report: "playwright show-report", and a devDependencies object holding "@playwright/test": "^1.44.2" and "vitest": "^1.6.0".
  • Print how many packages sit in devDependencies — count its keys (4.8 gave you the tool).
  • Then print each script NAME (not its command), one per line, in the order written — loop over the keys.

when you press RUN, the console must show exactly:

2
test
report

✏️ Quick check 1

package.json says "vitest": "^1.6.0". Can npm install give you vitest 2.0.0? Type yes or no.

✏️ Quick check 2

Which file records the EXACT versions actually installed — package.json or package-lock.json?

✏️ Quick check 3

The scripts field has "test": "playwright test". What do you type in the terminal to run it (starting with npm)?

teach it back

🗣️ Now teach it back

Explain to a friend what happens when you run npm install @playwright/test — name the three effects — and then what ^1.44.2 permits and why the lockfile exists anyway.

Write it as if your friend is sitting next to you. Saved to your journal — future-you will use these notes to teach others.

a few sentences, minimum — you’ve got this
to remember
npm = the public registry of packages (versioned modules). npm install downloads to node_modules/, records in package.json, pins in package-lock.json — one command, three effects.
Semver: MAJOR.MINOR.PATCH = breaking · new-but-safe · fixes-only. ^ allows minor+patch, ~ allows patch only, bare = exact. The lockfile pins what you actually got.
scripts = the project’s named commands (npm run test). Test tools live in devDependencies — the shipped app doesn’t need them, you do.
next: 8.3 Debugging like a pro →