Default Exports
Every module can have at most one default export. It is the “primary” thing the module provides — the main class, the main function, the main object.
Exporting a default
Section titled “Exporting a default”Use export default before the value:
export default class Expense { // ... full class definition}Or assign it separately:
class Expense { /* ... */ }export default Expense;Importing a default
Section titled “Importing a default”When importing a default export, you do not use curly braces, and you can use any name you want:
import Expense from './expense.js';import MyExpenseClass from './expense.js'; // also valid — same thingThe name you choose on import is entirely up to you. Convention is to use the same name as the exported value.
Mixing default and named exports
Section titled “Mixing default and named exports”A module can have both a default export and named exports:
export default class Expense { /* ... */ }
export const CATEGORIES = ['Food', 'Transport', 'Health', 'Entertainment', 'Other'];
export function createExpense(data) { return new Expense(data);}import Expense, { CATEGORIES, createExpense } from './expense.js';The default import (Expense) comes first, before the curly braces.
Default vs named: when to use which
Section titled “Default vs named: when to use which”This is a real decision that JavaScript developers disagree about. Here is a practical rule:
Use a named export when:
- A module exports multiple things of equal importance
- You want the import name enforced across the codebase (it must match)
- You are building a library or utility module with several small helpers
Use a default export when:
- A module has one primary thing (a class, a component, a main function)
- You want to allow the importer to choose the name
- The module is a self-contained unit (one file = one thing)
For BudgetBuddy, Expense is the primary export of expense.js — a good candidate for default. Utility functions in utils.js are all equal in importance — better as named exports.
A common pattern: default class, named utilities
Section titled “A common pattern: default class, named utilities”export default class Expense { static CATEGORIES = ['Food', 'Transport', 'Health', 'Entertainment', 'Other']; // ...}
export function isValidCategory(category) { return Expense.CATEGORIES.includes(category);}import Expense, { isValidCategory } from './expense.js';What to avoid
Section titled “What to avoid”Do not use default exports for modules that export many things — the name ambiguity becomes a problem:
// ✗ confusing — what does this object contain?export default { formatCurrency, formatDate, DEFAULT_CURRENCY,};
// ✓ named exports — clear and self-documentingexport { formatCurrency, formatDate, DEFAULT_CURRENCY };Exercise
Section titled “Exercise”- Change the
Expenseclass inexpense.jsto a default export. - Update
main.jsto use the default import syntax (no curly braces). - Add a named export
CATEGORIESarray toexpense.jsand import it inmain.jsalongside the default. - Intentionally import the default under a different name (e.g.,
import MyExpense) — confirm it still works.
export default valuemarks one primary export per module.- Default imports do not use curly braces and can use any name.
- A module can have both a default export and named exports — default comes first in the import statement.
- Use default for a module’s one primary thing; use named exports when multiple items are equally important.