Skip to main content

Command Palette

Search for a command to run...

JavaScript Modules: Import and Export Explained – Stop Writing Spaghetti Code

Updated
•7 min read•View as Markdown

The "One Giant File" Nightmare

Imagine you're building a LEGO castle. You have 10,000 bricks, but instead of organizing them into bags by color and shape, you dump them all into one giant pile. Every time you need a red 2x4 brick, you have to dig through thousands of pieces.

That's what JavaScript code looks like without modules.

You've probably seen it before—or maybe you've written it yourself (I know I have!):

// script.js – 2000 lines of chaos

// User authentication code (200 lines)
function login() { ... }
function logout() { ... }
function checkAuth() { ... }
function resetPassword() { ... }

// Shopping cart code (300 lines)
let cart = [];
function addToCart() { ... }
function removeFromCart() { ... }
function calculateTotal() { ... }

// Product catalog code (400 lines)
let products = [];
function fetchProducts() { ... }
function filterProducts() { ... }
function displayProducts() { ... }

// Payment code (500 lines)
function processPayment() { ... }
function validateCard() { ... }
// ... and on and on

This is what developers call spaghetti code—everything tangled together, impossible to navigate, and terrifying to change. One small edit could break something completely unrelated.

Enter JavaScript Modules – the solution that turns that giant pile of LEGO into organized, labeled bags.


What Are Modules? (The Simple Explanation)

A module is just a JavaScript file that exports its code so other files can import it.

Think of it like this:

  • Without modules: One giant notebook where every subject is mixed together

  • With modules: Separate notebooks for Math, Science, History, and English

Each module has one job, and it does it well.


The Problem Modules Solve

Let's see the nightmare of managing a project without modules:

Problem 1: Name Collisions

// Two developers working on different features

// Developer A
function calculate() {
  // Price calculation logic
  return price * tax;
}

// Developer B
function calculate() {
  // Distance calculation logic
  return distance / speed;
}

// Which calculate() gets used? 
// The LAST one defined! 💥

Problem 2: Global Pollution

// Everything is in the global scope
let cartTotal = 0;     // Anyone can accidentally change this
let userName = "Mohit"; // Could be overwritten
let isLoggedIn = false; // No privacy

// Some random script somewhere
cartTotal = "hacked!"; // Oops, now everything breaks

Problem 3: No Organization

// To find where a function is defined, you need to:
// 1. Open the giant file
// 2. Ctrl+F (Command+F)
// 3. Scroll through 2000 lines
// 4. Hope you found the right one

Problem 4: Unused Code

// You wrote 50 helper functions
function helper1() { ... }
function helper2() { ... }
// ... 48 more helpers

// But you only use 3 of them
// The rest are dead weight in your final bundle

Modules fix all of this.


How Modules Work: The Import/Export Dance

Creating an Export (Giving Permission)

You can export code in two ways: named exports and default exports.

Named Exports (Multiple per file)

// math.js

// Export individual values
export const PI = 3.14159;
export const E = 2.71828;

// Export functions
export function add(a, b) {
  return a + b;
}

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

// Or export at the bottom (cleaner style)
const subtract = (a, b) => a - b;
const divide = (a, b) => a / b;

export { subtract, divide };

Default Export (One per file)

// calculator.js

// A default export is the "main thing" this file provides
export default function calculator(operation, a, b) {
  switch(operation) {
    case 'add': return a + b;
    case 'subtract': return a - b;
    case 'multiply': return a * b;
    case 'divide': return a / b;
    default: return null;
  }
}

// You can also have named exports alongside a default export
export const version = "1.0.0";
export const author = "Mohit";

Importing (Using What Others Shared)

Importing Named Exports

// app.js

// Option 1: Import specific things
import { add, multiply, PI } from './math.js';

console.log(add(5, 3));     // 8
console.log(multiply(4, 2)); // 8
console.log(PI);             // 3.14159

// Option 2: Import everything under a namespace
import * as MathUtils from './math.js';

console.log(MathUtils.add(5, 3));      // 8
console.log(MathUtils.subtract(10, 4)); // 6
console.log(MathUtils.PI);              // 3.14159

// Option 3: Import with alias (rename)
import { add as sum, multiply as times } from './math.js';

console.log(sum(5, 3));   // 8
console.log(times(4, 2)); // 8

Importing Default Exports

// app.js

// Default exports can be imported with ANY name
import calculate from './calculator.js';
// Or
import doMath from './calculator.js';
// Or
import calc from './calculator.js';

console.log(calculate('add', 10, 5));      // 15
console.log(calculate('multiply', 3, 4));  // 12

// Import both default AND named exports
import calculate, { version, author } from './calculator.js';

console.log(calculate('add', 5, 3)); // 8
console.log(version);                 // "1.0.0"
console.log(author);                  // "Mohit"

Named vs Default Exports: When to Use Which

Feature Named Export Default Export
Per file Multiple One
Import syntax { name } Any name
Autocomplete ✅ Yes (IDEs know the name) ❌ No (you choose the name)
Refactoring Easy (rename everywhere) Hard (other files choose names)
Best for Utilities, helpers Main component, main class
Example export const add = ... export default Calculator

Quick Rule of Thumb

// Use DEFAULT export when the file has ONE main purpose
// Example: A component, a class, a single function

// user.js
export default class User { ... }

// Use NAMED exports when the file provides multiple utilities
// Example: Helper functions, constants, tools

// utils.js
export const formatDate = () => { ... };
export const validateEmail = () => { ... };
export const API_URL = "https://api.example.com";

Benefits of Modular Code

Benefit Without Modules With Modules
Organization Everything in 1 file Separate files by feature
Reusability Copy-paste code Import the same module anywhere
Collaboration Merge conflicts everywhere Work on separate files
Testing Test everything together Test modules independently
Debugging "Where is this defined?" Clear file = clear location
Tree Shaking Can't remove unused code Bundlers remove unused exports

Common Beginner Mistakes

❌ Forgetting the type="module" in HTML

<!-- WRONG - won't work -->
<script src="app.js"></script>

<!-- RIGHT -->
<script type="module" src="app.js"></script>

❌ Using .js without the extension in imports

// WRONG (in browser environments)
import { add } from './math';

// RIGHT
import { add } from './math.js';

❌ Mixing default and named import syntax incorrectly

// WRONG
import { calculate } from './calculator.js'; // calculate is default export!

// RIGHT - default import
import calculate from './calculator.js';

// OR - named import (if it was named export)
import { calculate } from './calculator.js';

❌ Trying to import without exporting

// utils.js
function secretHelper() {
  // Not exported!
}

// app.js
import { secretHelper } from './utils.js'; // ERROR: not exported