DEV Community

Harman Panwar
Harman Panwar

Posted on

JavaScript Modules Explained: From Chaos to Clean Code

If you've ever opened a JavaScript file and found 3,000 lines of tangled functions, global variables clashing with each other, and no clear structure — you already understand why modules exist, even if you haven't used them yet.

Modules are one of the most important concepts in modern JavaScript. They solve a fundamental problem: how do you split your code into organized, reusable, and maintainable pieces without everything falling apart?

In this guide, we'll start from the problem modules solve, then walk through how to export, import, and structure your code like a professional developer. No bundler configuration. No framework abstractions. Just vanilla JavaScript and the module system built into the language itself.


Table of Contents

  1. The Problem: Why Your Code Falls Apart Without Modules
  2. What Are JavaScript Modules?
  3. Setting Up Your First Module
  4. Exporting: Sharing Code From a Module
  5. Importing: Using Code From Other Modules
  6. Default Exports vs Named Exports
  7. When to Use Default vs Named Exports
  8. Re-Exporting: Cleaning Up Your Import Paths
  9. Benefits of Modular Code
  10. Common Mistakes and Gotchas
  11. Wrapping Up

The Problem: Why Your Code Falls Apart Without Modules

Let's paint a realistic picture. You're building a small web app — maybe a task manager. In the beginning, everything lives in one file:


javascript
// app.js — the "everything" file

let tasks = [];
let currentFilter = "all";

function addTask(title) {
  const task = { id: Date.now(), title, completed: false };
  tasks.push(task);
  renderTasks();
}

function deleteTask(id) {
  tasks = tasks.filter((task) => task.id !== id);
  renderTasks();
}

function toggleTask(id) {
  const task = tasks.find((task) => task.id === id);
  if (task) task.completed = !task.completed;
  renderTasks();
}

function renderTasks() {
  const list = document.getElementById("task-list");
  list.innerHTML = "";
  const filtered = filterTasks(tasks, currentFilter);
  filtered.forEach((task) => {
    const li = document.createElement("li");
    li.textContent = task.title;
    if (task.completed) li.classList.add("done");
    list.appendChild(li);
  });
}

function filterTasks(tasks, filter) {
  if (filter === "active") return tasks.filter((t) => !t.completed);
  if (filter === "completed") return tasks.filter((t) => t.completed);
  return tasks;
}

// ... 200 more lines for event handlers, localStorage, date formatting, etc.
Enter fullscreen mode Exit fullscreen mode

Top comments (0)