Load page modules on-demand as users navigate:
// router.js
export class Router {
constructor() {
this.routes = new Map();
}
register(path, loader) {
this.routes.set(path, loader);
}
async navigate(path) {
const loader = this.routes.get(path);
if (loader) {
const module = await loader();
return module.default;
}
throw new Error(`Route not found: ${path}`);
}
}
// app.js
import { Router } from './router.js';
const router = new Router();
router.register('/', () => import('./pages/home.js'));
router.register('/about', () => import('./pages/about.js'));
router.register('/contact', () => import('./pages/contact.js'));
// Navigate
const page = await router.navigate(window.location.pathname);
page.render();
Reusable API client as a singleton:
// api-client.js
export class APIClient {
constructor(baseURL) {
this.baseURL = baseURL;
}
async get(endpoint) {
const response = await fetch(`${this.baseURL}${endpoint}`);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
}
async post(endpoint, data) {
const response = await fetch(`${this.baseURL}${endpoint}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
}
}
// Create singleton instance
export const api = new APIClient('https://api.example.com');
// Usage in other files
import { api } from './api-client.js';
const users = await api.get('/users');
const newUser = await api.post('/users', { name: 'John' });
Conditionally load features based on flags:
// config.js
export const features = {
darkMode: true,
analytics: false,
betaFeatures: true
};
// app.js
import { features } from './config.js';
// Load features conditionally
if (features.darkMode) {
const { enableDarkMode } = await import('./dark-mode.js');
enableDarkMode();
}
if (features.analytics) {
const { initAnalytics } = await import('./analytics.js');
initAnalytics();
}
if (features.betaFeatures) {
const { loadBetaFeatures } = await import('./beta.js');
loadBetaFeatures();
}
Simple reactive state management:
// store.js
class Store {
constructor(initialState = {}) {
this.state = initialState;
this.listeners = new Set();
}
getState() {
return this.state;
}
setState(updates) {
this.state = { ...this.state, ...updates };
this.notify();
}
subscribe(listener) {
this.listeners.add(listener);
return () => this.listeners.delete(listener);
}
notify() {
this.listeners.forEach(listener => listener(this.state));
}
}
export const store = new Store({ count: 0, user: null });
// component.js
import { store } from './store.js';
store.subscribe(state => {
console.log('State updated:', state);
});
store.setState({ count: 1 });
Extensible plugin architecture:
// plugin-manager.js
const plugins = [];
export function registerPlugin(plugin) {
if (plugin.name && plugin.init) {
plugins.push(plugin);
console.log(`Plugin registered: ${plugin.name}`);
}
}
export async function initializePlugins() {
for (const plugin of plugins) {
await plugin.init();
}
}
export function getPlugins() {
return plugins;
}
// plugins/logger.js
import { registerPlugin } from '../plugin-manager.js';
registerPlugin({
name: 'logger',
init() {
console.log('Logger plugin initialized');
}
});
// plugins/auth.js
import { registerPlugin } from '../plugin-manager.js';
registerPlugin({
name: 'auth',
async init() {
console.log('Auth plugin initialized');
}
});
// main.js
import './plugins/logger.js';
import './plugins/auth.js';
import { initializePlugins } from './plugin-manager.js';
await initializePlugins();
Watch all 6 ES Module patterns execute live in your browser. See real imports, exports, and execution flow. Click "Edit in CodePen" to modify and experiment!