Skip to content

Intermediate · Modules, errors, JSON and dates · topic 26 of 61 · 25 min

Modules: import and export

Explanation

A module is a file whose variables are private unless you export them. Other files import what they need. ES modules (import/export) are the standard in browsers and Node.js; older Node code uses CommonJS (require and module.exports). Modules keep large programs organised and avoid name clashes.

Why modules?

A real app has thousands of lines. In one file, every variable would be visible to every other line, two people would accidentally use the same name, and nobody could find anything. A module is simply a file with its own private scope. It decides what to share (export), and other modules decide what to use (import).

Named exports

javascript
// gst.js
export const GST_RATE = 18;
export function addGst(amount) {
  return Math.round(amount * (1 + GST_RATE / 100));
}
function secretHelper() {}      // not exported: private to this file

// cart.js
import { addGst, GST_RATE } from './gst.js';
console.log(addGst(1000), GST_RATE); // 1180 18
A file can have many named exports. The names in { } must match.

Default exports

javascript
// logger.js
export default function log(msg) {
  console.log(new Date().toISOString(), msg);
}

// app.js
import log from './logger.js';          // any name you like, no braces
import writeLog from './logger.js';     // the same function
A file can have at most one default export.

Renaming and namespace imports

javascript
import { addGst as withTax } from './gst.js';  // rename on import
import * as gst from './gst.js';               // everything as one object
console.log(gst.GST_RATE, withTax(100));

Using modules in the browser and in Node

  • Browser: <script type="module" src="app.js"></script>. Module scripts run in strict mode, are deferred automatically, and the import paths need the file extension (./gst.js).
  • Node.js: files ending in .mjs are ES modules, or set "type": "module" in package.json to make every .js file an ES module.
  • Imports are read before the code runs, so they must be at the top level of the file, not inside an if.
  • An imported binding is read-only: you cannot assign GST_RATE = 5 in the importing file.

CommonJS: the older Node format

javascript
// gst.cjs (CommonJS)
const GST_RATE = 18;
function addGst(a) { return Math.round(a * 1.18); }
module.exports = { GST_RATE, addGst };

// app.cjs
const { addGst } = require('./gst.cjs');
Many npm packages and older projects still use CommonJS. require is a function that runs at run time.
ES modulesCommonJS
Syntaximport / exportrequire / module.exports
LoadedBefore running (static)When require runs (dynamic)
WhereBrowsers and NodeNode (and bundlers)
Top-level awaitAllowedNot allowed

Dynamic import()

import('./charts.js') is a function-like expression that loads a module LATER and returns a promise. Use it to load heavy code only when it is needed, for example the chart library only when the user opens the reports page.

Careful: Circular imports (a.js imports b.js and b.js imports a.js) can give you undefined or a ReferenceError at start-up, because one file runs before the other has finished. If two modules need each other, move the shared part into a third module.
Tip: Prefer named exports in your own code: editors can auto-import them, renaming is easier, and a typo in the name is a clear error instead of silently importing the wrong default.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Modules: import and export · 1/7

Modules

In this lesson you will split programs into modules with import and export.

Prefer a video by a teacher? Find free videos on “javascript es modules import export commonjs require” on YouTube ↗

In real life: Organising a billing service

A billing backend for a chain of pharmacies is split into modules: tax.js (GST rules), invoice.js (building invoices), pdf.js (rendering) and email.js (sending). When the GST rules change, only tax.js is edited and tested. New developers can read one small file instead of a 5,000-line monolith.

javascript
// invoice.js
import { addGst } from './tax.js';
import { renderPdf } from './pdf.js';

export function createInvoice(items) {
  const total = items.reduce((s, i) => s + addGst(i.price), 0);
  return renderPdf({ items, total });
}
invoice.js uses tax.js and pdf.js without knowing their internals.

Practice (0/3 done)

Task 1 · Question

math.js has 'export default function add(a, b) {...}'. Which import is correct?

Task 2 · Code · Javascript

Modules give each file a private scope. Imitate this with a closure: write createGstModule() that returns an object with ONLY addGst(amount) (rounded total with 18% GST) and RATE (18). The helper round2 must stay private (not on the returned object).

Task 3 · Practice

On your computer, make a folder with package.json containing { "type": "module" }, a file gst.js that exports GST_RATE and addGst, and main.js that imports them and prints addGst(250). Run node main.js.

Quick quiz

Question 1

1.How many default exports can a module have?

Question 2

2.What does import * as tax from "./tax.js" give?

Question 3

3.Which is CommonJS?

Question 4

4.What does import("./big.js") return?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

How many default exports can a module have?

Answer: At most one

One default export per module; named exports are unlimited.

What does import * as tax from "./tax.js" give?

Answer: An object with all named exports

A namespace import collects all exports into one object.

Which is CommonJS?

Answer: module.exports = { a }

CommonJS uses require and module.exports.

What does import("./big.js") return?

Answer: A promise for the module

Dynamic import is asynchronous and returns a promise.

In import formatPrice, { addGst } from './money.js'; which one is the default export?Related

Answer: formatPrice

The name outside the braces is the default export. Names inside { } are named exports.

From Modules, npm and Vite

Which import lets you write sqrt(25) without math. in front?Related

Answer: from math import sqrt

from math import sqrt brings the name sqrt straight into your program.

From Modules and imports

Which modifier allows access from subclasses in other packages but not from unrelated classes there?Related

Answer: protected

protected adds subclasses to package access.

From Packages and access modifiers

What decides whether a Go name is exported?Related

Answer: Whether its first letter is upper-case

Upper-case first letter means exported.

From Packages, visibility and project layout

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 4 more topics in “Modules, errors, JSON and dates” before its exam: Error handling: try, catch, finally and throw, JSON: data in and out, Dates and times, Formatting numbers, money and text with Intl.
  2. Module 6 exam: Modules, errors, JSON and dates · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Map, Set, iterators, generators and regular expressions. 61 topics left in the course before the final exam.

← Previous: Inheritance and composition