Phase 1 · Node.js FoundationsModule 5~40 min read

npm, Dependencies & Scripts

Create repeatable projects, install third-party packages safely, understand semantic versions, and automate common tasks with npm scripts.

What you'll learn

npm makes a Node.js project repeatable: package.json records its contract, the lockfile captures an exact dependency graph, and scripts give every contributor the same commands.

By the end of this lesson, you'll be able to:

  • Create and read a package.json file
  • Separate production dependencies from development tools
  • Interpret semantic-version ranges and preserve the lockfile
  • Automate repeatable development tasks with npm scripts

Core mental model

Node.js becomes easier when you separate the JavaScript language from the runtime and the operating-system capabilities it exposes. Use this table as a decision guide.

ConceptWhat it meansDecision rule
package.jsonProject metadata, scripts, module mode, and dependency rangesCommit it as the human-maintained project contract
package-lock.jsonThe exact resolved dependency treeCommit it for applications so installs are reproducible
Semantic versionmajor.minor.patch communicates compatibility intentReview major upgrades; test every dependency update
npm scriptA named project command run in a predictable package contextGive common checks short stable names such as test and start

Professional workflow

Build and verify Node.js programs from the terminal in small, observable steps.

  1. Initialize the project and inspect every generated field.
  2. Declare the supported module format and Node.js engine range.
  3. Install runtime libraries as dependencies and build/test tools as devDependencies.
  4. Commit package.json and package-lock.json together.
  5. Create scripts for start, development, tests, and validation.
  6. Review package source, maintenance, license, size, and security before adoption.

Keep the feedback loop short

Run the smallest useful command after every meaningful change. Read the complete error message before editing again, and keep inputs and outputs visible while you learn.

Guided code lab

Initialize and inspect a project

npm init creates the package contract. npm pkg set provides a scriptable way to update common fields.

Terminal
mkdir node-course-lab
cd node-course-lab
npm init -y
npm pkg set type=module
npm pkg set engines.node=">=22"
npm pkg set scripts.start="node src/app.js"

Read the project contract

Scripts describe common operations. Dependencies belong to the running app; devDependencies support development and verification.

package.json
{
  "name": "node-course-lab",
  "version": "1.0.0",
  "private": true,
  "type": "module",
  "engines": { "node": ">=22" },
  "scripts": {
    "start": "node src/app.js",
    "check": "node --check src/app.js",
    "test": "node --test"
  }
}

Install deliberately and run shared scripts

Use a development dependency for tooling. npm ci uses the committed lockfile and is the usual clean-install command in automation.

Terminal
npm install dotenv
npm install --save-dev eslint
npm run check
npm test
npm ci
npm audit

Production practice

Review packages

A tiny dependency can carry a large transitive graph. Check ownership, release history, license, and whether the feature belongs in your own code.

Keep the lockfile

Commit lockfile changes with dependency changes and review unexpected transitive updates.

Automate checks

CI should use the same npm scripts developers run locally so there is one shared definition of success.

Common failure mode

Deleting the lockfile whenever an install fails hides the real dependency problem and allows the entire graph to drift. Diagnose the mismatch before regenerating it intentionally.

Independent workshop

Turn your runtime-report program into a documented npm project with predictable setup, start, check, and test commands.

Your finished workshop must include:

  • A complete package.json with type and engines
  • At least four useful scripts
  • One justified runtime or development dependency
  • A committed lockfile and setup section in README

Definition of done

Run the happy path and at least two edge cases, keep responsibilities separated, and add a short README explaining how to run the program.

Recap & quick check

Key takeaways

  • package.json is the project contract
  • The lockfile records exact resolutions
  • Semantic versions communicate compatibility intent
  • Production and development dependencies serve different roles
  • npm scripts standardize workflows

Quick check

1. Where should a library required by the running application be listed?

2. What does a major semantic-version change normally signal?

3. Why commit package-lock.json for an application?

4. Which command is designed for a clean lockfile-based install?

Next: Files, Paths & Essential Core APIs