JavaScript Modules – import, export, and Code Organization

Modular JavaScript: Writing Clean, Maintainable, and Scalable Code

As JavaScript applications grow in size and complexity, organizing code into modules becomes essential. ES6 introduced a native module system that allows developers to break code into separate files and reuse it with clean import and export syntax.

In this module, we’ll explore what modules are, how they work, and best practices to use them effectively.


Table of Contents

  1. What Are Modules in JavaScript?
  2. Benefits of Using Modules
  3. export Statement
  4. import Statement
  5. Default Exports vs Named Exports
  6. Combining Named and Default Exports
  7. Modules in Browser vs Node.js
  8. Using Modules in HTML
  9. Module Scope
  10. Best Practices
  11. Conclusion

1. What Are Modules in JavaScript?

A module is a file that contains reusable code. Instead of putting everything in one file, you split logic across multiple files and import/export functionality as needed.


2. Benefits of Using Modules

  • Encourages code reuse
  • Improves readability and maintainability
  • Avoids global scope pollution
  • Enables lazy loading and better performance
  • Facilitates team collaboration

3. export Statement

To make something available outside a file, you use export.

// math.js
export const add = (a, b) => a + b;
export const multiply = (a, b) => a * b;

You can export variables, functions, or classes.


4. import Statement

To use exported code in another file:

// main.js
import { add, multiply } from './math.js';

console.log(add(2, 3)); // 5
console.log(multiply(4, 5)); // 20

The file path must be relative and include the .js extension when used in browsers.


5. Default Exports vs Named Exports

Named Export (can export multiple things):

export const greet = () => console.log("Hi");
export const PI = 3.14;

Import like:

import { greet, PI } from './utils.js';

Default Export (only one per file):

// logger.js
export default function log(msg) {
console.log(msg);
}

Import like:

import log from './logger.js';

You can name the default import anything.


6. Combining Named and Default Exports

// lib.js
export const version = "1.0.0";
export default function sayHello() {
console.log("Hello!");
}
// main.js
import sayHello, { version } from './lib.js';

7. Modules in Browser vs Node.js

  • Browser: Use ES Modules with <script type="module">.
  • Node.js: Use import/export in .mjs files or enable "type": "module" in package.json.
<!-- index.html -->
<script type="module" src="main.js"></script>

Modules are deferred by default, so no need to add defer.


8. Using Modules in HTML

If you’re working with front-end JavaScript:

<!-- main.js -->
import { sayHi } from './greetings.js';
sayHi("Ravi");
<!-- index.html -->
<script type="module" src="main.js"></script>

Make sure your files are served over HTTP (not just opened with file://) due to CORS restrictions.


9. Module Scope

Every module has its own scope. Variables and functions defined inside a module are not accessible outside unless explicitly exported.

// helper.js
const secret = "12345"; // not exported
export const reveal = () => "The secret is hidden.";

10. Best Practices

  • Group related functions into modules.
  • Use default export for primary functionality and named exports for helpers.
  • Keep module files small and focused.
  • Avoid circular dependencies.
  • Use index files to simplify imports.

Example index.js:

export * from './math.js';
export * from './string.js';

Now import everything from one place:

import { add, capitalize } from './utils/index.js';

11. Conclusion

JavaScript modules bring structure and reusability to your codebase. They’re essential for building modern applications, and you’ll find them in every serious JavaScript project.

Next up: JavaScript Event Loop, Call Stack, and Concurrency Explained