# JavaScript Modules: Import and Export Explained

In the early days of web development, JavaScript files were like a giant bowl of spaghetti. Everything was thrown into one place, and variables lived in a global space where they could easily overwrite each other. As applications grew, this became a nightmare to maintain.

Enter **JavaScript Modules (ESM)**—the modern way to organize, share, and protect your code.

## The Chaos Before Modules: Why We Need Them

Before ES6 (2015), JavaScript relied on multiple `<script>` tags in HTML. This led to several critical issues:

*   **Global Scope Pollution:** Every variable declared in one file was accessible (and changeable) by any other file.
    
*   **Dependency Issues:** You had to make sure scripts were loaded in the exact right order. If `script-b.js` used a function from `script-a.js`, then `a` had to load first.
    
*   **Lack of Encapsulation:** It was impossible to keep "private" logic hidden within a file.
    

Modules solved this by giving every file its own **private scope**. Nothing is shared unless you explicitly **export** it.

## Exporting: Sharing Your Code

To make a function, object, or variable available to other files, you use the `export` keyword. There are two primary ways to do this: **Named Exports** and **Default Exports**.

### 1\. Named Exports

Named exports allow you to export multiple values from a single file. You must use the exact name when importing them.

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

export const PI = 3.14;
```

### 2\. Default Exports

A file can have only **one** default export. This is often used for the main functionality of a module (like a React component or a main Class).

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

## Importing: Bringing It All Together

Once you've exported something, you use the `import` keyword to bring it into another file.

### Importing Named Exports

When importing named exports, you must use curly braces `{}` and the specific names.

```javascript
import { add, PI } from './mathUtils.js';

console.log(add(5, PI)); // 8.14
```

### Importing Default Exports

When importing a default export, you don't use curly braces, and you can name it whatever you want.

```javascript
import customLogger from './Logger.js';

customLogger("Modules are working!");
```

## Named vs. Default Exports: At a Glance

<table style="min-width: 75px;"><colgroup><col style="min-width: 25px;"><col style="min-width: 25px;"><col style="min-width: 25px;"></colgroup><tbody><tr><td colspan="1" rowspan="1"><p><strong>Feature</strong></p></td><td colspan="1" rowspan="1"><p><strong>Named Export</strong></p></td><td colspan="1" rowspan="1"><p><strong>Default Export</strong></p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Quantity</strong></p></td><td colspan="1" rowspan="1"><p>Multiple per file</p></td><td colspan="1" rowspan="1"><p>Only one per file</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Syntax (Export)</strong></p></td><td colspan="1" rowspan="1"><p><code>export const myVar = ...</code></p></td><td colspan="1" rowspan="1"><p><code>export default myVar</code></p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Syntax (Import)</strong></p></td><td colspan="1" rowspan="1"><p><code>import { myVar } from ...</code></p></td><td colspan="1" rowspan="1"><p><code>import anyName from ...</code></p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Best For</strong></p></td><td colspan="1" rowspan="1"><p>Utility libraries, multiple helpers</p></td><td colspan="1" rowspan="1"><p>Main components, classes</p></td></tr></tbody></table>

## The Benefits of Modular Code

Moving to a modular structure isn't just about following trends; it fundamentally changes how you build software:
