Terminal
$ npm run dev
Error: Cannot find module 'next'

The code is fine. Nothing is installed yet. Most of the failures in your first week are this category: the project is asking for something your machine does not have, in a folder it is not looking in.

The idea

The code you and your assistant write is a small fraction of what runs. The rest arrives as a few hundred , downloaded onto your machine by a such as npm or pnpm. Running the project means installing those, then starting a dev server that compiles your files and serves them to your browser at an address on your own computer.

text
  package.json            "next": "16.0.1", "react": "19.0.0"
        |
        |  npm install   (reads the list, writes the lockfile)
        v
  node_modules/           ~300MB of downloaded packages. Never committed.
        |
        |  npm run dev
        v
  dev server (a running program, holds your terminal)
        |
        v
  http://localhost:3000   localhost = this machine.  3000 = the port.

How it works

  • package.json lists what the project needs and defines the shortcut commands under scripts, so npm run dev runs whatever that project decided dev means.
  • The lockfile (package-lock.json for npm, pnpm-lock.yaml for pnpm) records the exact version of every package that was installed. It is committed to git so a second machine gets identical versions. node_modules/ is not committed, because it is rebuildable from those two files.
  • npm install downloads everything. npm install resend adds one new package and updates both files.
  • A keeps running until you stop it with Control+C. The terminal tab it occupies is busy for as long as it runs.
  • localhost means this computer, and the after the colon says which program to reach. Next.js defaults to 3000, Vite to 5173.

What to do

  1. Install once per project, in the project root: npm install (or pnpm install if the repo has a pnpm-lock.yaml). Mixing the two in one project produces two lockfiles and hours of confusion.
  2. Start it with npm run dev and open the address it prints. Leave that tab alone.
  3. When it fails, read the first error rather than the last. Everything below the first one is usually a consequence.
  4. Work through the five that catch everyone:
    • Cannot find module 'x'. You have not installed, or you are in the wrong folder. Run ls and check you can see package.json.
    • Port 3000 is already in use. An older dev server is still running. npx kill-port 3000, or start on another port with npm run dev -- -p 3001.
    • Unsupported engine or a syntax error inside node_modules. Your Node version is too old. node -v, then install the version the project's engines field asks for.
    • undefined where a key should be. A missing . Copy .env.example to .env.local and fill it in.
    • Changes that do not appear, or errors that survive a fix. A stale install or cache. Stop the server, delete node_modules and .next, install again.

Where it breaks

Working on your machine proves less than it feels like it proves. Your laptop has your Node version, your .env.local, your cached build, and a case-insensitive filesystem. A server has none of those. This is the real content of "it works on my machine", and it is why Chapter 5 spends a whole section on environments.

The dev server also lies in a useful direction. It rebuilds constantly, serves unminified code, and shows friendly errors, so it is faster and more forgiving than the production build. npm run build is the command that tells you the truth, and it is worth running before you promise anyone anything.