Modules vs Namespaces

The shift to standard ES Modules.

TypeScript3 min readConcept 46 of 54

The Evolution of Scope

Before JavaScript had standard import/export syntax (ES Modules), TypeScript invented its own module system called namespace.

Today, standard ES Modules are natively supported by Node.js and all modern browsers, making TS namespaces largely obsolete.

Why Switch?

Namespaces compile down to instantly-invoked function expressions (IIFEs) attached to the global object. This makes tree-shaking (removing unused code during build) nearly impossible for modern bundlers like Vite or Next.js.

ES Modules use a static structure that bundlers can analyze easily.

Syntax

typescript // ❌ Legacy Namespaces namespace Geometry { export function area(r: number) { return Math.PI * r * r; } } /// <reference path="geometry.ts" /> Geometry.area(5); // ✅ Modern ES Modules export function area(r: number) { return Math.PI * r * r; } import { area } from "./geometry.js"; area(5);

Try it

Compare the legacy namespace syntax alongside its compiled JavaScript output against the clean, modern ES Module standard.

// 1. Legacy TypeScript (Pre-2015)
namespace MathUtils {
export function add(a: number) {}
}
/// <reference path="math.ts" />
MathUtils.add(5);

// 2. Modern TypeScript (ES Modules)
export function add(a: number) {}
import { add } from "./math.js";
add(5);
Under The Hood
Compiled Namespace
var MathUtils;
(function (_MathUtils) {
  function add(a) {}
  _MathUtils.add = add;
})(MathUtils || (MathUtils = {}));
Creates a giant global object. Bundlers cannot tree-shake unused functions inside it.
Compiled ES Module
export function add(a) {}
Keeps static exports. Bundlers can cleanly slice off (tree-shake) any function you don't import.

Check yourself

Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.

  1. 1Why are Namespaces bad for modern web development?

Remember this

  • TypeScript namespace is a legacy feature from before ES Modules existed.
  • Always use standard import/export syntax in modern apps.
  • Namespaces break tree-shaking and bloat your bundle size.
  • Only use namespaces in .d.ts files to type legacy global scripts.

Done with this concept?

Mark it complete to track your progress. No login needed.