Chapter 14: Node Modules

What is a Module in Node.js?

A module is simply a file (or sometimes a folder) that contains JavaScript code you want to reuse in other parts of your application.

Most common things we put inside modules:

  • Utility functions (formatters, validators, helpers)
  • Classes / Models
  • Route handlers / controllers
  • Service layer (business logic)
  • Database helpers / repositories
  • Configuration values
  • Middleware
  • Custom error classes

Main goals of using modules:

  • Keep files small and focused (single responsibility)
  • Avoid huge 2000+ line files
  • Make code easier to test
  • Make code easier to reuse
  • Make team collaboration easier

Chapter 2 – Two Module Systems in Node.js (very important to understand)

System Syntax used Introduced in Status in 2026 Recommended for new projects? File extension requirement
CommonJS require() / module.exports 2009 Still very widely used No – legacy No (.js is optional)
ES Modules (ESM) import / export Node.js 12+ Modern standard Yes Usually yes (.js)

2026 reality check:

  • New libraries are mostly ESM-only or dual
  • Most new projects start with ESM
  • Many enterprise / legacy projects still use CommonJS
  • You need to know both — especially when you work with older codebases

Chapter 3 – CommonJS – The Classic Way (still very common)

3.1 Exporting in CommonJS

utils/math.js

JavaScript

3.2 Importing in CommonJS

index.js

JavaScript

Destructuring is also very common:

JavaScript

Important notes about CommonJS:

  • No need to write .js in the path
  • require() can be called anywhere (even inside if statements)
  • Circular dependencies are allowed (but can be confusing)

Chapter 4 – ES Modules – The Modern Way (recommended in 2026)

Step 1: Enable ESM in your project

Add this line to package.json:

JSON

Without “type”: “module”, Node.js treats .js files as CommonJS.

Step 2: Writing an ES Module

utils/math.js

JavaScript

Step 3: Importing ES Modules

index.js

JavaScript

Very important rules for ESM:

  • You usually need to write the .js extension./utils/math.js ← correct ./utils/math ← usually does NOT work
  • import must be at top level (cannot be inside if/for blocks)
  • Dynamic import is possible with await import()

Chapter 5 – Real-world folder structure example (modern style)

text

Example: user-service.js

JavaScript

Using it in controller:

JavaScript

Chapter 6 – Quick Comparison Table (CommonJS vs ESM)

Feature CommonJS ES Modules Winner 2026
Syntax require / module.exports import / export ESM
File extension in import Optional Usually required
Top-level await Not allowed Allowed ESM
Dynamic import require() anywhere await import() (inside async functions) CommonJS
Tree-shaking Poor Excellent ESM
Circular dependencies Allowed (sometimes tricky) Allowed but stricter
Modern libraries Less common now Most new libraries ESM

Chapter 7 – Common Mistakes & Best Practices (2026 style)

Common mistakes:

  1. Forgetting “type”: “module” → SyntaxError: Cannot use import statement outside a module
  2. Forgetting .js extension in ESM imports
  3. Using require in ESM project (or vice versa)
  4. Putting import inside conditions/loops (not allowed in ESM)
  5. Exporting nothing → undefined when imported

Best practices 2025–2026:

  • Use ESM for all new projects
  • Use named exports most of the time
  • Use default export when there is clearly one main thing per file
  • Keep modules small (ideally < 200–300 lines)
  • Use barrel files carefully (index.js that re-exports everything)
  • Always prefer relative paths (../utils) over absolute paths unless you have alias configured

Homework / Practice Suggestions

  1. Create a small project with 5–6 modules (utils, services, controllers)
  2. Write it first in CommonJS, then convert it to ESM
  3. Try both named exports and default exports
  4. Intentionally make a circular dependency and see what happens
  5. Create a module that exports both functions and a class

Let me know which part you want to go deeper into next:

  • Converting CommonJS → ESM step-by-step
  • Barrel files (index.js re-exports)
  • Dynamic import (await import())
  • Publishing dual CommonJS + ESM packages
  • Real folder structure for medium/large project
  • Handling circular dependencies

Just tell me what you want to explore next — I’ll continue with full examples. 😄

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *