Watch This First
Everything on this page is a thing you do. This is the same material explained before you have to do it: what npm init actually writes, what npm install adds to the file without you typing, the four rules JSON insists on, and how a script gets added and run. This video runs for five and a half minutes.
Before You Start
You need a terminal open and Node installed. Running the command node --version will print a number rather than an error. Windows requires running Git Bash rather than PowerShell or Command Prompt because the quoting rules differ and the difference shows up later in a way that is genuinely hard to spot.
Everything below happens in a folder you are going to delete at the end. Nothing here is a deliverable.
Opening a terminal, if you have not before
That first line assumes you already know where to find one. Here is HAP opening the terminal built into VS Code, then answering the question that comes straight after it: which folder is that terminal standing in? This video runs for two and a half minutes.
Step 1: Make An Empty Folder And Stand In It
cd ~
pwd # see where home is
mkdir npm-practice
cd npm-practice
pwd # make sure you are in the practice folder The mkdir command makes the folder and cd moves the terminal into it. pwd prints where the terminal currently is, and it should end in npm-practice. Notice the # starts a comment.
That pwd command matters more than it looks. Every npm command acts on the folder the terminal is standing in, and it never asks whether that was the folder you meant. A lot of confusing npm behavior turns out to be a command that ran in the wrong place, either because it printed lines of errors or, just as bad, because it worked but in the wrong place.
Step 2: Create The package.json File
npm init -y Without -y, npm asks a series of questions. With it, npm accepts every default and writes the file immediately. You can open package.json and read it before going on.
{
"name": "npm-practice",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
} You can read the file out loud, field by field. The name came from the folder name. The package version is mostly relevant only when you plan to publish your module on a public repository. While required, it is usually ignored for other purposes like building websites. The scripts list holds one placeholder that does nothing useful. Notice how lists are bracketed by open and close curly braces.
The package.json reference page goes through every field properly.
The list of dependencies is missing because nothing has been installed yet.
Step 3: Install One Tool
npm install --save-dev http-server http-server is a small program that serves files over HTTP. The --save-dev flag files it as a development tool rather than something a visitor's browser needs.
Three things changed on disk.
npm-practice/
├── node_modules/ ← new, and very large
├── package.json ← changed
└── package-lock.json ← new You will see a devDependencies block naming http-server and its version when you open package.json again. Opening package-lock.json reveals thousands of lines describing every package that came down, including the ones http-server depends on that you never named. The node_modules folder contains dozens of subfolders for this single tool.
🟠 A message about vulnerabilities is not a failure
npm often ends an install by reporting a number of known vulnerabilities. That is a report about the packages, not an error in what you typed. The install finished. Whether any of those findings matter depends on whether the affected code ever runs in a place that handles untrusted input, which for a local development tool is usually no.
Step 4: Write A Script
An installed tool is not on your system path. Typing http-server by itself will most likely report that the command was not found. npm scripts exist to solve exactly this: inside a script, npm looks in node_modules first.
You can open package.json to find and replace the scripts block with this code.
"scripts": {
"serve": "http-server -p 3000"
}, You must save the file, since forgetting to do so produces a Missing script: "serve" error on the next command. This is the single most common mistake in this exercise.
Step 5: Run It
npm run serve Starting up http-server, serving ./
Available on:
http://127.0.0.1:3000
http://192.168.1.14:3000
Hit CTRL-C to stop the server The terminal stops and sits there, which is correct even though it is new behavior you may never have seen before. Most terminal commands run, print something, and give you your prompt back. A server never finishes, because finishing would mean it stopped serving, so it holds the terminal until you stop it.
You can visit http://127.0.0.1:3000 in a browser. Because there is no HTML file in this folder, you will see a file listing generated by the server. You can stop the server and return to the prompt by pressing Ctrl and C in the terminal.
The page on dev servers covers what the port number is doing and why any of this is necessary.
Step 6: Chain Two Commands
A script can run other scripts, and commands can be strung together. You can replace the scripts block again.
"scripts": {
"list": "ls > files.txt",
"serve": "http-server -p 3000",
"start": "npm run list && npm run serve"
}, npm run start Two characters in there are special shell characters.
The greater-than sign
ls > files.txt takes what ls would have printed to the screen and writes it into a file instead. This is called redirection. It overwrites the file every time. Two of them in a row, >>, appends rather than overwrites.
The double ampersand
a && b means run a, and run b only if a succeeded. Success is measured by the exit code, a number every command returns when it finishes, where zero means fine. A chain stops at the first failure instead of carrying on with broken input.
Once you stop the server, opening files.txt reveals the folder listing written by the first half of the chain before the second started.
Step 7: Throw It Away
cd ~ # get back to your home directory
ls npm-practice && rm -rf npm-practice # make sure npm-practice is there This folder is meant to be deleted at the end as everything there was just practice.
What To Take Away
The terminal's current folder decides everything
npm acts on wherever the terminal is standing. A quick check with pwd before installing costs one second and heads off a whole class of confusion.
Read package.json after every command that touches it
The file is short, and it is the record of what you did. You can learn what each command does by watching the file change after each step.
Save before you run
A script not running usually means the editor still holds unsaved changes.
A server holding the terminal is correct behavior
It has not hung. You can open a second terminal tab if you need one, and stop the server with Ctrl and C when you are done.
Scripts are shell, not JavaScript
The contents of a script line are handed to your shell. && and > are shell features, which is why the choice of terminal on Windows matters.