JavaScript Modules: What they are and How to use them

  

As a JavaScript project grows, the code tends to become long, difficult to read, and complicated to maintain. Putting everything in a single file is not a good practice: it becomes easier to introduce errors and more difficult to reuse the code.

To solve these problems, JavaScript provides modules.

In this article, we'll see:

  • what is a JavaScript module
  • why modules are useful
  • how to export and import code
  • practical examples explained step by step
  • how to use modules in the browser and in Node.js
🔗 Do you like Techelopment? Check out the site for all the details!

What is a module in JavaScript

A module is simply a JavaScript file that:

  • contains isolated code
  • exposes only what it decides to make public
  • can be imported into other files

Each module has its own scope, meaning the variables defined within it are not visible externally unless they are explicitly exported.

👉 This avoids name conflicts and makes the code More secure and organized.


Why use modules

The main advantages of modules are:

1. Code organization

You can separate your code into logical files:

  • a file for mathematical functions
  • a file for user management
  • a file for interface logic

2. Reuse

The same module can be imported into multiple places in the project.

3. Maintainability

If you need to change a feature, you know exactly where to intervene.

4. Avoiding Global Variables

Global variables are one of the most common causes of bugs in JavaScript.


How Modules Work: Export and Import

JavaScript modules are based on two keywords:

  • export → to make something available
  • import → to use something exported from another file

First Simple Example

File: math.js

export function sum(a, b) {
   return a + b;
}

Here we are:

  • creating a sum
  • function
  • exporting it with the export
  • keyword

This means that other files can use it.

File: main.js

import { sum } from "./math.js";

const result = sum(3, 5);
console.log(result);

Here we are:

  1. Importing the sum function from the math.js
  2. Using it as if it were defined in the same file

📌 The parentheses {} are needed because we are importing a named export.


Named exports

export function sum(a, b) {
   return a + b;
}

export function subtract(a, b) {
   return a - b;
}
import { sum, subtract } from "./math.js";

console.log(sum(10, 5));
console.log(subtract(10, 5));

⚠️ Important

You must use the same names used in the export.


Renaming an import

import { sum as addition } from "./math.js";

console.log(addition(2, 3));

This is useful for:

  • avoiding name conflicts
  • making code more readable

Exporting variables and constants

export const PI = 3.14159;
import { PI } from "./math.js";
console.log(PI);

Default export

export default function greet(name) {
   return `Hello, ${name}!`;
}
import greet from "./saluta.js";

console.log(greet("Marco"));

📌 Important note:

  • You don't need {}
  • You choose the name - we could have also written:
    import say_saluta from "./saluta.js";

Difference between normal and default export

Type Number Import
named export more than one with {}
default export only one without {}

Importing an entire module

import * as math from "./math.js";

console.log(math.sum(4, 6));
console.log(math.subtract(8, 3));

Here:

  • math is an object
  • each export becomes a property

Modules in the browser

To use modules in the browser, you must:

  1. use separate files
  2. declare the module type in the script
<script type="module" src="main.js"></script>

📌 Without type="module":

  • import and export do not work

Important features of modules

1. Automatic strict mode

Modules are always in strict mode, even without writing it.

2. Load only once

A module is loaded only once, even if imported multiple times.

3. Mandatory paths

In the browser, you must always write:
"./file.js"
Not just "file.js", but let's look at it in detail.

Why you should write "./file.js" in the browser

When you use JavaScript modules in the browser, each import follows URL rules, not those typical of traditional programming languages ​​(this is the key point to understand).

How the browser interprets an import

When the browser encounters a statement like this:
import { sum } from "file.js";
does not interpret "file.js" as “a file in the same folder”.

Instead, it interprets it as:
  • the name of an external resource
  • a possible package
  • a context-dependent absolute path
As a result, the browser tries to look up the file as if it were a URL, and the result is almost always a loading error.

What does "./file.js" mean

import { sum } from "./file.js";

The ./ prefix explicitly tells the browser:

"Start from the file's folder current”

It's the same logic as file system paths:

  • ./ → current folder
  • ../ → previous folder
  • / → site root

Concrete example

Project structure:

/project
  ├─ index.html
  └─ js
     ├─ main.js
     └─ math.js

Inside main.js:

import { sum } from "./math.js";

In this case:

  • main.js and math.js are in the same folder
  • ./math.js is the pathorretto

What happens if you don't use "./"

If you write:

import { sum } from "math.js";

The browser tries to search for the file as if it were:

https://yoursite.com/math.js

Since the file isn't there, the result is a 404 error.

More complex relative paths

If the file is in a different folder:

import { sum } from "../utils/math.js";

This It means:

  • go up one folder
  • enter the utils
  • folder
  • load math.js

Why "./" is often not needed in Node.js

In Node.js, it's common to see:

import express from "express";

This works because Node.js has a module resolution system that:

  • looks for packages in node_modules
  • recognizes modules by name

The browser, on the other hand:

  • doesn't know node_modules
  • doesn't know what a package is
  • only uploads files via URL

Bundlers and build tools

Tools like Webpack, Vite, or Rollup:

  • mimic Node.js behavior
  • transform imports into real paths
  • allow you to use package names

But this happens before the code reaches the browser.

Key rule to remember

In the browser, every import must be a valid URL.

Valid examples:

  • ./file.js
  • ../file.js
  • /scripts/file.js
  • https://example.com/file.js

Summary

  • The browser uses URLs, not logical names
  • "file.js" alone is not a valid relative path
  • "./file.js" explicitly specifies the current folder
  • Node.js and bundlers follow different rules
  • The path must always be specified in the browser

Real-world example: organizing a project

/src
  ├─ utils.js
  ├─ user.js 
  └─ main.js
// utils.js
export function formatName(name) { 
   return name.toUpperCase();
}
// user.js
import { formatName } from "./utils.js";

export function createUser(name) { 
   return { 
      name: formatName(name) 
   };
}
// main.js
import { createUser } from "./user.js";

const user = createUser("Luca");
console.log(user);

Conclusion

Modules are an essential foundation of modern JavaScript. They allow you to:

  • write cleaner code
  • avoid common mistakes
  • build scalable applications

Understanding modules well means taking a big step forward in JavaScript development, whether for small projects or complex applications.



Follow me #techelopment

Official site: www.techelopment.it
facebook: Techelopment
instagram: @techelopment
X: techelopment
Bluesky: @techelopment
telegram: @techelopment_channel
whatsapp: Techelopment
youtube: @techelopment