Node.js Cheatsheet
npm and Packages
Use this Node.js reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Essential npm Commands
# Initialize npm init # interactive npm init -y # accept all defaults # Install npm install # install from package.json npm install express # add dependency npm install -D jest # devDependency (--save-dev) npm install -g nodemon # global (avoid for project tools) npm install express@4 # exact major npm install express@~4.18 # patch range npm install express@^4.18 # minor range (default) # Remove npm uninstall express npm uninstall -D jest # Update npm update # update within semver ranges npm update express # update one package npm outdated # show outdated deps # Run scripts npm run dev npm test # shortcut for npm run test npm start # shortcut for npm run start # List npm list # dependency tree npm list --depth=0 # top-level only npm list -g --depth=0 # global packages # Info npm info express versions # all published versions npm view react peerDependencies
package.json Fields
{
"name": "my-app",
"version": "1.2.3",
"description": "A Node.js app",
"main": "dist/index.js",
"module": "dist/index.esm.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"require": "./dist/index.cjs"
}
},
"type": "module",
"engines": { "node": ">=18" },
"scripts": {
"dev": "node --watch src/index.js",
"build": "tsc",
"start": "node dist/index.js",
"test": "node --test",
"lint": "eslint src"
},
"dependencies": {
"express": "^4.18.0"
},
"devDependencies": {
"typescript": "^5.0.0"
},
"peerDependencies": {
"react": ">=17"
},
"optionalDependencies": {
"fsevents": "^2.3.0"
},
"private": true,
"license": "MIT",
"keywords": ["node", "tool"],
"author": "Name <email>",
"repository": { "type": "git", "url": "https://github.com/..." },
"files": ["dist", "README.md"],
"bin": { "mytool": "./bin/cli.js" }
}Version Ranges (Semver)
| Range | Meaning |
|---|---|
"1.2.3" | Exact version only |
"^1.2.3" | >=1.2.3 <2.0.0 — compatible minor/patch |
"~1.2.3" | >=1.2.3 <1.3.0 — patch only |
">=1.2.3" | Any version at or above |
"1.x" | Any 1.*.* |
"*" | Any version |
"1.2.3 - 2.0.0" | Inclusive range |
"^0.1.2" | >=0.1.2 <0.2.0 — 0.x is special: only patch |
npm Scripts
{
"scripts": {
"build": "tsc -p tsconfig.json",
"test": "node --test tests/**/*.test.js",
"lint": "eslint src",
"format": "prettier --write src",
"prebuild": "npm run lint",
"postbuild": "echo Build done",
"dev": "node --watch --env-file=.env src/index.js",
"start": "node src/index.js",
"clean": "rm -rf dist",
"prepare": "npm run build"
}
}# pre/post hooks: npm run <name> runs pre<name> → <name> → post<name> npm run build # runs: prebuild → build → postbuild # Pass extra args after -- npm test -- --reporter=tap # Environment in scripts # npm sets npm_package_* vars: npm_package_version, npm_package_name, etc.
npx
# Run a local binary (from node_modules/.bin) npx jest # Run without installing npx cowsay hello # Run specific version npx create-react-app@5 my-app # Force download (ignore local/cached) npx --yes create-next-app # Run in the context of a package npx -p typescript tsc --init
package-lock.json and Integrity
# lock file records exact resolved versions + content hashes # ALWAYS commit package-lock.json for apps; .gitignore it for libraries # Install from lock file only (CI-safe, fails if lock is out of date) npm ci # Rebuild native addons after Node update npm rebuild # Verify integrity of installed packages npm audit # security vulnerabilities npm audit fix # auto-fix (within semver range) npm audit fix --force # bump to latest even if breaking # Inspect why a package is installed npm why lodash npm ls lodash # same
Workspaces (Monorepo)
// root package.json { "private": true, "workspaces": ["packages/*", "apps/*"] }
npm install # installs all workspaces, hoists deps npm install -w packages/utils # install dep in specific workspace npm run test -w packages/utils # run script in workspace npm run build --workspaces # run in ALL workspaces npm run build --workspaces --if-present # skip if script missing npm exec -w packages/utils -- tsc # run binary in workspace
.npmrc
# .npmrc — per-project or ~/.npmrc (user) save-exact=true # pin exact versions (no ^ or ~) package-lock=true registry=https://registry.npmjs.org/ @myorg:registry=https://npm.pkg.github.com # scoped registry # Auth for private registry //npm.pkg.github.com/:_authToken=${GITHUB_TOKEN} # Proxy https-proxy=http://proxy.corp:8080
Publishing a Package
# Create account / login npm login npm whoami # Dry-run to see what will be published npm publish --dry-run # Publish npm publish npm publish --access public # required for scoped @scope/pkg # Tag releases npm publish --tag beta # consumers install with: npm install pkg@beta # Deprecate npm deprecate my-pkg@"<1.0.0" "Use 1.0+ instead" # Unpublish (within 72 hours) npm unpublish my-pkg@1.2.3
Node.js Built-in Test Runner (Node 18+)
// No dependencies needed import { test, describe, it, before, after, beforeEach, afterEach } from "node:test"; import assert from "node:assert/strict"; test("addition", () => { assert.equal(1 + 1, 2); }); describe("math", () => { it("adds", () => assert.equal(1 + 1, 2)); it("subtracts", () => assert.equal(3 - 1, 2)); }); // Async test test("async", async () => { const result = await fetchData(); assert.deepEqual(result, { id: 1 }); });
# Run tests node --test # discover *.test.js / test.js node --test tests/**/*.test.js # glob node --test --watch # re-run on change node --test --reporter=tap # TAP output