Advanced Frontend Architecture Patterns

1. Micro-Frontend Module Federation

Split large applications into independently deployable micro-frontends that can be developed, tested, and deployed by separate teams.

Approach Technology Benefits Challenges
Module Federation Webpack 5 Runtime integration, shared dependencies Complex configuration
Iframe Approach Native iframe Complete isolation, simple Poor performance, communication overhead
Web Components Custom Elements Framework agnostic, standards-based Styling isolation issues
Single-SPA Single-SPA framework Framework agnostic orchestration Learning curve, complexity

Example: Webpack Module Federation setup

// Host app (shell) - webpack.config.js
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: 'host',
      remotes: {
        // Load remote apps
        app1: 'app1@http://localhost:3001/remoteEntry.js',
        app2: 'app2@http://localhost:3002/remoteEntry.js'
      },
      shared: {
        // Share dependencies
        react: { singleton: true, requiredVersion: '^18.0.0' },
        'react-dom': { singleton: true, requiredVersion: '^18.0.0' }
      }
    })
  ]
};

// Remote app 1 - webpack.config.js
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: 'app1',
      filename: 'remoteEntry.js',
      exposes: {
        // Expose components
        './Button': './src/components/Button',
        './Dashboard': './src/pages/Dashboard'
      },
      shared: {
        react: { singleton: true },
        'react-dom': { singleton: true }
      }
    })
  ]
};

// Host app - Load remote component
import React, { lazy, Suspense } from 'react';

const RemoteDashboard = lazy(() => import('app1/Dashboard'));
const RemoteButton = lazy(() => import('app1/Button'));

function App() {
  return (
    <div>
      <h1>Host Application</h1>
      <Suspense fallback="Loading Dashboard...">
        <RemoteDashboard />
      </Suspense>
      <Suspense fallback="Loading Button...">
        <RemoteButton />
      </Suspense>
    </div>
  );
}

Example: Vite Module Federation with plugin

// Installation
npm install -D @originjs/vite-plugin-federation

// Host app - vite.config.ts
import { defineConfig } from 'vite';
import federation from '@originjs/vite-plugin-federation';

export default defineConfig({
  plugins: [
    federation({
      name: 'host-app',
      remotes: {
        remoteApp: 'http://localhost:3001/assets/remoteEntry.js'
      },
      shared: ['react', 'react-dom']
    })
  ],
  build: {
    target: 'esnext',
    minify: false
  }
});

// Remote app - vite.config.ts
export default defineConfig({
  plugins: [
    federation({
      name: 'remote-app',
      filename: 'remoteEntry.js',
      exposes: {
        './Button': './src/components/Button',
        './Header': './src/components/Header'
      },
      shared: ['react', 'react-dom']
    })
  ],
  build: {
    target: 'esnext'
  }
});

// Host usage
import { lazy } from 'react';

const RemoteButton = lazy(() => import('remoteApp/Button'));

function App() {
  return <RemoteButton />;
}

Example: Communication between micro-frontends

// Shared event bus for communication
// eventBus.ts
class EventBus {
  private events: Map<string, Function[]> = new Map();
  
  subscribe(event: string, callback: Function) {
    if (!this.events.has(event)) {
      this.events.set(event, []);
    }
    this.events.get(event)!.push(callback);
    
    // Return unsubscribe function
    return () => {
      const callbacks = this.events.get(event);
      if (callbacks) {
        const index = callbacks.indexOf(callback);
        if (index > -1) callbacks.splice(index, 1);
      }
    };
  }
  
  publish(event: string, data?: any) {
    const callbacks = this.events.get(event);
    if (callbacks) {
      callbacks.forEach(cb => cb(data));
    }
  }
}

export const eventBus = new EventBus();

// App 1 - Publish event
import { eventBus } from '@shared/eventBus';

function CartComponent() {
  const addToCart = (item: Product) => {
    eventBus.publish('cart:add', { item, quantity: 1 });
  };
  
  return <button onClick={() => addToCart(product)}>Add to Cart</button>;
}

// App 2 - Subscribe to event
import { eventBus } from '@shared/eventBus';
import { useEffect, useState } from 'react';

function CartBadge() {
  const [count, setCount] = useState(0);
  
  useEffect(() => {
    const unsubscribe = eventBus.subscribe('cart:add', (data) => {
      setCount(prev => prev + data.quantity);
    });
    
    return unsubscribe;
  }, []);
  
  return <div>Cart: {count}</div>;
}

// Alternative: Use CustomEvents for cross-app communication
window.dispatchEvent(new CustomEvent('cart:update', { 
  detail: { items: 5 } 
}));

window.addEventListener('cart:update', (e) => {
  console.log('Cart updated:', e.detail);
});
Challenges: Version conflicts in shared dependencies, deployment coordination, testing complexity, increased bundle size. Use only for large-scale apps with multiple teams. Consider monorepo first.

2. Web Components Custom Elements

Create reusable, framework-agnostic components using Web Components standards (Custom Elements, Shadow DOM, HTML Templates).

API Purpose Use Case Browser Support
Custom Elements Define custom HTML tags Reusable components Excellent
Shadow DOM Encapsulated styles and DOM Style isolation Excellent
HTML Templates Reusable DOM fragments Component templates Excellent
Slots Content projection Flexible layouts Excellent

Example: Creating Custom Element with Shadow DOM

// my-button.ts - Custom button component
class MyButton extends HTMLElement {
  private _disabled: boolean = false;
  
  constructor() {
    super();
    // Create Shadow DOM for style encapsulation
    this.attachShadow({ mode: 'open' });
  }
  
  // Observed attributes - trigger attributeChangedCallback
  static get observedAttributes() {
    return ['disabled', 'variant'];
  }
  
  // Lifecycle: Element added to DOM
  connectedCallback() {
    this.render();
    this.addEventListener('click', this.handleClick);
  }
  
  // Lifecycle: Element removed from DOM
  disconnectedCallback() {
    this.removeEventListener('click', this.handleClick);
  }
  
  // Lifecycle: Attribute changed
  attributeChangedCallback(name: string, oldValue: string, newValue: string) {
    if (name === 'disabled') {
      this._disabled = newValue !== null;
    }
    this.render();
  }
  
  handleClick = (e: Event) => {
    if (this._disabled) {
      e.preventDefault();
      e.stopPropagation();
      return;
    }
    // Dispatch custom event
    this.dispatchEvent(new CustomEvent('button-click', {
      bubbles: true,
      composed: true,
      detail: { timestamp: Date.now() }
    }));
  };
  
  render() {
    const variant = this.getAttribute('variant') || 'primary';
    
    this.shadowRoot!.innerHTML = `
      <style>
        :host {
          display: inline-block;
        }
        
        button {
          padding: 12px 24px;
          border: none;
          border-radius: 4px;
          font-size: 16px;
          cursor: pointer;
          transition: all 0.2s;
        }
        
        button.primary {
          background: #007acc;
          color: white;
        }
        
        button.secondary {
          background: #6c757d;
          color: white;
        }
        
        button:hover:not(:disabled) {
          opacity: 0.9;
          transform: translateY(-1px);
        }
        
        button:disabled {
          opacity: 0.5;
          cursor: not-allowed;
        }
      </style>
      <button class="${variant}" ?disabled="${this._disabled}">
        <slot></slot>
      </button>
    `;
  }
}

// Register custom element
customElements.define('my-button', MyButton);

// Usage in HTML
<my-button variant="primary">Click Me</my-button>
<my-button variant="secondary" disabled>Disabled</my-button>

// Usage in JavaScript
const button = document.createElement('my-button');
button.setAttribute('variant', 'primary');
button.textContent = 'Dynamic Button';
button.addEventListener('button-click', (e) => {
  console.log('Clicked at:', e.detail.timestamp);
});
document.body.appendChild(button);

Example: Web Component with Lit library (simplifies creation)

// Installation
npm install lit

// my-card.ts
import { LitElement, html, css } from 'lit';
import { customElement, property } from 'lit/decorators.js';

@customElement('my-card')
export class MyCard extends LitElement {
  @property({ type: String }) title = '';
  @property({ type: String }) subtitle = '';
  @property({ type: Boolean }) loading = false;
  
  // Scoped styles
  static styles = css`
    :host {
      display: block;
      border: 1px solid #ddd;
      border-radius: 8px;
      padding: 16px;
      background: white;
    }
    
    .title {
      font-size: 20px;
      font-weight: bold;
      margin-bottom: 8px;
    }
    
    .subtitle {
      color: #666;
      font-size: 14px;
    }
    
    .loading {
      opacity: 0.6;
    }
  `;
  
  render() {
    return html`
      <div class="${this.loading ? 'loading' : ''}">
        <div class="title">${this.title}</div>
        <div class="subtitle">${this.subtitle}</div>
        <slot></slot>
      </div>
    `;
  }
}

// Usage
<my-card title="Card Title" subtitle="Card subtitle">
  <p>Card content goes here</p>
</my-card>

// React integration
function App() {
  return (
    <my-card 
      title="From React" 
      subtitle="Web Component in React"
    >
      <p>Content</p>
    </my-card>
  );
}

Example: Slots for content projection

// dialog-box.ts
class DialogBox extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
  }
  
  connectedCallback() {
    this.shadowRoot!.innerHTML = `
      <style>
        .dialog {
          border: 1px solid #ccc;
          border-radius: 8px;
          padding: 20px;
          background: white;
          box-shadow: 0 4px 6px rgba(0,0,0,0.1);
        }
        
        .header {
          font-size: 20px;
          font-weight: bold;
          margin-bottom: 12px;
        }
        
        .content {
          margin-bottom: 16px;
        }
        
        .footer {
          display: flex;
          justify-content: flex-end;
          gap: 8px;
        }
      </style>
      
      <div class="dialog">
        <div class="header">
          <slot name="header">Default Header</slot>
        </div>
        <div class="content">
          <slot>Default content</slot>
        </div>
        <div class="footer">
          <slot name="footer"></slot>
        </div>
      </div>
    `;
  }
}

customElements.define('dialog-box', DialogBox);

// Usage with named slots
<dialog-box>
  <span slot="header">Confirm Action</span>
  <p>Are you sure you want to delete this item?</p>
  <div slot="footer">
    <button>Cancel</button>
    <button>Confirm</button>
  </div>
</dialog-box>
When to Use: Design systems shared across multiple frameworks, embeddable widgets, library components. Lit, Stencil, or vanilla Web Components all work. Full framework agnosticism with standards-based approach.

3. Island Architecture Astro Qwik

Ship zero JavaScript by default, hydrate interactive components only when needed for optimal performance.

Framework Approach Hydration Strategy Best For
Astro Islands Architecture Partial, on-demand Content sites, blogs, docs
Qwik Resumability No hydration, resume on interaction Web apps, e-commerce
Next.js Islands Server Components Selective client components Full-stack apps
Marko Automatic partial hydration Component-level eBay's solution

Example: Astro Islands Architecture

// Installation
npm create astro@latest

// src/pages/index.astro
---
import Layout from '../layouts/Layout.astro';
import Counter from '../components/Counter.jsx'; // React component
import Carousel from '../components/Carousel.vue'; // Vue component
---

<Layout title="Astro Islands">
  <h1>Welcome to Astro</h1>
  
  <!-- Static content - no JS shipped -->
  <p>This content is completely static.</p>
  
  <!-- Island 1: Load immediately -->
  <Counter client:load />
  
  <!-- Island 2: Load when visible -->
  <Carousel client:visible />
  
  <!-- Island 3: Load on idle -->
  <Comments client:idle />
  
  <!-- Island 4: Load on media query -->
  <MobileMenu client:media="(max-width: 768px)" />
  
  <!-- No client directive = zero JS -->
  <StaticComponent />
</Layout>

// Hydration directives:
// client:load - Load immediately
// client:idle - Load when browser is idle
// client:visible - Load when scrolled into view
// client:media - Load based on media query
// client:only - Only run on client (skip SSR)

// astro.config.mjs
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';
import vue from '@astrojs/vue';
import svelte from '@astrojs/svelte';

export default defineConfig({
  integrations: [react(), vue(), svelte()],
  output: 'static' // or 'server' for SSR
});

Example: Qwik resumability (no hydration)

// Installation
npm create qwik@latest

// src/routes/index.tsx
import { component$, useSignal } from '@builder.io/qwik';

export default component$(() => {
  const count = useSignal(0);
  
  return (
    <div>
      <h1>Qwik Counter</h1>
      <p>Count: {count.value}</p>
      
      {/* Event handlers are lazy-loaded on interaction */}
      <button onClick$={() => count.value++}>
        Increment
      </button>
    </div>
  );
});

// Key concepts:
// 1. $ suffix - Qwik optimizer boundary
// 2. useSignal - Reactive state
// 3. No hydration - app "resumes" from server state
// 4. Lazy load event handlers only when needed

// src/components/product-list.tsx
import { component$, Resource, useResource$ } from '@builder.io/qwik';

export default component$(() => {
  // Data fetching with suspense
  const products = useResource$(async () => {
    const res = await fetch('/api/products');
    return res.json();
  });
  
  return (
    <Resource
      value={products}
      onPending={() => <div>Loading...</div>}
      onRejected={(error) => <div>Error: {error.message}</div>}
      onResolved={(data) => (
        <ul>
          {data.map((product) => (
            <li key={product.id}>{product.name}</li>
          ))}
        </ul>
      )}
    />
  );
});

// Performance benefits:
// - Instant Time to Interactive (TTI)
// - Progressive interactivity
// - Optimal Core Web Vitals

Example: Astro with React islands for interactivity

// src/components/InteractiveCart.jsx (React)
import { useState } from 'react';

export default function InteractiveCart({ initialItems = [] }) {
  const [items, setItems] = useState(initialItems);
  
  const addItem = (item) => {
    setItems([...items, item]);
  };
  
  const removeItem = (id) => {
    setItems(items.filter(item => item.id !== id));
  };
  
  return (
    <div className="cart">
      <h2>Cart ({items.length})</h2>
      <ul>
        {items.map(item => (
          <li key={item.id}>
            {item.name} - ${item.price}
            <button onClick={() => removeItem(item.id)}>Remove</button>
          </li>
        ))}
      </ul>
    </div>
  );
}

// src/pages/shop.astro
---
import Layout from '../layouts/Layout.astro';
import InteractiveCart from '../components/InteractiveCart.jsx';
import ProductCard from '../components/ProductCard.astro';

const products = await fetch('https://api.example.com/products').then(r => r.json());
---

<Layout title="Shop">
  <!-- Static product grid (no JS) -->
  <div class="products">
    {products.map(product => (
      <ProductCard product={product} />
    ))}
  </div>
  
  <!-- Interactive cart (JS island, loads when visible) -->
  <InteractiveCart client:visible initialItems={[]} />
</Layout>

// Result: Only cart component ships JavaScript
// Products are pure HTML/CSS = instant rendering
Performance Impact: Islands reduce JavaScript by 90%+. Perfect for content-heavy sites. Use Astro for static sites with islands of interactivity. Use Qwik for full web apps with optimal performance.

4. Server Components Next.js 13

React Server Components render on server, reducing client bundle size and enabling direct backend access without APIs.

Component Type Rendering Capabilities Use Case
Server Component Server only Direct DB access, no client JS Static content, data fetching
Client Component Client + Server Hooks, events, browser APIs Interactive UI
Shared Component Both (default) Limited to serializable props Reusable components

Example: Next.js App Router with Server Components

// app/page.tsx - Server Component (default)
import { db } from '@/lib/database';
import ProductList from './ProductList';

// This runs ONLY on the server
export default async function HomePage() {
  // Direct database access (no API route needed)
  const products = await db.product.findMany({
    include: { category: true }
  });
  
  // Can use Node.js APIs
  const fs = require('fs');
  const data = fs.readFileSync('./data.json', 'utf8');
  
  return (
    <div>
      <h1>Products</h1>
      <ProductList products={products} />
    </div>
  );
}

// No JavaScript shipped for this component!

// app/ProductList.tsx - Client Component
'use client'; // Directive to mark as client component

import { useState } from 'react';

export default function ProductList({ products }) {
  const [filter, setFilter] = useState('');
  
  const filtered = products.filter(p => 
    p.name.toLowerCase().includes(filter.toLowerCase())
  );
  
  return (
    <div>
      <input 
        type="text"
        value={filter}
        onChange={(e) => setFilter(e.target.value)}
        placeholder="Filter products..."
      />
      <ul>
        {filtered.map(product => (
          <li key={product.id}>{product.name}</li>
        ))}
      </ul>
    </div>
  );
}

// This ships JavaScript for interactivity

Example: Data fetching patterns with Server Components

// app/dashboard/page.tsx
import { Suspense } from 'react';
import UserStats from './UserStats';
import RecentOrders from './RecentOrders';
import Analytics from './Analytics';

export default function DashboardPage() {
  return (
    <div>
      <h1>Dashboard</h1>
      
      {/* Stream components independently */}
      <Suspense fallback={<div>Loading stats...</div>}>
        <UserStats />
      </Suspense>
      
      <Suspense fallback={<div>Loading orders...</div>}>
        <RecentOrders />
      </Suspense>
      
      <Suspense fallback={<div>Loading analytics...</div>}>
        <Analytics />
      </Suspense>
    </div>
  );
}

// app/dashboard/UserStats.tsx - Server Component
async function UserStats() {
  // Each component fetches its own data
  const stats = await fetch('https://api.example.com/stats', {
    // Next.js extended fetch with caching
    next: { revalidate: 60 } // Revalidate every 60 seconds
  }).then(r => r.json());
  
  return (
    <div className="stats">
      <div>Users: {stats.users}</div>
      <div>Active: {stats.active}</div>
    </div>
  );
}

// app/dashboard/RecentOrders.tsx
async function RecentOrders() {
  const orders = await db.order.findMany({
    take: 10,
    orderBy: { createdAt: 'desc' }
  });
  
  return (
    <ul>
      {orders.map(order => (
        <li key={order.id}>
          Order #{order.id} - ${order.total}
        </li>
      ))}
    </ul>
  );
}

// Parallel data fetching with streaming
// Each Suspense boundary resolves independently

Example: Mixing Server and Client Components

// app/product/[id]/page.tsx - Server Component
import { db } from '@/lib/database';
import AddToCartButton from './AddToCartButton';
import RelatedProducts from './RelatedProducts';

export default async function ProductPage({ params }) {
  const product = await db.product.findUnique({
    where: { id: params.id },
    include: { reviews: true }
  });
  
  return (
    <div>
      {/* Server-rendered content */}
      <h1>{product.name}</h1>
      <p>{product.description}</p>
      <p>Price: ${product.price}</p>
      
      {/* Client component for interactivity */}
      <AddToCartButton productId={product.id} />
      
      {/* Server component for related products */}
      <RelatedProducts categoryId={product.categoryId} />
      
      {/* Server-rendered reviews */}
      <div>
        <h2>Reviews</h2>
        {product.reviews.map(review => (
          <div key={review.id}>
            <strong>{review.author}</strong>
            <p>{review.content}</p>
          </div>
        ))}
      </div>
    </div>
  );
}

// app/product/[id]/AddToCartButton.tsx - Client Component
'use client';

import { useState } from 'react';

export default function AddToCartButton({ productId }) {
  const [loading, setLoading] = useState(false);
  
  const handleAdd = async () => {
    setLoading(true);
    await fetch('/api/cart', {
      method: 'POST',
      body: JSON.stringify({ productId })
    });
    setLoading(false);
  };
  
  return (
    <button onClick={handleAdd} disabled={loading}>
      {loading ? 'Adding...' : 'Add to Cart'}
    </button>
  );
}

// Rules:
// 1. Server components can import client components
// 2. Client components CANNOT import server components directly
// 3. Pass server components as children to client components
Limitations: Cannot use hooks, event handlers, or browser APIs in Server Components. Props must be serializable (no functions). Requires Next.js 13+ App Router. Learning curve for new mental model.

5. Edge Computing Vercel Functions

Deploy serverless functions to edge locations globally for ultra-low latency API responses and dynamic content.

Platform Runtime Cold Start Use Case
Vercel Edge Functions V8 isolates <50ms API routes, middleware
Cloudflare Workers V8 isolates <5ms Edge compute, KV storage
AWS Lambda@Edge Node.js ~100ms CloudFront customization
Netlify Edge Functions Deno <50ms JAMstack edge logic

Example: Vercel Edge Function (Next.js)

// app/api/edge/route.ts
import { NextRequest, NextResponse } from 'next/server';

export const runtime = 'edge'; // Enable Edge Runtime

export async function GET(request: NextRequest) {
  // Access geo location
  const country = request.geo?.country || 'Unknown';
  const city = request.geo?.city || 'Unknown';
  
  // Fast external API call (co-located at edge)
  const data = await fetch('https://api.example.com/data', {
    headers: { 'Authorization': process.env.API_KEY }
  }).then(r => r.json());
  
  return NextResponse.json({
    message: `Hello from ${city}, ${country}!`,
    data,
    edge: true
  });
}

// Edge middleware - runs before every request
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  // Geo-based redirect
  const country = request.geo?.country;
  
  if (country === 'CN' && !request.nextUrl.pathname.startsWith('/cn')) {
    return NextResponse.redirect(new URL('/cn', request.url));
  }
  
  // A/B testing
  const bucket = Math.random() < 0.5 ? 'a' : 'b';
  const response = NextResponse.next();
  response.cookies.set('ab-test', bucket);
  
  // Add custom headers
  response.headers.set('x-edge-location', request.geo?.city || 'Unknown');
  
  return response;
}

export const config = {
  matcher: ['/api/:path*', '/products/:path*']
};

Example: Cloudflare Workers with KV storage

// worker.js
addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  const url = new URL(request.url);
  
  // Check cache first
  const cache = caches.default;
  let response = await cache.match(request);
  
  if (response) {
    return response;
  }
  
  // Access KV storage (ultra-fast key-value store)
  const config = await MY_KV_NAMESPACE.get('config', { type: 'json' });
  
  // Generate response
  response = new Response(JSON.stringify({
    message: 'Hello from Cloudflare Edge',
    config,
    location: request.cf?.city
  }), {
    headers: {
      'content-type': 'application/json',
      'cache-control': 'public, max-age=60'
    }
  });
  
  // Cache response
  event.waitUntil(cache.put(request, response.clone()));
  
  return response;
}

// wrangler.toml
name = "my-worker"
main = "worker.js"
compatibility_date = "2024-01-01"

[[kv_namespaces]]
binding = "MY_KV_NAMESPACE"
id = "your-namespace-id"

// Deploy: npx wrangler deploy

Example: Edge function for personalization

// app/api/personalize/route.ts
import { NextRequest, NextResponse } from 'next/server';

export const runtime = 'edge';

export async function GET(request: NextRequest) {
  // Get user preferences from cookie
  const preferences = request.cookies.get('preferences')?.value;
  const parsed = preferences ? JSON.parse(preferences) : {};
  
  // Geo-based content
  const country = request.geo?.country || 'US';
  const currency = getCurrency(country);
  
  // A/B test variant
  const variant = request.cookies.get('ab-variant')?.value || 'control';
  
  // Time-based personalization
  const hour = new Date().getHours();
  const greeting = hour < 12 ? 'Good morning' : 
                   hour < 18 ? 'Good afternoon' : 'Good evening';
  
  return NextResponse.json({
    greeting,
    currency,
    variant,
    preferences: parsed,
    location: {
      country,
      city: request.geo?.city
    }
  });
}

function getCurrency(country: string): string {
  const currencyMap: Record<string, string> = {
    US: 'USD',
    GB: 'GBP',
    JP: 'JPY',
    DE: 'EUR'
  };
  return currencyMap[country] || 'USD';
}

// Usage in page
async function ProductPrice({ productId }) {
  const personalization = await fetch('/api/personalize').then(r => r.json());
  const price = await getPrice(productId, personalization.currency);
  
  return <div>{price}</div>;
}
Edge Benefits: 50-200ms faster than traditional serverless, global distribution, lower costs at scale. Limitations: No Node.js APIs, limited CPU time (50ms), smaller bundle size. Perfect for API routes, middleware, auth.

6. WebAssembly WASM Integration

Run high-performance compiled code (C, C++, Rust) in the browser at near-native speed for compute-intensive tasks.

Language Toolchain Use Case Performance
Rust wasm-pack, wasm-bindgen CPU-intensive algorithms Near-native
C/C++ Emscripten Porting existing libraries Near-native
AssemblyScript asc (TypeScript-like) TypeScript developers Very fast
Go TinyGo Small WASM binaries Fast

Example: Rust WebAssembly module with wasm-pack

// Installation
cargo install wasm-pack

// Create new Rust project
cargo new --lib image-processor
cd image-processor

// Cargo.toml
[package]
name = "image-processor"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2"

// src/lib.rs
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn fibonacci(n: u32) -> u32 {
    match n {
        0 => 0,
        1 => 1,
        _ => fibonacci(n - 1) + fibonacci(n - 2)
    }
}

#[wasm_bindgen]
pub struct ImageProcessor {
    width: u32,
    height: u32,
}

#[wasm_bindgen]
impl ImageProcessor {
    #[wasm_bindgen(constructor)]
    pub fn new(width: u32, height: u32) -> ImageProcessor {
        ImageProcessor { width, height }
    }
    
    pub fn grayscale(&self, pixels: &mut [u8]) {
        for chunk in pixels.chunks_mut(4) {
            let avg = (chunk[0] as u32 + chunk[1] as u32 + chunk[2] as u32) / 3;
            chunk[0] = avg as u8;
            chunk[1] = avg as u8;
            chunk[2] = avg as u8;
        }
    }
    
    pub fn blur(&self, pixels: &mut [u8], radius: u32) {
        // High-performance blur algorithm
        // ... implementation
    }
}

// Build WASM
// wasm-pack build --target web

// JavaScript usage
// src/App.tsx
import init, { fibonacci, ImageProcessor } from './wasm/image_processor';

async function App() {
  // Initialize WASM module
  await init();
  
  // Use Rust functions
  const result = fibonacci(10);
  console.log('Fibonacci(10):', result);
  
  // Process image
  const processor = new ImageProcessor(800, 600);
  const imageData = ctx.getImageData(0, 0, 800, 600);
  processor.grayscale(imageData.data);
  ctx.putImageData(imageData, 0, 0);
  
  return <div>WASM Loaded</div>;
}

Example: AssemblyScript for TypeScript developers

// Installation
npm install -D assemblyscript

// assembly/index.ts (AssemblyScript - TypeScript-like)
export function add(a: i32, b: i32): i32 {
  return a + b;
}

export function sortArray(arr: Int32Array): void {
  // Efficient sorting in WASM
  for (let i = 0; i < arr.length; i++) {
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[i] > arr[j]) {
        const temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
      }
    }
  }
}

export function processMatrix(
  matrix: Float64Array,
  rows: i32,
  cols: i32
): Float64Array {
  const result = new Float64Array(rows * cols);
  
  for (let i = 0; i < rows; i++) {
    for (let j = 0; j < cols; j++) {
      const idx = i * cols + j;
      result[idx] = matrix[idx] * 2.0;
    }
  }
  
  return result;
}

// Build: npm run asbuild

// JavaScript usage
import { add, sortArray } from './build/release.js';

const result = add(5, 10);
console.log(result); // 15

const arr = new Int32Array([5, 2, 8, 1, 9]);
sortArray(arr);
console.log(arr); // [1, 2, 5, 8, 9]

Example: Real-world WASM use case - Image compression

// imageCompressor.ts - React component using WASM
import { useEffect, useState } from 'react';
import init, { compress_image } from './wasm/image_compressor';

export function ImageCompressor() {
  const [wasmReady, setWasmReady] = useState(false);
  
  useEffect(() => {
    init().then(() => setWasmReady(true));
  }, []);
  
  const handleCompress = async (file: File) => {
    if (!wasmReady) return;
    
    const arrayBuffer = await file.arrayBuffer();
    const uint8Array = new Uint8Array(arrayBuffer);
    
    // Call Rust WASM function
    const compressed = compress_image(uint8Array, 80); // 80% quality
    
    // Create download link
    const blob = new Blob([compressed], { type: 'image/jpeg' });
    const url = URL.createObjectURL(blob);
    
    const a = document.createElement('a');
    a.href = url;
    a.download = 'compressed.jpg';
    a.click();
  };
  
  return (
    <div>
      {wasmReady ? (
        <input 
          type="file" 
          accept="image/*" 
          onChange={(e) => handleCompress(e.target.files[0])}
        />
      ) : (
        <p>Loading WASM module...</p>
      )}
    </div>
  );
}

// Performance comparison:
// JavaScript image compression: ~2000ms
// WASM image compression: ~200ms
// 10x faster!

Advanced Architecture Decision Matrix

Pattern When to Use Benefits Complexity
Micro-Frontends Large orgs, multiple teams, gradual migration Independent deployment, tech diversity High
Web Components Design systems, framework-agnostic libraries Standards-based, reusable everywhere Medium
Islands Architecture Content sites with selective interactivity Minimal JS, excellent performance Low-Medium
Server Components Data-heavy apps, reducing client bundle Zero client JS, direct backend access Medium
Edge Computing Global apps, low-latency requirements Ultra-fast responses, geo-distribution Low-Medium
WebAssembly CPU-intensive tasks, porting existing code Near-native performance High