The RADIO Framework
MedThe 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