CommonJS vs ES Modules & Package.json Dependency Management0%
CommonJS vs ES Modules & Package.json Dependency Management
Beginner12 min read•Updated: Jul 11, 2026
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)
| Feature | CommonJS (CJS) | ES Modules (ESM) |
|---|---|---|
| Syntax | const x = require('./x') / module.exports = ... | import x from './x.js' / export default ... |
| Loading Mechanism | Synchronous, runtime evaluation | Asynchronous, static parsing phase |
| Top-Level Await | Supported only in limited wrapper contexts | Supported natively at top-level |
| File Extension | .cjs or default .js | .mjs or .js with "type": "module" in package.json |
| Dynamic Imports | Dynamic require() allowed anywhere | import() returns a Promise |
| Special Variables | __dirname, __filename available | Use 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.
Related Lessons
Practice Quiz
Test your understanding of this lesson with 5 questions. Each question has one correct answer.