Skip to content

Export and Import

This lesson explains Export and Import with clear examples, use cases, and best practices so you can use modern JavaScript confidently in real projects.

ES6 Modules Overview

ES6 introduced Modules, allowing JavaScript code to be split into reusable files. Modules help organize applications by exporting variables, functions, classes, and objects from one file and importing them into another.

Modern frameworks such as React, Angular, Vue, Next.js, Astro, Svelte, Node.js, and Vite rely heavily on ES Modules.

Keyword Purpose
export Expose values from a module.
import Use exported values from another module.
Named Export Export multiple values.
Default Export Export one primary value.
Dynamic Import Load modules on demand.

Why Use ES Modules?

  • Organize code into reusable files.
  • Avoid global variables.
  • Improve maintainability.
  • Enable code splitting.
  • Support tree shaking.
  • Improve application performance.
  • Encourage reusable architecture.
  • Work seamlessly with modern frameworks.

Named Export

// math.js

export const pi =
  3.14159;

export function add(

  a,

  b

) {

  return a + b;

}

export function subtract(

  a,

  b

) {

  return a - b;

}

Named exports allow multiple values to be exported from the same module.

Import Named Exports

// app.js

import

{

  pi,

  add,

  subtract

}

from "./math.js";

console.log(pi);

console.log(
  add(5, 3)
);

console.log(
  subtract(8, 2)
);

Export Variables

export const company =
  "OpenAI";

export let version =
  1;

Export Functions

export function greet(

  name

) {

  return "Hello " + name;

}

Export Classes

export class User {

  constructor(name) {

    this.name =
      name;

  }

}

Export Multiple Items Together

const first =
  "John";

const second =
  "David";

function greet() {

  return "Hello";

}

export

{

  first,

  second,

  greet

};

Rename Named Exports

function calculate() {

}

export

{

  calculate as mathHelper

};

Import Using Aliases

import

{

  mathHelper as calculate

}

from "./math.js";

Import Everything

import

* as MathUtils

from "./math.js";

console.log(
  MathUtils.pi
);

console.log(
  MathUtils.add(
    5,
    8
  )
);

Default Export

// logger.js

export default function log(

  message

) {

  console.log(message);

}

Every module can have only one default export.

Import Default Export

import log

from "./logger.js";

log(
  "Application Started"
);

Default Export Class

export default class User {

  constructor(name) {

    this.name =
      name;

  }

}

Import Default Class

import User

from "./User.js";

const user =
new User("Alice");

Default and Named Exports Together

export default class User {

}

export const version =
  "2.0";

export function login() {

}

Import Default and Named Exports

import User,

{

  version,

  login

}

from "./User.js";

Re-export Modules

export

*

from "./math.js";

export

*

from "./date.js";

Re-exporting is useful when creating a central module index.

Barrel File Example

// index.js

export

{

  add,

  subtract

}

from "./math.js";

export

{

  User

}

from "./User.js";

Import from Barrel File

import

{

  add,

  User

}

from "./index.js";

Dynamic Import

const module =

await import(
  "./math.js"
);

console.log(
  module.add(
    5,
    10
  )
);

Dynamic imports load modules only when required.

Module Side Effects

import
"./styles.js";

Sometimes a module is imported only to execute its code.

Browser Module

<script

type="module"

src="app.js">

</script>

Browsers require type="module" to load ES modules.

Node.js Module

{

  "type": "module"

}

Node.js enables ES Modules by setting the package type to module.

Named Export vs Default Export

Named Export Default Export
Multiple per file. Only one per file.
Imported with braces. No braces.
Name must match. Any import name is allowed.
Supports aliases. Supports aliases naturally.
Good for utilities. Good for main module export.

Real-World Folder Structure

src/

├── app.js

├── components/

│   ├── Button.js

│   └── Card.js

├── services/

│   └── api.js

├── utils/

│   ├── math.js

│   └── date.js

└── index.js

Common Use Cases

  • React applications.
  • Node.js projects.
  • Reusable utility libraries.
  • API service layers.
  • Component libraries.
  • Design systems.
  • Micro frontends.
  • Enterprise applications.
  • Code splitting.
  • Package development.

Common Mistakes

  • Using braces with default imports.
  • Forgetting braces for named imports.
  • Multiple default exports in one file.
  • Wrong file paths.
  • Mixing CommonJS and ES Modules.
  • Forgetting type="module" in browsers.
  • Incorrect import names.
  • Circular module dependencies.
  • Exporting unnecessary values.
  • Ignoring tree shaking opportunities.

Best Practices

  • Prefer named exports for utility modules.
  • Use default exports for primary components.
  • Keep modules focused on one responsibility.
  • Group related exports.
  • Use barrel files for large projects.
  • Use dynamic imports for lazy loading.
  • Avoid circular dependencies.
  • Organize folders logically.
  • Export only public APIs.
  • Use descriptive file names.

Interview Questions

  • What are ES Modules?
  • What is the difference between named and default exports?
  • Can a module have multiple default exports?
  • When should you use named exports?
  • How do you import all exports from a module?
  • What is a barrel file?
  • What is tree shaking?
  • What is dynamic import?
  • How do ES Modules differ from CommonJS?
  • What are circular dependencies?

Pro Tip

Modern JavaScript applications typically use named exports for utility functions and shared libraries because they support better auto-completion, tree shaking, and refactoring. Use default exports for a module's primary component or class, and organize large projects with barrel files and dynamic imports for optimal maintainability and performance.