Careeroza
ES Modules vs CommonJS
Two Module Systems
| CommonJS (CJS) | ES Modules (ESM) | |
|---|---|---|
| Syntax | require(), module.exports | import, export |
| Loading | synchronous | asynchronous, supports top-level await |
Node.js default for .js | yes, unless "type": "module" | with "type": "module" or .mjs |
| Used by | older Node code, NestJS (compiled output) | browsers, Vite, Next.js, modern Node |
How TypeScript Emits Imports
You write import/export in TypeScript either way. The module option decides the output. With "module": "commonjs":
import { readFileSync } from "node:fs";
export const VERSION = "1.0";"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.VERSION = void 0;
const node_fs_1 = require("node:fs");
exports.VERSION = "1.0";With "module": "nodenext" TypeScript follows Node rules exactly: in an ESM package, relative imports must include the extension (import { x } from "./util.js", even though the file is util.ts).
Which Settings to Use
| Project | module / moduleResolution |
|---|---|
| Node.js app or library | nodenext / nodenext |
| Next.js, Vite, any bundler | esnext / bundler |
| NestJS (default) | commonjs / node |
Note: Details of these options are in the advanced level (tsconfig.json in Depth).