By WebNest Studio Engineering Team
JavaScript Tutorial
JavaScript Modules (import/export)
As applications grow, keeping all code in a single file becomes unmanageable. ES Modules (introduced in ES2015 and now natively supported in browsers and Node.js) let you split code across files and explicitly declare what each file shares with others using export and what it needs from others using import.
Modules are automatically executed in strict mode, have their own top-level scope (variables don't leak into the global scope), and are only evaluated once no matter how many times they're imported.
Why it matters
Real applications are split across many files, and modules are how those files share code without polluting the global scope. Every React, Vue or Node.js project is built from import and export statements. Knowing named and default exports is necessary to read the first line of almost any modern source file.
Named Exports and Imports
A module can export multiple named values — functions, classes, constants — using export in front of a declaration, or a single export { a, b, c } statement. The importing file must use the exact same names (or rename them with as) inside curly braces: import { a, b } from './module.js'.
Default Exports
Each module may additionally have one export default, typically used for the "main" thing a file provides (a single class or component). Importing a default export doesn't use curly braces, and the local name can be anything you choose: import MyThing from './module.js'. A file can mix one default export with several named exports.
Practical Usage
In the browser, modules are loaded with <script type="module" src="main.js"></script>, which automatically defers execution and enforces CORS rules on cross-origin imports. In Node.js, modules are used either via .mjs files or by setting "type": "module" in package.json. Import paths for local files must be relative (starting with ./ or ../) and typically include the file extension.
Examples
Named exports and a default export in one module, then imported
// math.js
export const PI = 3.14159;
export function add(a, b) {
return a + b;
}
export default function multiply(a, b) {
return a * b;
}
// main.js
import multiply, { PI, add } from './math.js';
console.log(add(2, 3));
console.log(multiply(4, 5));
console.log(PI);
5
20
3.14159
Renaming an import to avoid a naming collision
// logger.js
export function log(message) {
console.log('[APP]', message);
}
// main.js
import { log as appLog } from './logger.js';
appLog('Server started');
[APP] Server started
Common Mistakes
- Mixing up default and named export syntax — forgetting curly braces for named imports, or adding them by mistake for a default import.
- Trying to have more than one
export defaultin the same file, which is a syntax error. - Forgetting the file extension in relative import paths in the browser (
import x from './utils'instead of'./utils.js'), which fails since browsers don't auto-resolve extensions the way bundlers do. - Loading a module script without
type="module"on the<script>tag, soimport/exportthrow a syntax error.
Exercise
In a project the module would be a separate file. Here its source is held in a string and loaded with a dynamic import() so that the exercise runs in one file. Add the export keywords so that PI and area are named exports and describe is the default export, then log each of them.
Expected output: 3.14, 12.56, circle tools (one per line)
// TODO: add "export" (and "export default") to the three declarations
const source =
"const PI = 3.14;" +
"function area(r) { return PI * r * r; }" +
"function describe() { return 'circle tools'; }";
import("data:text/javascript," + encodeURIComponent(source)).then((module) => {
// TODO: log the named export PI
// TODO: log area(2)
// TODO: log the result of calling the default export
});
Show hints
- A named export is written
export const PI = ..., and the default exportexport default function describe() { ... }. - On the module object, named exports are properties with their own names, and the default export is the property
default.
Show solution
const source =
"export const PI = 3.14;" +
"export function area(r) { return PI * r * r; }" +
"export default function describe() { return 'circle tools'; }";
import("data:text/javascript," + encodeURIComponent(source)).then((module) => {
console.log(module.PI);
console.log(module.area(2));
console.log(module.default());
});
Quick quiz
1. How many default exports can one module have?
- A. None
- B. Two
- C. Any number
- D. One
Show answer
D. A module can have one default export and any number of named exports.
2. How is a named export called add imported?
- A. require add from "./math.js"
- B. import add from "./math.js"
- C. import { add } from "./math.js"
- D. include add "./math.js"
Show answer
C. Named imports use braces and must match the exported name. A default import has no braces.
3. How do you rename an import to avoid a clash with a local name?
- A. import { add = sum } from "./math.js"
- B. It cannot be renamed
- C. import { add: sum } from "./math.js"
- D. import { add as sum } from "./math.js"
Show answer
D. The as keyword gives the import a different local name.
Interview questions
What is the difference between named and default exports?
Show answer
A module can have many named exports, each imported by its exact name inside braces: import { add, subtract } from "./math.js". It can have one default export, imported without braces under any name the importer chooses: import calculate from "./math.js". Named exports give consistent names across a codebase and better editor support; default exports suit a module whose purpose is one main thing.
What is the difference between ES modules and CommonJS?
Show answer
ES modules are the standard of the language: import and export, resolved statically before the code runs, which allows tools to remove unused code, and supported by browsers and Node.js. CommonJS is the older Node.js system: require() and module.exports, loaded synchronously at runtime. New code uses ES modules; CommonJS is still found in many existing Node.js packages.
Key Points to Remember
- A module can have any number of named exports plus at most one default export.
- Named imports must match exported names (or be renamed with
as); default imports can use any local name. - Modules run in strict mode with their own scope and are evaluated only once even if imported from multiple places.
- Browsers need
<script type="module">; Node.js needs.mjsor"type": "module"in package.json.
Practice in the playground
Write and run your own code for this topic, or start from the exercise or an example. Shows a live preview of your HTML, CSS and JavaScript. Your code for each topic is kept in this browser.
Run the examples
Change an input, predict the result, then compare it with the output. Explain why the result changes.
Written by
WebNest Studio Engineering Team
Practical lessons from developers working with Java, Python, React, databases and production systems.
Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering