Skip to main content

Command Palette

Search for a command to run...

JavaScript Modules: Import and Export Explained

Updated
•3 min read•View as Markdown
JavaScript Modules: Import and Export Explained
S
I'm a full-stack developer passionate about building scalable, real-world applications from the ground up. My expertise spans the entire web development stack, from crafting semantic HTML and responsive layouts with modern CSS (Flexbox, Grid, Tailwind) to building dynamic interfaces with React, TypeScript, and Next.js.

Why are modules needed?

Imagine building a complex application in a single JavaScript file with 5,000 lines of code. You would quickly encounter several major issues:

  • Global Namespace Pollution: If you define a variable in one script and another script also uses the same variable name, they can clash and overwrite each other.

  • Dependency Nightmares: It becomes challenging to determine which parts of the code rely on one another. If you delete a function at the top of the file, you might unintentionally break something at the bottom without realizing why.

  • Difficult Debugging: Finding a bug in a "spaghetti code" file is like searching for a needle in a haystack.

  • Low Reusability: If you create a great validation function, you would need to copy and paste it into every new project because it's trapped in a massive file.

Exporting functions or values

To make a function or variable available to other files, you must explicitly export it. Think of this as making a "public" part of your module.

Named Exports

You can export multiple things from a single file by giving them specific names.

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

Default Exports

Each file can have one default export. This is usually the "main" thing the file is responsible for.

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

Importing modules

Once you've exported something, you can import it into another file.

  • Importing Named Exports: You must use curly braces {} and match the names exactly.

  • Importing Default Exports: You can name the import whatever you want, and no braces are needed.

// main.js
import log from './Logger.js'; // Default import (name it anything)
import { add, PI } from './mathUtils.js'; // Named imports (must match)

log(add(10, PI)); // Output: [LOG]: 13.14

Default vs named exports

Feature Named Exports Default Exports
Quantity Multiple per file Only one per file
Import Syntax import { name } from './file' import anyName from './file'
Strictness Must use the exact exported name Can use any alias (custom name)
Best For Utility libraries with multiple functions Main components, classes, or objects

Benefits of modular code

A. Improved Maintainability

Each module has a specific function, allowing you to update a single file without worrying about unintentionally breaking the entire system. This approach isolates the logic.

B. Reusability

You can take a module from an old project and drop it into a new one. It is a self-contained unit that works seamlessly.

C. Better Organization (Encapsulation)

Modules conceal the complex internal logic. Other files only access the functions you choose to expose. This keeps the rest of your codebase clean and focused on high-level logic.

D. Easier Testing

It is significantly easier to write tests for a small module with three functions than for a massive script with dozens of hidden dependencies.