Skip to main content

Command Palette

Search for a command to run...

JavaScript Modules: Import and Export Explained

Updated
โ€ข5 min readโ€ขView as Markdown
JavaScript Modules: Import and Export Explained
S
A software engineer who work across the Full Stack. Having adept skills on coding and product management

Why modules are needed

Before ES6 (ECMAScript 2015), JavaScript did not have a native way to split code across multiple files. All variables were dumped into the global scope, which often caused problems like naming collisions and messy code.

To solve this problem, modules was introduced to share code in multiple files by giving each file it's own private scope.

You have to explicitly export it from one file and export in from another

Exporting functions or values

Sharing Your Code

There are two ways in which we can share our code using the standard of modules

Named Exports and Default Exports.

You can export variables, functions, or classes.

A) Named Exports

Name exports when you want to exports multiple things at once. They are convenient when you are working in file and you can export a function or a variable one by one.

  1. Inline exports
// math.js
export const pi = 3.14159;

export function add(a, b) {
  return a + b;
}
  1. Group exports

Or, You can use second method of named exports which is exporting everything at once at the end of the file.

// math.js
const pi = 3.14159;
function add(a, b) {
  return a + b;
}

export { pi, add }; // Exporting everything together at the end

Helps in larger code files

This is all of export TYPE 1.

B) Default Exports

Default exports are solely use for single file exports. Where you only have a one main purpose or a single primary value to share.

One file can only have a single default export

// User.js
export default class User {
  constructor(name) {
    this.name = name;
  }
  
  greet() {
    console.log(`Hello, I am ${this.name}`);
  }
}
๐Ÿ’ก
Note: You can mix one default export and multiple named exports in the same file, though it's generally best practice to keep files focused.

Importing modules

Bringing Code In

How you import the code depends entirely on how it was exported.

A) Importing Name Exports

When you are using name imports and exports, the names must match exactly. and you must wrap them in curly braces {} .

// app.js
import { pi, add } from './math.js';

console.log(pi); // 3.14159
console.log(add(2, 3)); // 5

=> Renaming Named Imports (Aliasing): If you already have a variable with the same name in your file, you can rename the import using the as keyword.

import { add as addNumbers } from './math.js';

console.log(addNumbers(5, 5)); // 10

B) Default Imports

When importing a default exports no need to add curly braces.

As you only have a single export per file while using default import & exports

// app.js
import User from './User.js'; 
// We could also call it "import MyUser from './User.js';"

const myUser = new User('Alice');
myUser.greet(); // "Hello, I am Loid Forger"

Default vs named exports

Feature Named Exports Default Exports
Quantity Unlimited per file Only one per file
Export Syntax export const signIn = ... export default myVar
Import Syntax Requires curly braces {} No curly braces used
Import Name Must match the exported name Can be any name you choose

Benefits of modular code

  • Improves reusability: Can import everywhere from a single source of truth

  • Maintainability: Create less mess in code.

  • Separation of concerns: Helps in catching bugs fast

  • Fast and reliable

The HTML Browser Catch

If you are writing vanilla JavaScript for the browser (not using a bundler like Webpack or Vite), you must tell the browser that your JavaScript file is a module.

You do this by adding type="module" to your script tag in the HTML file:

HTML

<body>
  <h1>My Module Blog</h1>
  
  <script type="module" src="app.js"></script>
</body>

Importing everything at Once

If a file has a lot of named exports, you can import them all as a single object using the * (wildcard) syntax.

// app.js
import * as MathUtils from './math.js';

console.log(MathUtils.pi);
console.log(MathUtils.add(10, 20));

Conclusion

In short, ES6 modules solve the global-scope problems of older JavaScript by giving each file its own private scope and requiring explicit exports and imports. You can share code in two main ways:

  • Named exports โ€” export multiple values from a file (inline or grouped at the end). Use when a module exposes several utilities: export function a() {}, export { a, b }.

  • Default export โ€” export a single main value from a file: export default MyComponent. One file can have at most one default export.

You can also combine them: a file may have one default export plus any number of named exports. When importing, use import name from './mod.js' for defaults and import { name } from './mod.js' for named exports.

Practical tips

  • Prefer named exports for libraries and utility modules (better tooling, clearer API, and tree-shaking).

  • Use default exports for modules that have a single primary responsibility (e.g., a React component).

  • Keep exports focused and consistent; consider index (barrel) files for cleaner imports in larger projects.

  • Rely on modules to avoid global variables and make your code easier to maintain and reason about.

Mastering export/import patterns and using modules consistently will make your codebase cleaner, safer, and easier to scale.

Consistency and Persistence all you need!

written by theadroitdev(Shivam Verma) :)

๐ŸŒ โ†’ https:/theadroitdev.com/

X โ†’ https://x.com/theadroitdev

Github โ†’ https://github.com/TheAdroitDev

ChaiCode Repo โ†’ https://github.com/TheAdroitDev/ChaiCode-Cohort-2026