You will be able to bring named, default, and namespace exports from another JavaScript module into the current module using import declarations.
What it is
An import declaration is part of JavaScript's ES module system. A module is a file that can export values and import values from other files. Importing does not copy the value; it creates a local binding to the exported binding. If the exporting module changes the value, the importing module sees the updated value, except for primitive constants that are not reassigned.
Related terms: export, named export, default export, namespace import, module specifier, and dynamic import.
Why it matters
- It lets you split code into reusable files instead of putting everything in one script.
- It makes dependencies explicit, so tools can detect missing exports and bundle code.
- It supports tree shaking, where unused exports can be removed from production bundles.
- It works in modern browsers with
<script type="module">and in Node.js with ES module files. - It avoids global variables, reducing accidental name collisions.
Syntax or steps
The smallest useful pattern is a named import:
import { PI } from "./math.js";
Common forms:
import name from "./file.js";imports the default export.import { name } from "./file.js";imports a named export.import { name as alias } from "./file.js";renames the imported binding.import * as ns from "./file.js";imports all exports as an object-like namespace.import "./file.js";runs the module for side effects only.
Import declarations must appear at the top level of a module. They are hoisted, so the imported bindings are available before the import statement in source order, but the module still executes its dependencies first.
Example
Create math.js:
export const PI = 3.14159;
export function area(radius) {
return PI * radius * radius;
}
export default function circle(radius) {
return area(radius);
}
Create main.js:
import { PI, area } from "./math.js";
import circle from "./math.js";
import * as math from "./math.js";
console.log(PI);
console.log(area(2));
console.log(circle(2));
console.log(math.PI);
Run it from an HTML file:
<script type="module" src="./main.js"></script>
Expected output:
3.14159
12.56636
12.56636
3.14159
Part by part: export const PI creates a named export. export default function circle creates a default export. In main.js, import { PI, area } brings two named exports into local bindings. import circle brings the default export and names it circle. import * as math creates a namespace object containing all exports. The type="module" attribute tells the browser to treat main.js as an ES module.
Common mistakes
- Using
require()in an ES module. Fix: useimportor configure the file as CommonJS. - Forgetting the file extension in browsers. Fix: use
./math.js, not./math. - Importing a default export as a named export. Fix: use
import circle from "./math.js", notimport { circle }, unless the module exports it as named. - Trying to import from a file that does not export the requested name. Fix: check the exporting module for matching
exportdeclarations.
When to use it
Use static import when you know the dependency at build or load time. Use dynamic import() when you want to load a module later, such as after a user action or route change. Use CommonJS require() only in legacy Node.js CommonJS files.
| Pattern | Best for | Example |
|---|---|---|
| Static import | Normal module dependencies | import { PI } from "./math.js"; |
| Dynamic import | Lazy loading and conditional loading | const mod = await import("./math.js"); |
| CommonJS require | Legacy Node.js scripts | const math = require("./math.js"); |
Practice
Guided exercise: create utils.js with export function sum(a, b) { return a + b; }. In main.js, import sum and log sum(2, 3). Expected output: 5.
Challenge: import all exports from utils.js as a namespace and log the namespace object. Hint: use import * as utils from "./utils.js"; and console.log(utils);.
Quick check
Question: What does import { PI } from "./math.js"; do?
Answer: It brings the named export PI from ./math.js into the current module as a local binding named PI.
Summary
Import is the way a JavaScript module declares and accesses values exported by another module. It supports named, default, and namespace imports, making code modular, explicit, and easier to maintain.