Every Node project has a `package.json` describing its name, version, entry point, scripts and dependencies. `npm install` reads it, resolves the dependency tree, and writes a `package-lock.json` pinning exact versions for reproducible installs.
json
{
"name": "rpc-proxy",
"version": "1.0.0",
"main": "index.js",
"scripts": { "start": "node index.js", "test": "node --test" },
"dependencies": { "express": "^4.19.0" },
"devDependencies": { "vitest": "^1.0.0" }
}`dependencies` ship to production; `devDependencies` (linters, test runners, bundlers) do not. `npm run <script>` executes anything under `scripts`, and `npm ci` installs strictly from the lockfile — the command CI pipelines should use.