npm vs npx: which one do you type, and why?
In one sentence:npm installs and manages the packages your project keeps; npx runs a package's command once, using your project's copy if it exists or downloading one to npm's cache if it doesn't.
What it actually is
npm and npx ship together and sit one letter apart, which is the whole problem: they do different jobs. npm is the package manager. It downloads packages, records them in package.json, and stores the code in node_modules so your app can import it. npx is the runner. It executes the command a package provides, and it works whether or not that package is installed in your project.
Think of a hardware store. npm install is buying the drill: it goes in your toolbox (node_modules), it’s on the receipt (package.json), and it stays until you remove it. npx is renting the carpet cleaner for an afternoon. You use it, hand it back, and your toolbox is unchanged.
npx follows one rule: local copy first. If the tool already exists in your project’s dependencies, npx runs that exact version from node_modules. If it doesn’t, npx asks permission, downloads the package to npm’s cache, runs the command, and leaves your project untouched. Under the hood, npx has been a thin wrapper around npm exec since npm 7, so when your agent uses that command instead, it’s the same machinery.
| You type | What it does |
|---|---|
npm install stripe | Adds Stripe to package.json and node_modules so your code can import it |
npx create-next-app@latest | Downloads the Next.js scaffolder, runs it once, adds nothing to your project |
npm run dev | Runs the dev script defined in your package.json |
npm create astro@latest | npm shortcut that runs the create-astro package, npx-style |
Why your AI just did this
Your agent picks based on whether your project needs to keep the tool. At project start, it reaches for npx and one-off scaffolders: npx create-next-app@latest is the official Next.js setup command, and most “create-something” tools follow the same pattern. At deploy time it may run npx vercel instead of installing the Vercel CLI on your machine. These are tools you use for a moment. Your app never imports them.
The moment your app needs a capability at runtime (charging cards, sending email, talking to a database), the agent switches to npm install, because that code has to exist every time your app runs, on your laptop and on the server. What that command does to your project is covered in npm, node_modules and package.json.
You’ll also see a third spelling: npm create astro@latest. Not a typo. npm create is an alias for npm init, and npm translates npm create astro into a run of the create-astro package. Same idea as npx: fetch a setup tool, use it once, move on.
When you’ll run into it
The classic mixup is typing npm create-next-app because the tutorial said npx create-next-app. npm replies with Unknown command: "create-next-app", since npm only understands its own subcommands (install, run, init, and friends). The reverse mixup, npx install stripe, is weirder: npx assumes install is the name of a package you want to run, which is nothing like what you meant.
Then there’s npx’s permission prompt. When the tool isn’t in your project, npx prints something like Need to install the following packages: create-next-app@16.x and waits at Ok to proceed? (y). That’s the rental desk asking for a signature, and it deserves a glance before you press y.
The sneakiest version is command not found. You type astro dev or next build bare, the terminal shrugs, and yet the package sits right there in node_modules. Locally installed commands live in node_modules/.bin, a folder your PATH doesn’t know about. Run them through npx (npx astro dev) or through a script (npm run dev), because npm run adds node_modules/.bin to the PATH while the script runs. What dev and build themselves mean is its own entry: build vs dev.
What to check
- Copy commands exactly as the tutorial or your agent writes them; npm and npx differ by one letter and are not interchangeable
- Read the
Ok to proceed?prompt before pressingy, and confirm the package name matches what you expected, character for character. A typosquatted name runs someone else’s code the moment npx fetches it - Prefer
npm run <script>for your project’s own commands (dev,build); thescriptsblock inpackage.jsonis the project’s official way to run itself - Keep the version tag when the official command has one (
npx create-next-app@latest); a bare name runs whatever version your project already has, and the@latesttag forces the current release - Check
package.jsonwhen npx behaves oddly; if the tool is listed there, npx runs your project’s version, whatever the tutorial assumed
Say it like a dev
Instead of: “the tutorial’s command doesn’t work” Say: “I ran npm create-next-app and got Unknown command. Should it be npx create-next-app@latest?”
Instead of: “put the deploy tool on my computer” Say: “Run it with npx vercel so we skip the global install”
Instead of: “it says astro is not a command” Say: “The astro binary is local to this project, so it’s not on my PATH. Run npx astro dev or npm run dev instead.”
People actually ask
“What is the difference between npm and npx?”
npm is the package manager: it installs and manages the packages listed in your package.json, storing the code in node_modules. npx is a runner that ships with npm: it executes a package's command, preferring the copy already installed in your project and downloading one to npm's cache when there isn't one. Install what your app imports with npm; run one-off tools with npx.
“Do I need to install npx separately?”
No. npx comes with npm, and npm comes with Node.js, so a single Node install gives you all three. If your terminal says npx isn't found, your Node install is very old or broken, and reinstalling the current version from nodejs.org is the fix.
“Why do tutorials say npx create-next-app instead of npm install create-next-app?”
Because create-next-app is a setup tool, not code your app needs while it runs. npx downloads it, runs it once to generate your project folder, and keeps it out of your package.json. Installing it with npm would add a dependency you'd never touch again.
Related terms
Checked against
Just met this in a real session? Glim reads it in plain words.
Paste what your agent just did, a git diff, your terminal, or its summary, and Glim tells you what changed and what to check before you ship. Nothing stored.
Explain my session →