The RADIO Framework

Med

The RADIO framework provides a structured approach to frontend system design interviews. It stands for Requirements, Architecture, Data Model, Interface (API), and Optimizations. Mastering this framework ensures you cover all critical dimensions systematically rather than diving straight into implementation details.

Interactive Visualization

Key Points

  • Requirements: Clarify functional and non-functional requirements before designing anything
  • Architecture: Define the high-level component tree and module boundaries
  • Data Model: Design the client-side state shape, server state, and data flow
  • Interface: Define component APIs, prop contracts, and communication protocols
  • Optimizations: Address performance, accessibility, and edge cases last
  • Spend 3-5 minutes on requirements to avoid redesigning mid-interview
  • Non-functional requirements include offline support, i18n, and real-time updates
  • Draw diagrams to communicate architecture visually during interviews

Code Examples

Requirements Gathering

// Step 1: Functional Requirements
// - What are the core user actions?
// - What data needs to be displayed?
// - What interactions are expected?

interface Requirements {
  functional: {
    userActions: string[]    // e.g., ['search', 'filter', 'paginate']
    dataDisplay: string[]    // e.g., ['list view', 'detail view']
    interactions: string[]   // e.g., ['drag-drop', 'inline edit']
  }
  nonFunctional: {
    performance: string      // e.g., 'First paint < 1.5s'
    accessibility: string    // e.g., 'WCAG 2.1 AA'
    offline: boolean
    i18n: boolean
    realTime: boolean
  }
  scale: {
    users: string            // e.g., '10M DAU'
    dataVolume: string       // e.g., '10K items in list'
    updateFrequency: string  // e.g., 'every 30 seconds'
  }
}

Always start by clarifying requirements. This prevents scope creep and shows the interviewer you think before coding. Ask about scale, data freshness, and edge cases.

Architecture Breakdown

// Step 2: High-level Architecture
//
// ┌─────────────────────────────────────┐
// │           App Shell                  │
// │  ┌──────────┐  ┌──────────────────┐ │
// │  │  NavBar   │  │   Main Content   │ │
// │  │          │  │  ┌────────────┐  │ │
// │  │  Search  │  │  │  List View  │  │ │
// │  │  Filters │  │  │            │  │ │
// │  │          │  │  │  Detail    │  │ │
// │  │          │  │  │  Panel     │  │ │
// │  └──────────┘  │  └────────────┘  │ │
// │                └──────────────────┘ │
// └─────────────────────────────────────┘

interface ArchitectureLayer {
  presentation: string[]  // UI components
  logic: string[]         // Custom hooks, state machines
  data: string[]          // API layer, caching, normalization
  infra: string[]         // Error boundaries, logging, analytics
}

const layers: ArchitectureLayer = {
  presentation: ['AppShell', 'ListView', 'DetailPanel', 'SearchBar'],
  logic: ['useSearch', 'useInfiniteScroll', 'useOptimisticUpdate'],
  data: ['apiClient', 'queryCache', 'normalizedStore'],
  infra: ['ErrorBoundary', 'AnalyticsProvider', 'FeatureFlags'],
}

Break the system into layers: presentation, logic, data, and infrastructure. This separation of concerns makes the design scalable and testable.

Data Model & Interface Design

// Step 3: Data Model
interface ClientState {
  entities: Record<string, Entity>  // Normalized store
  ui: {
    selectedId: string | null
    filters: FilterState
    pagination: { cursor: string; hasMore: boolean }
  }
  cache: {
    queries: Map<string, CachedQuery>
    ttl: number
  }
}

// Step 4: Component Interface
interface ListViewProps {
  items: Entity[]
  onSelect: (id: string) => void
  onLoadMore: () => void
  isLoading: boolean
  error: Error | null
}

// Step 5: Optimizations
// - Virtual scrolling for 10K+ items
// - Debounced search (300ms)
// - Optimistic updates for mutations
// - Service worker for offline reads

Design the data model to be normalized (avoiding duplication) and define clear component interfaces. Save optimizations for last but mention them proactively.

Common Mistakes

  • Jumping into component code before clarifying requirements
  • Ignoring non-functional requirements like accessibility or offline support
  • Designing only the happy path without considering error states and loading states
  • Over-engineering the solution for a scale that was never mentioned
  • Forgetting to discuss trade-offs between different approaches

Interview Tips

  • Spend the first 3-5 minutes asking clarifying questions about requirements and constraints
  • Draw a high-level architecture diagram before discussing implementation details
  • Explicitly state trade-offs when making design decisions
  • Mention optimizations even if you do not have time to implement them in detail
  • Practice the RADIO framework with real products: Twitter feed, Google Docs, Spotify player

Related Concepts