NoNode.js · Lesson 4 of 7

Modules & npm

Node's module system lets you split code across files. npm (Node Package Manager) gives you access to millions of packages. package.json describes your project and its dependencies.

JavaScript
// ES Modules (recommended — add "type": "module" in package.json)

// math.js — named exports
export function add(a, b)      { return a + b }
export function subtract(a, b) { return a - b }
export const PI = 3.14159

// Default export
export default class Calculator {
  add(a, b)      { return a + b }
  subtract(a, b) { return a - b }
}

// main.js — importing
import Calculator, { add, PI } from './math.js'  // .js required in Node ESM
import { readFile } from 'fs/promises'            // stdlib
import express from 'express'                      // npm package

// Dynamic import — lazy load a module
const { default: heavy } = await import('./heavy-module.js')

// __dirname / __filename equivalents in ESM
import { fileURLToPath } from 'url'
import { dirname, join } from 'path'

const __filename = fileURLToPath(import.meta.url)
const __dirname  = dirname(__filename)
const configPath = join(__dirname, "config.json")
Bash
# Initialize a project
npm init -y

# Install a package (adds to dependencies)
npm install express

# Install dev tools (adds to devDependencies)
npm install -D nodemon

# Install globally (available as CLI command)
npm install -g typescript

# Run scripts defined in package.json
npm start
npm run dev
npm test

# Audit for vulnerabilities
npm audit
npm audit fix

# List installed packages
npm list
npm list --depth=0   # only top-level

# Update packages
npm update
npm outdated   # see what's outdated
JSON
{
  "name": "my-api",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "start":  "node src/index.js",
    "dev":    "nodemon src/index.js",
    "test":   "node --test",
    "lint":   "eslint src"
  },
  "dependencies": {
    "express": "^4.18.2"
  },
  "devDependencies": {
    "nodemon": "^3.0.2"
  },
  "engines": {
    "node": ">=18.0.0"
  }
}
✦ Tip
Always commit `package-lock.json` — it records exact versions of every dependency. Never commit `node_modules/`. Add it to `.gitignore`. The lock file ensures everyone on the team (and CI) gets identical installs, preventing "works on my machine" bugs.