Check an npm package before you install it
Installing a package runs its code. So the thirty seconds you spend looking at it beforehand are the only thirty seconds where you're still in control. Here's what I actually check, and the commands for each.
npm install can run code from the package, on your machine, before you import anything. So "I'll just try it and see" isn't a safe position.
This is the check I run on anything I haven't used before. It takes well under a minute.
1. Is it the package you think it is?
npm view express
You get the description, the latest version, the maintainers and the repository URL. Read the repo link. If a package claiming to be a popular library points at a GitHub repo with four stars, or has no repo at all, stop there.
Then check the download count on npmjs.com. A package that millions of projects depend on has the numbers to match. A lookalike has a few hundred.
2. When was it published?
npm view express time.modified
npm view express time.created
Created last week and claiming to be a well-known library is the single strongest signal you'll get. Typosquats are new, because the real one took the name years ago.
3. Does it run anything at install?
This is the one that matters most and almost nobody checks.
npm view express scripts
If you see preinstall, install or postinstall, that package executes something when you install it. That's not automatically bad. Native modules genuinely need it, and so do tools that fetch a binary.
But for a small utility library, a postinstall is a question worth asking.
4. Read it before you run it
You can download the tarball without installing it, which means nothing executes:
npm pack express
tar -tzf express-*.tgz # list the files
tar -xzf express-*.tgz # extract it
Then look at package/package.json, and at whatever the scripts point to.
For a small package this is genuinely quick. You're looking for anything that reads environment variables, writes outside the package directory, or makes network calls at install time.
5. If you're not sure, install it without the scripts
npm install some-package --ignore-scripts
If the package works fine like that, it never needed them.
Honestly, this is worth doing as your default:
npm config set ignore-scripts true
It will break things. Native modules won't build. The fix is to find the few packages that genuinely need a build step and run those deliberately. What you get in exchange is that a typo becomes a failed build instead of a quiet compromise, and a failed build is a thing you notice.
What this doesn't cover
A package you've correctly used for three years, whose maintainer account got compromised last Tuesday.
Every check above passes. The name is right, the downloads are real, the repo is real, the history is long. That's what happened with event-stream and with ua-parser-js, and no amount of pre-install inspection catches it.
The thing that helps a bit there is not taking new versions on the day they ship. Renovate and Dependabot both support a delay of a few days. Most of these incidents are found within hours by somebody else, so a short cooling-off window catches a surprising share of them.
The short version
npm view <pkg> # repo, maintainers, latest
npm view <pkg> time.created # how old
npm view <pkg> scripts # does it run anything
npm pack <pkg> # read it without running it
Four commands. Less time than it takes the install to finish.
If you want the longer argument about why install-time execution is the real problem, that's here. And the lookalike-spotting gets faster with practice, which is what one of the formats in the daily drill is for.