Chrome's JavaScript engine is called V8. Ryan Dahl lifted it out, dropped the page, the DOM and the security sandbox, and bolted on the things a browser deliberately withholds: files, network ports, processes. He called it Node.
Same language. Different room. Click each line to run it, then flip the switch and run it in the other room.
A package is a folder with a package.json in it. Publishing means uploading the folder. Installing means downloading it into node_modules/, where import knows to look.
That's genuinely all it is. Install one.
Install next and you get next. But next depends on styled-jsx, postcss, @swc/helpers, sharp… and each of those depends on more. npm walks the whole graph and downloads all of it. (react isn't on that list: next expects you to install it yourself, which is why the command has three names.)
This is why node_modules is the heaviest object in the universe, and why it's in .gitignore: you never commit it, you regenerate it from the list.
package.json is the app's ID card. And npm run dev just reads it.Click any highlighted key on the right. In particular, look at scripts: npm run dev is not magic. It looks up the string under "dev" and runs it in a shell.
npm run build actually execute?The string. next build, in a shell, with node_modules/.bin on the path.
That's why you can rename scripts freely, why npm run with no name lists them, and why a broken build is almost never npm's fault: it's whatever command is under that key.
^19.0.0 means "19-point-anything". The lockfile pins the exact one.package.json says what you're okay with. package-lock.json (or pnpm-lock.yaml, bun.lock) records what you actually got, down to the byte hash, for every package in the graph.
Commit the lockfile. Run npm ci on the server. Every machine gets the identical thousand folders. Delete it and two laptops can quietly diverge.
Try it: publish a new zod, then install on the server, with and without the lockfile.
With the lockfile: identical.
When you deploy a Next.js app, what runs on Vercel or your VPS is a Node process listening on a port. Your server components, server actions and API routes all execute inside it.
But there's a snag. Your files end in .tsx. Node can't read those. Neither can the browser.