ES Modules: import export and dynamic import
Use named exports, default exports, namespace imports, and lazy-load code with dynamic import() for performance.
ES Modules: import export and dynamic import is a free Frontend Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Frontend Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Review: ES Module Basics
ES Modules give every file its own scope. Named exports share specific values; default exports share the primary value. The bundler or browser resolves imports at load time.
// Named exports
export const API_BASE = '/api/v1';
export function formatDate(d) { return d.toISOString().slice(0, 10); }
// Default export
export default class ApiClient {
constructor(base = API_BASE) { this.base = base; }
}Tree Shaking — Why Named Exports Matter
Bundlers (Rollup, esbuild, Vite) eliminate unused exports. If you import only { formatDate }, the bundler removes everything else from the bundle. Named exports enable tree shaking; import * as utils can prevent it.
// consumers/report.js — only needs formatDate
import { formatDate } from './utils.js';
// Bundler omits API_BASE and ApiClient from this chunkDynamic import() — Lazy Loading
Dynamic import() returns a Promise. The module is fetched only when the code runs. Bundlers split these into separate chunks automatically.
// Only load the heavy charting library when needed:
const showChart = async () => {
const { Chart } = await import('./Chart.js');
new Chart(canvas, config);
};
btn.addEventListener('click', showChart);Dynamic import with Error Handling
Wrap dynamic imports in try/catch to handle network failures or missing modules gracefully.
try {
const module = await import('./optional-feature.js');
module.activate();
} catch (err) {
console.warn('Optional feature unavailable:', err.message);
}import.meta
import.meta contains metadata about the current module. Key properties: import.meta.url (absolute URL), import.meta.env (Vite env vars), import.meta.resolve().
// Get the directory of this module:
const dir = new URL('.', import.meta.url).pathname;
// Vite env vars:
const API_URL = import.meta.env.VITE_API_URL;
const isProd = import.meta.env.PROD;Module Execution — Once
ES Modules are evaluated once regardless of how many times they are imported. All imports of the same module share the same instance. This makes modules great for singletons (stores, event buses).
// store.js — evaluated once
const state = { count: 0 };
export const increment = () => state.count++;
export const getCount = () => state.count;
// Any file that imports from store.js gets the same state instanceCircular Dependencies
Two modules can import each other. JavaScript handles this, but values may be undefined at first use due to the order of evaluation. Restructure to avoid cycles in most cases.
Type-Only Imports in TypeScript
Use import type { ... } to import types only. These are erased at compile time and never appear in the output bundle. Use them to avoid circular dependencies caused by type-only references.
import type { User } from './types.js';
function greet(user: User): string {
return `Hello, ${user.name}`;
}Re-exporting and Barrel Files
A barrel file re-exports from multiple modules, creating a convenient single import point. Be careful with barrel files in large apps — they can hinder tree shaking.
// components/index.ts
export { Button } from './Button';
export { Input } from './Input';
export type { ButtonProps } from './Button';
// Consumer:
import { Button, Input } from '@/components';Script type=module in the Browser
Add type="module" to a script tag to enable ES module syntax directly in the browser — without a bundler. Modules are deferred by default and have their own scope.
<script type="module">
import { greet } from './utils.js';
greet('World');
</script>CommonJS vs ESM Interoperability
Node.js supports both. ESM files use .mjs or set "type": "module" in package.json. When consuming CommonJS packages from ESM, the default export is the module.exports value. Bundlers handle this transparently.
Quick Check
What is the main performance benefit of using named exports over a single default export object?
Recap: ES Modules Deep Dive
Modules execute once; all importers share the same instance. Tree shaking removes unused named exports. Dynamic import() enables lazy loading and code splitting. import.meta gives module context. Barrel files are convenient but can hurt tree shaking. type-only imports in TypeScript produce no output.
Frequently asked questions
Is the “ES Modules: import export and dynamic import” lesson free?
Yes — the full text of “ES Modules: import export and dynamic import” is free to read here on the web, and the Frontend Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Frontend Academy course, upgrade to CoddyKit PRO.
What will I learn in “ES Modules: import export and dynamic import”?
Use named exports, default exports, namespace imports, and lazy-load code with dynamic import() for performance. You practise Frontend Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Frontend Academy?
No prior experience is required. Frontend Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “ES Modules: import export and dynamic import” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Frontend Academy lesson?
Yes. Every Frontend Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- ES Modules: import export and dynamic import
- npm and package.json: dependencies scripts
- Vite: dev server and build
- Bundling Concepts: tree shaking code splitting