You will be able to import an entire JavaScript ES module as a single namespace object and access its named exports as properties.
What it is
A namespace import uses import * as name from "module" to create a module namespace object. The object contains the module's named exports as properties. If the module also has a default export, it appears as name.default. Think of it as putting all exported names into a labeled box instead of bringing each name into the current scope.
For exported bindings, the properties reflect live bindings, so changes to exported let values are visible through the namespace object. This syntax belongs to ES modules, not CommonJS require. Related terms: named export, default export, module namespace object, live bindings.
Why it matters
- Keeps many related exports grouped under one clear prefix, such as
math.add()instead ofadd(). - Reduces naming collisions when two modules export the same function name.
- Makes it easy to inspect available exports during debugging.
- Useful when a module exposes a small API surface that you want to treat as a unit.
- Helps keep code readable when only a few exports are used but the module has many.
Syntax or steps
- Export values from a module using
export. - In another module, write
import * as alias from "./path.js". - Access named exports as
alias.exportName. - Access a default export, if present, as
alias.default.
Example
// math.mjs
export const PI = 3.14159;
export function add(a, b) {
return a + b;
}
export function multiply(a, b) {
return a * b;
}
export default function format(n) {
return n.toFixed(2);
}
// main.mjs
import * as math from "./math.mjs";
console.log(math.add(2, 3));
console.log(math.PI);
console.log(math.multiply(4, 5));
console.log(math.default(3.14159));
Save the files as math.mjs and main.mjs, then run node main.mjs.
Expected output:
5
3.14159
20
3.14
Part by part:
export const PIandexport function addcreate named exports.export default function formatcreates a default export.import * as mathimports the whole module as the namespace objectmath.math.add,math.PI, andmath.multiplyaccess named exports.math.defaultaccesses the default export.
Common mistakes
- Expecting the namespace object itself to be the default export. If a module has
export default something, usealias.default, notalias. - Trying to call the namespace object as a function. A namespace object is not callable unless you call one of its exported function properties.
- Using namespace imports when only one or two exports are needed. Named imports such as
import { add } from "./math.mjs"are often clearer and make dependencies explicit. - Assuming the namespace object is a plain mutable object. It is read-only; do not try to add or change properties on it.
When to use it
Namespace imports are best when you want a grouped view of a module's exports. Named imports are better when you need only a few exports and want them directly in scope.
| Approach | Syntax | Use when |
|---|---|---|
| Named imports | import { add, PI } from "./math.mjs"; | You use a few exports and want concise local names. |
| Namespace import | import * as math from "./math.mjs"; | You want all exports under one prefix or need to inspect the module surface. |
| Default import | import format from "./math.mjs"; | The module exports one main value as default. |
Practice
Guided exercise: create utils.mjs with export const version = "1.0"; and export function greet(name) { return "Hello, " + name; }. In app.mjs, import it as utils and log both exports.
Expected output:
1.0
Hello, Ada
Challenge: add export default function shout(name) { return name.toUpperCase(); } to utils.mjs. Call it through the namespace import.
Solution hint: use utils.default("Ada").
Quick check
Question: What does import * as ns from "./mod.js" give you?
Answer: It gives you a module namespace object containing the module's named exports as properties, plus any default export under ns.default.
Summary
Namespace imports let you bring an entire ES module into one object, making exports easy to group and inspect. Use them when a module's API should stay under a prefix, and prefer named imports when you need only a few values directly.