CodingNic

Modules & Code Organization

Default Exports

Modules & Code Organization 15 min read

Default Exports

Objectives

By the end of this chapter, you should be able to:

  • Export a single main value from a module with export default
  • Import a default export under any name you choose
  • Mix a default export with named exports in the same file

💡 Why this matters: Sometimes a module has one clear “main” thing it provides, a single class, a single function, everything else in the file just supports it. Default exports are built for exactly that case.

Exporting a Default

export default marks one value in a module as its main export. A module can only have one default export.

javascript
// logger.js
export default function log(message) {
  console.log(`[LOG] ${message}`);
}

Importing a Default

Importing a default export doesn’t use curly braces, and the name you give it on import doesn’t have to match anything, there’s no as needed, since a default export has no fixed name to begin with.

javascript
// main.js
import log from "./logger.js";

log("Hello");
// [LOG] Hello
javascript
// this works exactly the same way, the name is entirely up to the importing file
import myLog from "./logger.js";

myLog("Renamed on import, still works");
// [LOG] Renamed on import, still works

Compare this to a named import (previous lesson), which must use the exact exported name unless you explicitly rename it with as. A default import skips that requirement entirely, the name is whatever you write.

Mixing Default and Named Exports

A single file can have one default export alongside any number of named exports.

javascript
// userModule.js
export default class User {
  constructor(name) {
    this.name = name;
  }
}

export const MAX_USERS = 100;

Importing both looks like this: the default import first, without braces, then named imports in braces, separated by a comma.

javascript
import User, { MAX_USERS } from "./userModule.js";

const u = new User("Priya");
console.log(u.name);
// Priya

console.log(MAX_USERS);
// 100

When to Use Which

Reach for a default export when a module has one obvious main thing it provides, a single component, a single class, a single configuration object. Reach for named exports (previous lesson) when a module provides several related, equally important pieces, like a set of utility functions. Plenty of real modules use both, one default export as the main feature, plus a few named exports for supporting pieces, exactly like userModule.js above.

Try It

Imagine a file Timer.js with this content:

javascript
// Timer.js
export default class Timer {
  constructor(seconds) {
    this.seconds = seconds;
  }
}

export const DEFAULT_DURATION = 60;
  1. Import Timer as the default export, create one with new Timer(30), and log its .seconds.
  2. Import Timer under a different name, CountdownTimer, and confirm it still works exactly the same way.
  3. Import both Timer and DEFAULT_DURATION in a single import line, and log DEFAULT_DURATION.

Recap

  • export default marks one value as a module’s main export. A module can have at most one.
  • Importing a default export skips curly braces, and you can name it anything on import, no as required.
  • A file can combine one default export with any number of named exports, importing both looks like import Main, { named } from "./path".

Next lesson: organizing a small project across several files using both patterns together.