Skip to content

JavaScript Tutorial Modules

Named Exports and Imports

Lesson 167 of 258 2 min read By Deepak Paswan Updated Oct 4, 2026

A module shares things with the export keyword, and another module takes them with import.

Exporting

Put export in front of a declaration:

utils.js
JS
export const TAX_RATE = 0.2;

export function addTax(price) {
  return price * (1 + TAX_RATE);
}

export class Cart {
  items = [];
}

Or list the exports at the bottom:

utils.js
JS
const TAX_RATE = 0.2;
function addTax(price) { return price * (1 + TAX_RATE); }

export { TAX_RATE, addTax };

Anything not exported stays private to the module.

Importing

main.js
JS
import { addTax, TAX_RATE } from "./utils.js";

console.log(addTax(100)); // 120
  • The names in { } must match what was exported.
  • The path starts with ./ or ../ for your own files, and includes the .js extension in browsers.
  • Imports are hoisted: they are processed before the module runs, and always at the top level of the file.

Try it

index.html
HTML
<script type="module">
  // Module "utils" (normally its own file)
  const utilsSource = "data:text/javascript," + encodeURIComponent(`
    export const TAX_RATE = 0.2;
    export function addTax(price) { return price * (1 + TAX_RATE); }
    const secret = "not exported";
  `);

  const { addTax, TAX_RATE } = await import(utilsSource);
  console.log(addTax(100));    // → 120
  console.log(TAX_RATE);       // → 0.2
</script>

(This demo uses dynamic import() because the module source lives in a variable. In a real project you would write import { addTax } from "./utils.js" at the top.)

Namespace import

Import everything under one name with * as:

script.js
JS
import * as utils from "./utils.js";

utils.addTax(100);
utils.TAX_RATE;

Imports are read-only live bindings

An imported name is a view of the exporting module’s variable. You cannot assign to it from outside, but if the exporting module changes it, the importer sees the new value.

counter.js
JS
export let count = 0;
export function increment() { count++; }
main.js
JS
import { count, increment } from "./counter.js";

console.log(count);   // 0
increment();
console.log(count);   // 1  (the live binding updated)
// count = 5;         // TypeError: Assignment to constant variable

Side-effect imports

script.js
JS
import "./setup.js";     // runs the module, imports nothing

A module runs once

No matter how many files import it, a module’s top-level code runs one time, and everyone shares the same instance. That makes modules a natural place for shared settings or a single store. See Module Scope.

lightbulb
Prefer named exports
They make renaming and searching easier, and editors can auto-import them. Default exports have their own use.