ES Modules vs CommonJS

Two Module Systems

CommonJS (CJS)ES Modules (ESM)
Syntaxrequire(), module.exportsimport, export
Loadingsynchronousasynchronous, supports top-level await
Node.js default for .jsyes, unless "type": "module"with "type": "module" or .mjs
Used byolder 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

Projectmodule / moduleResolution
Node.js app or librarynodenext / nodenext
Next.js, Vite, any bundleresnext / bundler
NestJS (default)commonjs / node

Note: Details of these options are in the advanced level (tsconfig.json in Depth).