Skip to content

Fix: npm ERR! Missing script: "start"

FixDevs · (Updated: )

Part of:  JavaScript & TypeScript Errors

Quick Answer

How to fix "npm ERR! Missing script" for start, dev, build, and test. Covers adding scripts to package.json, common framework configurations for React, Next.js, Vite, Angular, Express, and Nest.js.

The Error

You run npm start and get:

npm ERR! Missing script: "start"
npm ERR!
npm ERR! To see a list of scripts, run:
npm ERR!   npm run
npm ERR! A complete log of this run can be found in: ...

The same error shows up with other script names:

npm ERR! Missing script: "dev"
npm ERR! Missing script: "build"
npm ERR! Missing script: "test"

A related error you might see after fixing the script definition:

sh: react-scripts: command not found

All of these mean the same thing: npm can’t find or can’t execute the script you’re trying to run.

Why This Happens

npm scripts are defined in the scripts object of your package.json. When you run npm start, npm looks for a "start" key in that object. If it’s not there, you get this error.

The most common reasons:

  • The script doesn’t exist in package.json. You cloned a repo or followed a tutorial that assumes a script is defined, but your package.json doesn’t have it.
  • You’re in the wrong directory. You ran npm start in a parent folder or subfolder that has its own package.json (or none at all) instead of the project root.
  • You used the wrong command. Some frameworks use npm run dev instead of npm start, or npm run build instead of npm build. The difference matters.
  • Dependencies aren’t installed. The script exists but references a binary (like react-scripts or vite) that isn’t in node_modules because you haven’t run npm install.

There is also a behavior most developers never notice. npm v6 used to provide an implicit start fallback. If your package.json had no start script but a server.js file existed at the project root, npm start would run node server.js as a default. This was useful for tiny scripts but masked many bugs by making npm start “just work” without an explicit definition. The implicit fallback was removed in newer behavior — modern npm requires every script you call to exist in the scripts object. If you are following a tutorial written for npm v6 and the example skips defining start, the same project will throw “Missing script: start” on npm v7 and later.

Version history: npm scripts then and now

The way npm executes scripts has changed across major releases, and the differences are worth knowing when you debug. npm v6 ran scripts through a small wrapper that on Windows often invoked cmd.exe and on POSIX systems used /bin/sh. npm v7 and v8 reworked the underlying spawn behavior so that quoting, environment inheritance, and exit code propagation became more consistent across platforms. npm v9 dropped support for older Node.js versions and removed the npm-run-all-style implicit chaining hacks that some early projects depended on. npm v10 (bundled with Node.js 20+) tightened script execution further — npm run now uses --workspaces more strictly and refuses to silently fall through to a parent package.json when a workspace lacks the script.

A few practical consequences of this history:

  • Scripts that worked in npm v6 by chance (“it ran because start happened to default to node server.js”) will fail on v7+. Add an explicit "start" script.
  • Scripts that relied on shell features like &&, ||, or environment variable expansion ($VAR) behaved differently on Windows in npm v6 because cmd.exe does not parse those the same way. Newer npm versions use cross-spawn semantics that are closer but still not identical. If you need cross-platform scripts, install cross-env and avoid shell-specific syntax.
  • Lifecycle scripts (prestart, poststart, preinstall, etc.) are still supported but npm v7+ no longer runs them for arbitrary script names — only for the documented lifecycle keywords. A pre<custom> script you wrote for npm v6 may be silently ignored on v10.

Fix 1: Add the Missing Script to package.json

Open your package.json and add the script you need under the "scripts" object.

Here are the correct scripts for the most common setups:

React (Create React App):

{
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test"
  }
}

Next.js:

{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  }
}

Note: In Next.js, npm run dev starts the development server. npm start runs the production server (requires npm run build first).

Vite (React, Vue, Svelte):

{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  }
}

Angular:

{
  "scripts": {
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test"
  }
}

Express / plain Node.js:

{
  "scripts": {
    "start": "node server.js",
    "dev": "node --watch server.js"
  }
}

Replace server.js with your entry file (index.js, app.js, etc.). The --watch flag (Node.js 18.11+) restarts the server on file changes. If Node.js can’t find your entry file, see Fix: Error Cannot find module. For older Node.js versions, use nodemon:

{
  "scripts": {
    "start": "node server.js",
    "dev": "nodemon server.js"
  }
}

Nest.js:

{
  "scripts": {
    "start": "nest start",
    "start:dev": "nest start --watch",
    "build": "nest build",
    "test": "jest"
  }
}

Common Mistake: Running npm dev or npm build instead of npm run dev or npm run build. Only start and test work without the run keyword. Every other custom script requires npm run <name>.

Fix 2: Check You’re in the Right Directory

This is more common than you’d think. If your project structure looks like this:

my-project/
├── package.json      ← this one might be empty or a monorepo root
├── frontend/
│   └── package.json  ← the scripts are here
└── backend/
    └── package.json

Running npm start from my-project/ will use the root package.json, which probably doesn’t have the script you want.

Navigate to the correct directory first:

cd frontend
npm start

Verify you’re in the right place by checking which package.json npm sees:

cat package.json | head -20

You should see the project name and the scripts you expect.

Fix 3: Install Dependencies First

If your package.json has the script defined but you get an error like:

sh: react-scripts: command not found
sh: vite: command not found
sh: next: command not found

The script exists, but the binary it references isn’t installed. Run:

npm install

This installs all dependencies listed in package.json and puts their CLI binaries in node_modules/.bin/. When npm runs a script, it adds node_modules/.bin to the system PATH, so commands like react-scripts, vite, and next work without a global install.

If npm install itself fails, you may have a separate dependency issue — see Fix: npm ERR! ERESOLVE unable to resolve dependency tree.

Fix 4: Use the Correct Script Name

npm has a few built-in shortcuts, but most script names require npm run as a prefix. This is a common source of confusion.

Scripts that work without run:

npm start       # runs the "start" script
npm test        # runs the "test" script

Scripts that require run:

npm run dev     # runs the "dev" script
npm run build   # runs the "build" script
npm run lint    # runs the "lint" script

A common mistake is running npm dev or npm build instead of npm run dev or npm run build. Without run, npm treats these as built-in npm commands (which do something completely different), not your custom scripts.

To see all available scripts in your project:

npm run

This lists every script defined in your package.json along with its command.

Pro Tip: Run npm run (with no arguments) to list all available scripts in your project’s package.json. This instantly shows you what commands are available and saves you from guessing whether to use start, dev, or serve.

Common Framework Scripts Reference

FrameworkDev ServerProduction BuildStart (Production)Test
Create React Appnpm startnpm run buildServe build/ dirnpm test
Next.jsnpm run devnpm run buildnpm startnpm test
Vitenpm run devnpm run buildnpm run previewnpm test
Angular CLInpm startnpm run buildServe dist/ dirnpm test
Expressnpm run devN/Anpm startnpm test
Nest.jsnpm run start:devnpm run buildnpm startnpm test

Note: “Serve build/ dir” and “Serve dist/ dir” mean the framework produces static files. You serve them with a static file server (e.g., npx serve build) or deploy them to a hosting provider. There’s no built-in npm start for production in those cases.

Still Not Working?

node_modules/.bin is missing the binary

Even after npm install, the binary might be missing from node_modules/.bin/. This can happen if the install was interrupted or the package’s bin field is misconfigured.

Delete node_modules and reinstall:

rm -rf node_modules package-lock.json
npm install

On Windows (Command Prompt):

rmdir /s /q node_modules
del package-lock.json
npm install

Use npx as an alternative

If you need to run a command once without adding it to your scripts, use npx:

npx vite
npx next dev
npx react-scripts start

npx looks in node_modules/.bin first, then downloads the package temporarily if it’s not found. This is useful for quick testing or when you don’t want to modify package.json.

Check package.json for syntax errors

A malformed package.json can cause npm to silently ignore your scripts. Validate it:

npm pkg get scripts

If this returns {} but you know you added scripts, your package.json has a syntax error. Common mistakes:

  • Trailing comma after the last entry in an object
  • Missing quotes around keys or values
  • Missing comma between entries

Run npx jsonlint package.json or paste it into a JSON validator to find the exact problem.

Monorepo: you’re in the wrong workspace

In monorepo setups with npm workspaces, Yarn workspaces, or pnpm workspaces, each workspace has its own package.json with its own scripts. Running npm start from the root won’t run a workspace’s script unless you specify it:

npm start --workspace=packages/frontend

Or navigate into the workspace directory:

cd packages/frontend
npm start

If you’re using Turborepo or Nx, use their CLI instead:

npx turbo run dev
npx nx serve my-app

package.json has no scripts object at all

If you initialized a project with npm init -y and never added scripts, your package.json only has the default "test" script (which just prints an error). Make sure your environment variables are also configured before running your app. Add the scripts object manually or re-scaffold with your framework’s CLI:

npx create-react-app my-app
npx create-next-app my-app
npm create vite@latest my-app

Mismatched npm and Node.js versions

If you upgraded Node.js but still have an old npm binary on your PATH (or vice versa), script execution can behave inconsistently. Check both:

node --version
npm --version

Node.js 18 ships with npm 9, Node.js 20 ships with npm 10, and Node.js 22 ships with npm 10 as well. If you see npm 6.x on a machine running Node.js 20, you have a stale npm somewhere on your PATH — usually a leftover from a global install. Reinstall Node.js from the official installer (or your version manager) so npm comes from the same bundle. If the binary itself is missing or node resolves to the wrong path, the underlying problem may be a missing module error.

Script silently fails on Windows due to shell differences

A script that works on macOS or Linux can fail on Windows even when the script exists in package.json. Common causes:

  • Inline environment variables: "start": "NODE_ENV=production node server.js" does not work in cmd.exe. Use cross-env: "start": "cross-env NODE_ENV=production node server.js".
  • Path separators: hard-coded / paths inside scripts can break when npm spawns a child process under cmd.exe. Use Node.js code or the path module to build paths instead of shell strings.
  • Long PATH on Windows can also cause node_modules\.bin entries to be cut off. Move your project closer to the drive root if you see “is not recognized as an internal or external command” for binaries that exist in node_modules\.bin.

Yarn or pnpm projects run with npm by mistake

If a project’s package.json is set up for pnpm or Yarn workspaces and you run npm start from the root, npm may pick up the wrong package.json or miss the workspace’s start script entirely. Check packageManager in package.json:

{
  "packageManager": "[email protected]"
}

If that field is set, use the matching CLI (pnpm start, yarn start) instead of npm start. Running npm in a pnpm workspace can also corrupt the lockfile — see Fix: npm ERR! ERESOLVE unable to resolve dependency tree if that happens.


Related: If npm install fails with dependency conflicts, see Fix: npm ERR! ERESOLVE unable to resolve dependency tree. For module resolution problems inside Node.js itself, see Fix: Error Cannot find module and Fix: Vite Failed to Resolve Import for bundler-level import errors.

F

FixDevs

Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.

Was this article helpful?

Related Articles