Skip to main content

Command Palette

Search for a command to run...

JavaScript Modules: import and export explained

Updated
•6 min read•View as Markdown
JavaScript Modules: import and export explained
M
Just a tech guy

One file. Thousand lines.

You need a function from the bottom. You scroll. And scroll. And scroll.

This is chaos.

Let me show you how modules fix this.


Why Modules Are Needed

Remember the old days?

<script src="app.js"></script>
<script src="utils.js"></script>
<script src="api.js"></script>

All variables were global.

One file overwrites another's variable. No warning. Just bugs.

Problems:

Problem What happens
Global namespace pollution Everything is everywhere
No encapsulation Can't hide internal code
Hard to maintain Change one thing, break another
Impossible to reuse Copy-paste code across files

Modules solve all of this.


What is a Module?

A module is a file. That's it.

One file = one module.

Code inside is private by default. Nothing leaks out unless you explicitly export it.

Other files can import only what they need.

Think of it as:

"Export what you want to share. Import what you need to use."


Exporting Functions or Values

Named Export (Multiple per file)

Export as you create:

// utils.js
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;
export const PI = 3.14159;

Or export at the bottom:

// utils.js
const add = (a, b) => a + b;
const subtract = (a, b) => a - b;

export { add, subtract };

Default Export (One per file)

// math.js
const calculate = (a, b) => a * b;
export default calculate;

Or directly:

export default function multiply(a, b) {
  return a * b;
}

Rule: One file can have many named exports, but only one default export.


Importing Modules

Importing Named Exports

// app.js
import { add, subtract } from './utils.js';

console.log(add(5, 3));      // 8
console.log(subtract(5, 3)); // 2

Rename while importing:

import { add as sum, subtract as difference } from './utils.js';

Import everything as an object:

import * as Utils from './utils.js';

console.log(Utils.add(5, 3));
console.log(Utils.subtract(5, 3));

Importing Default Export

// app.js
import calculate from './math.js';

console.log(calculate(4, 5)); // 20

Note: Default import can have any name. No curly braces.

Mixed Import (Default + Named)

// file has both export default and named exports
import calculate, { add, subtract } from './math.js';

Default vs Named Exports – Quick Comparison

Feature Named Export Default Export
Per file Multiple Only one
Import syntax { name } No curly braces
Rename on import as keyword Any name works
Best for Utilities, helpers Main thing of the file

When to use what?

  • Use named exports for multiple related functions/values.

  • Use default export when the file has one primary thing (a class, main function).


The File Dependency Flow

Imagine this structure:

project/
├── main.js
├── math.js
└── logger.js

math.js exports functions. logger.js exports a default logger. main.js imports from both.

// math.js
export const add = (a, b) => a + b;
export const multiply = (a, b) => a * b;
// logger.js
export default function log(msg) {
  console.log(`[LOG]: ${msg}`);
}
// main.js
import { add, multiply } from './math.js';
import log from './logger.js';

const result = add(2, 3);
log(`Result is ${result}`); // [LOG]: Result is 5

Flow: main.js → math.js and logger.js. No global pollution. Clean.


Benefits of Modular Code

Benefit Explanation
Encapsulation Internal code stays private
Reusability Import the same module anywhere
Maintainability Change one file, others work if exports unchanged
No namespace pollution No accidental variable collisions
Clear dependencies You know exactly what each file needs
Easier testing Test each module in isolation

The Correct Import Order

Always follow this order:

  1. Built-in Node.js modules (if using Node)

  2. Third-party packages (from npm)

  3. Your own modules (local files)

Why? Clarity and precedence. Built-in first, then external, then internal.

// ✅ Correct order
import fs from 'fs';           // Built-in
import express from 'express'; // Third-party
import { add } from './math.js'; // Local
import log from './logger.js';   // Local

Wrong order:

// ❌ Don't mix randomly
import { add } from './math.js';
import fs from 'fs';
import lodash from 'lodash';

Keep it clean. Readability matters.


How to Use Modules in Browser

Two things needed:

  1. Add type="module" to script tag:
<script type="module" src="main.js"></script>
  1. Use .js or .mjs extension (both work).

Important: Modules are deferred by default. They wait for HTML to load.


Common Mistakes

Mistake 1: Forgetting {} for named imports

// ❌ Wrong
import add from './utils.js'; // but add is named export

// ✅ Correct
import { add } from './utils.js';

Mistake 2: Trying default import with wrong name

// ❌ Wrong for default export
import { calculate } from './math.js'; // calculate is default

// ✅ Correct
import calculate from './math.js';

Mistake 3: Missing file extension

// ❌ May not work in browsers
import { add } from './utils';

// ✅ Always include .js
import { add } from './utils.js';

Mistake 4: Mixing default and named incorrectly

// ❌ Wrong order
import { add }, calculate from './math.js';

// ✅ Correct: default first, then named
import calculate, { add } from './math.js';

Mistake 5: Wrong import order

// ❌ Third-party before built-in
import express from 'express';
import fs from 'fs';
import cors from 'cors';

// ✅ Built-in first
import fs from 'fs';
import express from 'express';
import cors from 'cors';

Final Thought

Modules keep your code organized, private, and reusable.

Export what's needed. Import what's used.

One file = one responsibility.

And remember: built-in → third-party → local. Always.