What npm scripts do

A package.json file describes a Node.js project. Its scripts field is a collection of named commands that you can run from a terminal. Instead of remembering a command such as node app.js, you can give it a name such as start. Scripts are useful for repeated tasks: starting an application, running checks, building files, or preparing a project for release.

For this example, you need Node.js 18 or newer and npm 9 or newer, plus a text editor and a terminal. Check your installed versions with node -v and npm -v. The example uses only features built into Node.js, so there are no packages to install. If either command is unavailable, install Node.js before continuing.

Create a small project

Make a new folder, open a terminal in that folder, and run npm init -y. This creates a package.json file with default values. Open the file and add or replace its scripts field so it contains "start": "node app.js" and "check": "node check.js". Scripts must sit inside one scripts object; keep the other package.json fields that npm created.

Create app.js in the same folder with this JavaScript: function greeting(name) { return `Hello, ${name}!`; } module.exports = greeting; if (require.main === module) { console.log(greeting("workshop")); } When you run the file directly, it prints a greeting. When another file imports it, it provides the greeting function without printing.

Create check.js beside it with this JavaScript: const assert = require("node:assert/strict"); const greeting = require("./app.js"); assert.equal(greeting("Ada"), "Hello, Ada!"); console.log("Check passed"); This is a small automated check, not a full test suite. It compares the function’s result with an expected value and reports an error if they differ.

Run and understand the commands

From the project folder, run npm start to execute the start script. You should see Hello, workshop! Then run npm run check to execute the check script. You should see Check passed. The general form is npm run followed by the script name. Run npm run by itself to see the scripts available in the current project.

The words on the left of each script entry are names you choose; the strings on the right are commands your terminal environment will execute. npm start is a shortcut for npm run start. You can name other tasks according to their purpose, such as build or lint, but a name alone does not provide that functionality. Its command must point to a program or file that exists.

Many projects use scripts to invoke tools installed as project dependencies. npm makes those tools’ command-line programs available to scripts, so a script can often call a tool by its command name rather than by a path into node_modules. For a project you have received from someone else, install its declared dependencies before expecting such scripts to work.

Keep scripts clear and portable

Choose names that describe outcomes, and keep each command understandable. A short script such as "check": "node check.js" is easier to inspect than a long chain of unrelated steps. If a task grows, move its logic into a separate file and have the script run that file. Other contributors can then find both the entry point in package.json and the implementation it calls.

Remember that npm scripts run through a shell. Shell syntax and commands can differ across operating systems: a command that sets an environment variable or copies a file on one system may not work on another. Using Node.js files for more involved tasks can reduce those differences. Be cautious with scripts from unfamiliar projects, because running a script executes the command it contains.

Troubleshoot a script that will not run

First, confirm that your terminal is in the folder containing the intended package.json. Then check the script name: npm run checks will not find a script named check. If npm reports that it cannot find app.js or check.js, confirm the filename and its location relative to the project folder.

If package.json cannot be read, inspect its JSON syntax. Property names and string values need double quotes, entries need commas between them, and the final entry in an object must not have a trailing comma. If a check fails with an assertion error, read the expected and actual values and inspect the code being checked. A failing check can be useful: it tells you where the project’s behavior no longer matches its expectation.

Back to category ↗