Frontend System Architecture
This page covers design decisions inside a single frontend application. For the layers above it — micro-frontends, the edge/integration layer, containers and delivery, the design system, and AI-integrated patterns — see Frontend Platform Architecture.
Architecture Overview
1 Web
├─ 1.1 Web Framework — React.js / Next.js
│ └─ 1.1.1 Rendering Strategy — CSR / SSR / SSG
│ ├─ 1.1.1.1 Structure
│ ├─ 1.1.1.2 State & Data
│ └─ 1.1.1.3 Interactions
│
├─ 1.2 How We Host Our Web Server
│ ├─ 1.2.1 Static Hosting — GitHub Pages
│ ├─ 1.2.2 Managed Hosting — Vercel
│ └─ 1.2.3 Virtual Servers — AWS EC2
│
├─ 1.3 APIs & External Services
│ ├─ 1.3.1 Backend APIs
│ └─ 1.3.2 Third-Party Services
│
├─ 1.4 Scale & Performance
│ ├─ 1.4.1 Loading
│ ├─ 1.4.2 Rendering
│ ├─ 1.4.3 Data & Delivery
│ └─ 1.4.4 Measurement
│
├─ 1.5 Collaboration & Consistency
│ ├─ 1.5.1 Real-Time Communication
│ ├─ 1.5.2 Presence & Awareness
│ ├─ 1.5.3 Concurrent Edits
│ ├─ 1.5.4 Optimistic Updates
│ └─ 1.5.5 Reconnection
│
├─ 1.6 Access & Permissions
│ ├─ 1.6.1 Authentication
│ ├─ 1.6.2 Session Management
│ ├─ 1.6.3 Authorization
│ └─ 1.6.4 Access Enforcement
│
└─ 1.7 Reliability & Offline Support
├─ 1.7.1 Error Recovery
├─ 1.7.2 Offline Access
├─ 1.7.3 Offline Changes
├─ 1.7.4 Reconnection & Sync
├─ 1.7.5 Monitoring
└─ 1.7.6 Testing
1.1 Web Framework
1.1.1 Rendering Strategy
| Area | Design Question | Requirement / Condition | Technical Approach | Application Example |
|---|---|---|---|---|
| Initial Rendering | Where and when should initial content be generated? | SEO is not a priority; content can load in the browser after JavaScript runs. | CSR | Internal dashboard or design editor |
| SEO matters; content can be generated ahead of time and refreshed through rebuilds or revalidation. | SSG | Documentation or portfolio | ||
| SEO matters for public pages, and initial HTML needs fresh or request-specific data that cannot be fully generated ahead of time. | SSR | Public product page with request-time pricing and availability | ||
| Client Interactivity | How should server-rendered content become interactive? | HTML generated through SSR or SSG needs client-side event handling and state updates. | Hydration | Product page with interactive controls |
1.1.1.1 Structure
| Area | Design Question | Requirement / Condition | Technical Approach | Application Example |
|---|---|---|---|---|
| Components & Layouts | How should the UI be divided into reusable parts? | Pages repeat UI elements and share layouts. | Component composition | Reusable navigation, cards, and page layouts |
| How should layouts adapt to available space? | The interface must work across screen and container sizes. | Responsive layouts / Media queries / Container queries | Dashboard usable on mobile and desktop | |
| Routing | How should URLs map to pages and layouts? | Related pages share a layout and include dynamic parameters. | Nested routing / Dynamic routes | Product detail pages within a shared storefront |
| Modules & Dependencies | How should code boundaries be maintained? | Features need clear ownership and controlled imports. | Feature modules / Explicit public interfaces | Editor and billing modules with separate entry points |
| How should client and server code be separated? | Server-only dependencies must stay outside client bundles. | Client/server module boundaries | Server-side data access with an interactive client editor |
1.1.1.2 State & Data
| Area | Design Question | Requirement / Condition | Technical Approach | Application Example |
|---|---|---|---|---|
| State | Where should transient interaction state live? | A value is only needed by one component. | Local state / useState / useReducer | Modal visibility and selected tab |
| How should multiple components share client state? | A few related components share a value. | Lifting state up / Props | Selected item shared between sibling components | |
| A subtree needs shared values without passing props through every level. | React Context | Theme or locale shared throughout the application | ||
| Distant components share frequently updated state and need selective subscriptions. | Shared state store / Redux Toolkit / Zustand | Canvas selection shared with a properties panel | ||
| How should navigation state survive sharing and refreshes? | Filters or pagination should be encoded in a link. | URL search parameters | Shareable filtered product list | |
| How should form input and validation be tracked? | Inputs need validation and submission status. | Form state / Schema validation | Signup form with field-level errors | |
| How should data survive a browser restart? | Preferences or drafts must persist locally. | localStorage / IndexedDB | Saved theme preference or unsent draft | |
| API Integration & Data Fetching | How should remote data stay fresh after writes? | A mutation changes data already cached by the client. | Query caching / Mutation-driven invalidation | Project list refreshed after creating a project |
| How should large result sets be retrieved? | Fetching every result would create excessive network and memory use. | Pagination / Cursor-based fetching | Load the next page of search results |
1.1.1.3 Interactions
| Area | Design Question | Requirement / Condition | Technical Approach | Application Example |
|---|---|---|---|---|
| Input Frequency | When should frequent edits trigger a request? | Search requests or autosaving should wait until input pauses. | Debouncing | Search after typing stops or autosave after an editing pause |
| How often should continuous events trigger work? | Updates must continue at a bounded frequency during input. | Throttling | Limit shared cursor broadcasts during dragging | |
| Frame Scheduling | When should continuous visual changes be applied? | Continuous dragging needs visual updates aligned with browser frames. | requestAnimationFrame | Drag a shape across a design canvas |
1.2 How We Host Our Web Server
| Area | Design Question | Requirement / Condition | Technical Approach | Application Example |
|---|---|---|---|---|
| Static Hosting | Where should static output be served? | The frontend contains generated HTML, CSS, and JavaScript without request-time rendering. | Static hosting | Documentation hosted on GitHub Pages |
| Managed Hosting | How should server-rendered routes be deployed? | The team wants managed builds and application runtime infrastructure. | Managed application hosting | Next.js application deployed on Vercel |
| Virtual Servers | How much control is needed over the runtime? | The application needs custom operating system or server configuration. | Virtual server hosting | Custom web server running on AWS EC2 |
1.3 APIs & External Services
| Area | Design Question | Requirement / Condition | Technical Approach | Application Example |
|---|---|---|---|---|
| Backend APIs | Where should application data and business operations come from? | Our backend owns project data and business rules. | Internal backend API integration | Load and update project records through our backend |
| Third-Party Services | How should external capabilities be accessed? | An external provider supplies images, maps, or payments. | Third-party API integration | Search an image provider from a design editor |
| Where should requests requiring private credentials run? | A provider requires a secret that cannot be exposed to the browser. | Server-side API proxy | Call an image API through our backend |
1.4 Scale & Performance
| Area | Design Question | Requirement / Condition | Technical Approach | Application Example |
|---|---|---|---|---|
| Loading | How should initial downloads be reduced? | Some routes and features are not needed at startup. | Code splitting / Lazy loading | Load the editor only when its route is opened |
| Rendering | How should large lists remain responsive? | A large list creates excessive DOM work. | List virtualization | Table with thousands of rows |
| How should repeated computation be reduced? | An expensive calculation repeats with unchanged inputs. | Memoization | Reuse a filtered dataset until its inputs change | |
| Data & Delivery | How should static assets reach users efficiently? | Many users request the same versioned assets. | CDN / HTTP caching | Serve images and JavaScript from nearby cache locations |
| Measurement | How should performance bottlenecks be identified? | Loading, interaction latency, or layout stability needs investigation. | Core Web Vitals / Profiling | Identify slow interactions and large layout shifts |
1.5 Collaboration & Consistency
| Area | Design Question | Requirement / Condition | Technical Approach | Application Example |
|---|---|---|---|---|
| Real-Time Communication | How should users exchange live updates? | The application needs bidirectional communication with low latency. | WebSocket communication | Shared cursors and live document updates |
| Presence & Awareness | How should participants see who is active? | Online status and cursor positions should expire after disconnection. | Presence tracking / Heartbeats | Show active collaborators in an editor |
| Concurrent Edits | How should simultaneous changes be merged? | Multiple users edit the same shared document. | OT / CRDTs | Collaborative text editing |
| Optimistic Updates | How should the UI respond before a write is confirmed? | Users need immediate feedback while the server validates a change. | Optimistic updates / Rollback / Reconciliation | Move a shared task card before server confirmation |
| Reconnection | How should missed shared updates be recovered? | A client reconnects after other users have made changes. | Versioned resynchronization / Snapshot recovery | Refresh a shared document after reconnecting |
1.6 Access & Permissions
| Area | Design Question | Requirement / Condition | Technical Approach | Application Example |
|---|---|---|---|---|
| Authentication | How should user identity be established? | Users sign in through an existing identity provider. | OpenID Connect / SSO | Company login for a team workspace |
| Session Management | How should login state persist across requests? | A session needs expiration and server-side invalidation. | Server-managed sessions / Secure HttpOnly cookies | Keep a user signed in and revoke the session on logout |
| Authorization | How should actions depend on user permissions? | Users have different roles and resource ownership. | RBAC / Ownership checks | Owner, editor, and viewer permissions for a document |
| Access Enforcement | Where should access rules be enforced? | Restricted data must remain protected even when the UI is bypassed. | Server-side authorization / UI permission checks | Hide editing controls and reject unauthorized writes |
1.7 Reliability & Offline Support
| Area | Design Question | Requirement / Condition | Technical Approach | Application Example |
|---|---|---|---|---|
| Error Recovery | How should a UI failure be contained? | A component fails without needing to take down the entire page. | Error boundaries / Fallback UI | Replace a failed panel with a retry view |
| Offline Access | How should essential content remain available offline? | Previously loaded assets and data must remain accessible. | Service workers / Cache Storage | Open previously visited pages without a network |
| Offline Changes | How should edits be preserved during disconnection? | Users continue editing while writes cannot reach the backend. | Local persistence / Mutation queue | Save an offline draft and queue its update |
| Reconnection & Sync | How should queued writes be sent safely? | Pending operations may be retried or conflict with newer server data. | Idempotent replay / Conflict resolution | Synchronize offline edits without duplicate operations |
| Monitoring | How should production failures be investigated? | Errors need release context and actionable diagnostics. | Error tracking / Structured logs / Alerts | Investigate checkout errors after deployment |
1.7.6 Testing
| Area | Design Question | Requirement / Condition | Technical Approach | Application Example |
|---|---|---|---|---|
| Testing | Does individual application logic behave correctly? | Functions need fast, isolated verification. | Unit testing / Vitest | Validate form rules and data transformations |
| Do components respond correctly to user actions? | UI behavior needs verification with controlled dependencies. | Component testing / React Testing Library + Vitest | Show validation errors after submitting an invalid form | |
| Does a complete user journey work in a browser? | Pages, navigation, and backend integration need verification together. | End-to-end testing / Playwright | Sign in, create a project, and verify saved changes after reloading |