The JavaScript import statement
The import statement brings values that another file exported into the current module. Use named imports in braces — import { sum } from "./math.js" — or a default import — import React from "react". Imports run only in modules (a <script type="module"> or a bundler).
Overview
import is how a file pulls in code from other files. Modern JavaScript is organized into modules — each file is its own scope — and import connects them by bringing in whatever another file exported. This replaced the old habit of dumping everything into global scope, and it's the foundation of every framework and build setup.
There are two main shapes. Named imports use braces and must match the exported names: import { sum, PI } from "./math.js". A default import has no braces and you can name it anything: import myThing from "./thing.js". You can combine them, rename with as (import { sum as add }), or grab everything as a namespace: import * as math from "./math.js".
Two practical notes. Imports are static and hoisted — they're resolved before the module runs, so the path must be a literal string, not a variable. When you need to load a module conditionally or on demand, use the dynamic import(path) form, which returns a promise. And import only works in a module context: a <script type="module"> in the browser, or through a bundler like Vite or webpack.
Syntax
import defaultExport from "./module.js";
import { name1, name2 } from "./module.js"; // named
import { name1 as alias } from "./module.js"; // renamed
import * as ns from "./module.js"; // namespace
const mod = await import("./module.js"); // dynamic
Example
// math.js
export const PI = 3.14159;
export function sum(a, b) { return a + b; }
export default function multiply(a, b) { return a * b; }
// app.js
import multiply, { PI, sum } from './math.js';
console.log(sum(2, 3)); // 5
console.log(multiply(4, 5)); // 20
console.log(PI); // 3.14159
Best practices
- Match named imports to the exported names exactly (braces required); default imports can be named anything.
- Use a static string path —
importis resolved before the module runs. - Use dynamic
import()for conditional or lazy loading; it returns a promise. - Run modules via
<script type="module">or a bundler — plain scripts don't supportimport.
Frequently asked questions
What is the difference between a default and a named import?
import { sum }); a default import has no braces and you choose the name (import anything). A module can have one default and many named exports.Why does my import throw "Cannot use import outside a module"?
<script type="module">, a .mjs extension, or a bundler.How do I import a module conditionally?
await import("./mod.js"), which loads on demand and returns a promise.Can I rename an import?
as: import { sum as add } from "./math.js".