CommonJS vs ES Modules & Package.json Dependency Management0%

CommonJS vs ES Modules & Package.json Dependency Management

Beginner12 min read•Updated: Jul 11, 2026
Study MaterialsCheatsheet

CommonJS vs ES Modules & Package.json Dependency Management

Node.js has two module systems: the legacy CommonJS (CJS) standard and the official ECMAScript ES Modules (ESM) standard. Understanding the differences, interoperability, and modern NPM dependency management is essential for all professional backend developers.


1. CommonJS (CJS) vs ES Modules (ESM)

FeatureCommonJS (CJS)ES Modules (ESM)
Syntaxconst x = require('./x') / module.exports = ...import x from './x.js' / export default ...
Loading MechanismSynchronous, runtime evaluationAsynchronous, static parsing phase
Top-Level AwaitSupported only in limited wrapper contextsSupported natively at top-level
File Extension.cjs or default .js.mjs or .js with "type": "module" in package.json
Dynamic ImportsDynamic require() allowed anywhereimport() returns a Promise
Special Variables__dirname, __filename availableUse import.meta.url and fileURLToPath

Enabling ES Modules in Node.js

To use modern ESM across your Node.js project, add "type": "module" to your package.json:

JSON
{
"name": "backend-api",
"version": "1.0.0",
"type": "module",
"scripts": {
"start": "node src/server.js"
}
}

Resolving __dirname in ES Modules

JavaScript
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
 
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
 
console.log('Current directory:', __dirname);

2. Package.json: Dependencies vs DevDependencies

Managing dependencies correctly is crucial for keeping production Docker images slim and secure:

JSON
{
"dependencies": {
"express": "^4.21.0",
"cors": "^2.8.5",
"dotenv": "^16.4.5"
},
"devDependencies": {
"nodemon": "^3.1.4",
"eslint": "^9.10.0",
"jest": "^29.7.0"
}
}
  • dependencies: Essential runtime libraries required to serve production traffic (Express, database drivers, JWT).
  • devDependencies: Tools needed strictly for local development and CI/CD pipelines (test runners, linters, TypeScript compiler, Nodemon).
  • In production deployment, install only runtime libraries: npm ci --omit=dev.

Interactive Quiz

Multiple Choice Questions

Question 1
How do you configure a Node.js project so that all .js files are treated as ES Modules (ESM) by default?
Question 2
Which global variables are available natively in CommonJS (CJS) but undefined in ES Modules (ESM)?
Question 3
What is the semantic meaning of the caret symbol (^) in a dependency version declaration like "express": "^4.18.2"?
Question 4
What command installs strictly the exact dependencies recorded in package-lock.json without modifying the lockfile, ideal for production CI/CD?
Question 5
Why should development utilities like nodemon and jest be installed under devDependencies rather than dependencies?

Next Lesson

File System Operations: Sync, Async & Promises API (fs/promises)

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext