JavaScript import & export

Share Code Between Files

JavaScript import & export

`export` makes a value visible to other files. `import` brings it in. Two forms — named and default.

5 min read Level 2/5 #modules#import#export
What you'll learn
  • Use named exports and imports
  • Use a default export and import it under any name
  • Aliasing and namespace imports

Two ways to expose a value from a module: named exports and a default export.

Named Exports

You can export as many things by name as you want.

math.js
export const PI = 3.14159;

export function area(r) {
  return PI * r * r;
}

export function circumference(r) {
  return 2 * PI * r;
}
app.js
import { PI, area, circumference } from "./math.js";

console.log(PI);
console.log(area(5));
console.log(circumference(5));

You import named exports inside { }. The names must match what the module exports.

Renaming On Import

Use as to rename:

app.js
import { area as circleArea } from "./math.js";

console.log(circleArea(5));

Useful when two modules export the same name.

Default Export

A module can have ONE default export. Useful when the module is “about” one thing — a class, a main function, a constant.

user.js
export default class User {
  constructor(name) { this.name = name; }
}
app.js
import User from "./user.js";
// no braces — and you can call it anything you want:
// import Person from "./user.js";  also works

Default imports skip the braces and can be renamed at the import site.

Combining Default and Named

A module can have both:

db.js
export default function connect() { /* ... */ }
export const VERSION = "2.0";
app.js
import connect, { VERSION } from "./db.js";

Namespace Import (* as)

Bring in everything as a namespace object:

app.js
import * as math from "./math.js";

console.log(math.PI);
console.log(math.area(5));

Clear but verbose. Use when you want all of a module’s exports under one name.

Re-exporting

A module can re-export from another module. Common in “barrel” files (an index.js that re-exports submodules):

lib/index.js
export { default as User } from "./user.js";
export { area, circumference } from "./math.js";
export * from "./helpers.js";

Now consumers can import { User, area, helper1 } from "./lib";.

Static vs Dynamic

import declarations like the ones above are static — they run at the top of the file, before any other code. You can’t use them inside an if or a function.

For runtime imports, JavaScript has dynamic importawait import("…") — covered in the next lesson.

Default vs Named — Which Should You Use?

  • Default: when the module is “one main thing”.
  • Named: when the module exposes several siblings, OR you want the import name pinned (renaming at import is allowed but breaks refactor tools).

Many style guides recommend named exports everywhere for consistency. Pick a rule for your project and stick with it.

Try It Yourself

Exercise

Split a Module

Difficulty 2/5~6 min
Imagine you have one file with these three things: - a constant `PI` - a function `area(r)` that returns `PI * r * r` - a default export class `Circle` that uses `area` Split it into two modules: `math.js` (exports `PI` named + `area` named) and `circle.js` (default-exports the class, importing from `./math.js`). Sketch what the `import` and `export` lines look like in each file.
solution.js
// math.js
// ...

// circle.js
// ...
0tests will run
✅ Show solution
// math.js
export const PI = 3.14159;
export function area(r) {
  return PI * r * r;
}

// circle.js
import { area } from "./math.js";

export default class Circle {
  constructor(r) { this.r = r; }
  area() { return area(this.r); }
}

Up Next

Importing a module on demand instead of at the top of the file.

JavaScript Dynamic Imports →