Files
awesome-copilot/skills/web-coder/references/architecture-patterns.md
John Haugabook 8fedf95507 new skill web-coder (#881)
* new skill web-coder

* codespellrc: add aNULL HTTPS config cipher string

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Apply suggestions from code review

* Apply suggestion from @jhauga

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-05 21:43:04 +11:00

11 KiB

Architecture & Patterns Reference

Web application architectures, design patterns, and architectural concepts.

Application Architectures

Single Page Application (SPA)

Web app that loads single HTML page and dynamically updates content.

Characteristics:

  • Client-side routing
  • Heavy JavaScript usage
  • Fast navigation after initial load
  • Complex state management

Pros:

  • Smooth user experience
  • Reduced server load
  • Mobile app-like feel

Cons:

  • Larger initial download
  • SEO challenges (mitigated with SSR)
  • Complex state management

Examples: React, Vue, Angular apps

// React Router example
import { BrowserRouter, Routes, Route } from 'react-router-dom';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/products/:id" element={<Product />} />
      </Routes>
    </BrowserRouter>
  );
}

Multi-Page Application (MPA)

Traditional web app with multiple HTML pages.

Characteristics:

  • Server renders each page
  • Full page reload on navigation
  • Simpler architecture

Pros:

  • Better SEO out of the box
  • Simpler to build
  • Good for content-heavy sites

Cons:

  • Slower navigation
  • More server requests

Progressive Web App (PWA)

Web app with native app capabilities.

Features:

  • Installable
  • Offline support (Service Workers)
  • Push notifications
  • App-like experience
// Service Worker registration
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js')
    .then(reg => console.log('SW registered', reg))
    .catch(err => console.error('SW error', err));
}

manifest.json:

{
  "name": "My PWA",
  "short_name": "PWA",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#000000",
  "icons": [
    {
      "src": "/icon-192.png",
      "sizes": "192x192",
      "type": "image/png"
    }
  ]
}

Server-Side Rendering (SSR)

Render pages on server, send HTML to client.

Pros:

  • Better SEO
  • Faster first contentful paint
  • Works without JavaScript

Cons:

  • Higher server load
  • More complex setup

Frameworks: Next.js, Nuxt.js, SvelteKit

// Next.js SSR
export async function getServerSideProps() {
  const data = await fetchData();
  return { props: { data } };
}

function Page({ data }) {
  return <div>{data.title}</div>;
}

Static Site Generation (SSG)

Pre-render pages at build time.

Pros:

  • Extremely fast
  • Low server cost
  • Great SEO

Best for: Blogs, documentation, marketing sites

Tools: Next.js, Gatsby, Hugo, Jekyll, Eleventy

// Next.js SSG
export async function getStaticProps() {
  const data = await fetchData();
  return { props: { data } };
}

export async function getStaticPaths() {
  const paths = await fetchPaths();
  return { paths, fallback: false };
}

Incremental Static Regeneration (ISR)

Update static content after build.

// Next.js ISR
export async function getStaticProps() {
  const data = await fetchData();
  return {
    props: { data },
    revalidate: 60 // Revalidate every 60 seconds
  };
}

JAMstack

JavaScript, APIs, Markup architecture.

Principles:

  • Pre-rendered static files
  • APIs for dynamic functionality
  • Git-based workflows
  • CDN deployment

Benefits:

  • Fast performance
  • High security
  • Scalability
  • Developer experience

Rendering Patterns

Client-Side Rendering (CSR)

JavaScript renders content in browser.

<div id="root"></div>
<script>
  // React renders app here
  ReactDOM.render(<App />, document.getElementById('root'));
</script>

Hydration

Attach JavaScript to server-rendered HTML.

// React hydration
ReactDOM.hydrate(<App />, document.getElementById('root'));

Partial Hydration

Hydrate only interactive components.

Tools: Astro, Qwik

Islands Architecture

Independent interactive components in static HTML.

Concept: Ship minimal JavaScript, hydrate only "islands" of interactivity

Frameworks: Astro, Eleventy with Islands

Design Patterns

MVC (Model-View-Controller)

Separate data, presentation, and logic.

  • Model: Data and business logic
  • View: UI presentation
  • Controller: Handle input, update model/view

MVVM (Model-View-ViewModel)

Similar to MVC with data binding.

  • Model: Data
  • View: UI
  • ViewModel: View logic and state

Used in: Vue.js, Angular, Knockout

Component-Based Architecture

Build UI from reusable components.

// React component
function Button({ onClick, children }) {
  return (
    <button onClick={onClick} className="btn">
      {children}
    </button>
  );
}

// Usage
<Button onClick={handleClick}>Click me</Button>

Micro Frontends

Split frontend into smaller, independent apps.

Approaches:

  • Build-time integration
  • Run-time integration (iframes, Web Components)
  • Edge-side includes

State Management

Local State

Component-level state.

// React useState
function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>{count}</button>;
}

Global State

Application-wide state.

Solutions:

  • Redux: Predictable state container
  • MobX: Observable state
  • Zustand: Minimal state management
  • Recoil: Atomic state management
// Redux example
import { createSlice, configureStore } from '@reduxjs/toolkit';

const counterSlice = createSlice({
  name: 'counter',
  initialState: { value: 0 },
  reducers: {
    increment: state => { state.value += 1; }
  }
});

const store = configureStore({
  reducer: { counter: counterSlice.reducer }
});

Context API

Share state without prop drilling.

// React Context
const ThemeContext = React.createContext('light');

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar() {
  const theme = useContext(ThemeContext);
  return <div className={theme}>...</div>;
}

API Architecture Patterns

REST (Representational State Transfer)

Resource-based API design.

// RESTful API
GET    /api/users      // List users
GET    /api/users/1    // Get user
POST   /api/users      // Create user
PUT    /api/users/1    // Update user
DELETE /api/users/1    // Delete user

GraphQL

Query language for APIs.

# Query
query {
  user(id: "1") {
    name
    email
    posts {
      title
    }
  }
}

# Mutation
mutation {
  createUser(name: "John", email: "john@example.com") {
    id
    name
  }
}
// Apollo Client
import { useQuery, gql } from '@apollo/client';

const GET_USER = gql`
  query GetUser($id: ID!) {
    user(id: $id) {
      name
      email
    }
  }
`;

function User({ id }) {
  const { loading, error, data } = useQuery(GET_USER, {
    variables: { id }
  });
  
  if (loading) return <p>Loading...</p>;
  return <p>{data.user.name}</p>;
}

tRPC

End-to-end typesafe APIs.

// Server
const appRouter = router({
  getUser: publicProcedure
    .input(z.string())
    .query(async ({ input }) => {
      return await db.user.findUnique({ where: { id: input } });
    })
});

// Client (fully typed!)
const user = await trpc.getUser.query('1');

Microservices Architecture

Split application into small, independent services.

Characteristics:

  • Independent deployment
  • Service-specific databases
  • API communication
  • Decentralized governance

Benefits:

  • Scalability
  • Technology flexibility
  • Fault isolation

Challenges:

  • Complexity
  • Network latency
  • Data consistency

Monolithic Architecture

Single, unified application.

Pros:

  • Simpler development
  • Easier debugging
  • Single deployment

Cons:

  • Scaling challenges
  • Technology lock-in
  • Tight coupling

Serverless Architecture

Run code without managing servers.

Platforms: AWS Lambda, Vercel Functions, Netlify Functions, Cloudflare Workers

// Vercel serverless function
export default function handler(req, res) {
  res.status(200).json({ message: 'Hello from serverless!' });
}

Benefits:

  • Auto-scaling
  • Pay per use
  • No server management

Use Cases:

  • APIs
  • Background jobs
  • Webhooks
  • Image processing

Architectural Best Practices

Separation of Concerns

Keep different aspects separate:

  • Presentation layer
  • Business logic layer
  • Data access layer

DRY (Don't Repeat Yourself)

Avoid code duplication.

SOLID Principles

  • Single Responsibility
  • Open/Closed
  • Liskov Substitution
  • Interface Segregation
  • Dependency Inversion

Composition over Inheritance

Prefer composing objects over class hierarchies.

// Composition
function withLogging(Component) {
  return function LoggedComponent(props) {
    console.log('Rendering', Component.name);
    return <Component {...props} />;
  };
}

const LoggedButton = withLogging(Button);

Module Systems

ES Modules (ESM)

Modern JavaScript modules.

// export
export const name = 'John';
export function greet() {}
export default App;

// import
import App from './App.js';
import { name, greet } from './utils.js';
import * as utils from './utils.js';

CommonJS

Node.js module system.

// export
module.exports = { name: 'John' };
exports.greet = function() {};

// import
const { name } = require('./utils');

Build Optimization

Code Splitting

Split code into smaller chunks.

// React lazy loading
const OtherComponent = React.lazy(() => import('./OtherComponent'));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <OtherComponent />
    </Suspense>
  );
}

Tree Shaking

Remove unused code.

// Only imports 'map', not entire lodash
import { map } from 'lodash-es';

Bundle Splitting

  • Vendor bundle: Third-party dependencies
  • App bundle: Application code
  • Route bundles: Per-route code

Glossary Terms

Key Terms Covered:

  • Abstraction

  • API

  • Application

  • Architecture

  • Asynchronous

  • Binding

  • Block (CSS, JS)

  • Call stack

  • Class

  • Client-side

  • Control flow

  • Delta

  • Design pattern

  • Event

  • Fetch

  • First-class Function

  • Function

  • Garbage collection

  • Grid

  • Hoisting

  • Hydration

  • Idempotent

  • Instance

  • Lazy load

  • Main thread

  • MVC

  • Polyfill

  • Progressive Enhancement

  • Progressive web apps

  • Property

  • Prototype

  • Prototype-based programming

  • REST

  • Reflow

  • Round Trip Time (RTT)

  • SPA

  • Semantics

  • Server

  • Synthetic monitoring

  • Thread

  • Type

Additional Resources