The RADIO framework
A five-part checklist, Requirements, Architecture, Data model, Interface, and Optimizations, for running a frontend system design interview: design the right thing, cover the basics fast, and save time for deep dives.
Why you need a framework at all
Picture two candidates who get the same prompt: "Design a news feed." Both know React well, and both have built infinite scroll at work.
One gets a strong hire, the other gets a no. The difference is not what they know but what they did with 45 minutes.
The first candidate starts drawing components in minute one. By minute 15 they have a nice FeedItem with likes and comments. Then the interviewer asks "what if the feed has 5,000 posts?", and they realise they never asked how big the feed is. They rewrite the list, run out of time, and never reach performance, accessibility, or errors.
The second candidate spends five minutes asking questions, sketches the big parts in about eight, names the data and the API in under ten more, and then says: "The two hard parts here are long-list performance and keeping the feed fresh. Let me go deep on those." They spend 15 minutes there, and that is where the interviewer learns the most about them.
What goes wrong without a plan
A system design prompt is short and vague on purpose. There is no single right answer, and nobody hands you a spec. That freedom is the trap. Without a plan, people fall into the same four holes again and again.
- Designing the wrong thing. "Design an image carousel" can mean a hero banner with 5 slides or a product gallery with 200 zoomable photos. Skip the questions and you may solve a problem nobody asked about.
- Spending the clock badly. Twenty minutes on a button component, then three rushed minutes on the parts that were actually hard.
- Leaving holes. Forgetting the API, or never saying where data lives, so the interviewer has to drag it out of you, and that costs you points.
- Freezing. A blank whiteboard and a silent interviewer make it hard to know what to say next. A plan always gives you a next step.
What RADIO stands for
RADIO is a name for the five things every frontend design answer needs to cover. Each letter is one part, and each part builds on the one before it. The mnemonic comes from Yangshun Tay's front end system design playbook on GreatFrontEnd, linked in the references.
| Letter | Part | The question it answers |
|---|---|---|
| R | Requirements | What are we building, for whom, how well must it work, and what are we skipping? |
| A | Architecture | What are the big parts on the client and server, and how does data flow between them? |
| D | Data model | What data does the client hold, what shape is it, and where does each piece live? |
| I | Interface | How do the parts talk: the API calls to the server and the props and events between components? |
| O | Optimizations | Which two or three hard parts deserve a deep dive: performance, accessibility, offline, security? |
The order is not random. You cannot draw the right parts until you know the requirements, and you cannot name the data until you know the parts that hold it.
You cannot design an API until you know the data it carries. And you cannot choose good optimizations until you know where the system is under strain.
A checklist, not a template
Here is the most important idea in this lesson. RADIO is a checklist for running the interview, not a form to fill in.
Strong answers do not sound like "Section R. Section A. Section D." They sound like a story of decisions: "Because the feed can hold thousands of posts, I'll virtualize the list, which means the data layer must give me items by index, so the API returns pages with a cursor." To virtualize a list means to render only the rows on screen.
That is why the problem guides on this site are written as a chain of decisions and not as five fixed boxes. Each chapter makes one choice, weighs the options, and shows how it shapes the next choice. RADIO is still there underneath: every guide starts with requirements, sketches the parts, names the data and the API, and spends its longest chapters on deep dives. You just don't see the labels.
Use RADIO the way a pilot uses a pre-flight checklist. The pilot does not read it aloud to the passengers, but they never take off without touching every item. In the interview, glance at the five letters every ten minutes and ask yourself: "Have I covered this yet? Is it the most useful thing to talk about now?"
Check your understanding · Exercise 1
Which of these are real benefits of following RADIO in an interview? Select all that apply.
How to spend 45 minutes
Time is the one resource you cannot get back in an interview, so plan it before you need it. The calendar invite may say 45 or 60 minutes, but you never get all of it for design. Introductions take a few minutes at the start, and many interviewers keep the last five minutes for your questions.
So a 45-minute slot gives you about 35 to 38 minutes of real design time. A 60-minute slot gives you about 50. Every minute you plan below comes out of that budget.
A default split
Start from this split for a 45-minute interview and bend it to the problem. The numbers are a starting point that has worked for many people, not a law. Notice that the last part gets the most time: that is on purpose.
| Minutes | Part | What you should have at the end |
|---|---|---|
| 0 to 3 | Hello | Names, roles, and the prompt read out. Nothing to design yet. |
| 3 to 8 | Requirements | A short list of functional and non-functional requirements, and what is out of scope, written where both of you can see it. |
| 8 to 16 | Architecture | A box diagram: the main client parts, the server or API, and arrows for how data flows. |
| 16 to 20 | Data model | The main entities with their key fields, and where each kind of state lives. |
| 20 to 25 | Interface | One or two API calls with their shape, and the props or events of the main component. |
| 25 to 40 | Optimizations | Two or three deep dives, each with the problem, your solution, and its cost. |
| 40 to 45 | Your questions | Time for you to ask about the team. Wrap up the design in one sentence before this. |
Why the last part gets the most time
Requirements, architecture, data, and interface are the parts most candidates get roughly right. They are necessary, but they rarely separate a mid-level engineer from a senior one. The deep dives are where you show real depth: why the list needs virtualization at 2,000 items, how you stop an old search response from overwriting a newer one, how focus moves in a modal.
So the goal of the first four parts is to be correct and quick. Cover them well enough that the deep dives rest on solid ground, then move on. If you are still on the data model at minute 30, the interviewer will have little to score you on in the area that matters most.
Bending the split to the question
Different questions put the weight in different places. A component question, like an autocomplete or a date picker, has a tiny server side and a rich component API, so Architecture shrinks and Interface grows. An app question, like a news feed or a chat app, has more moving parts, so Architecture and Data model grow. Try it in the planner below: the feature setting reproduces the table above, and the other two show how the split bends.
Design time: 37 of 45 minutes. Requirements 5 min, Architecture 8 min, Data model 4 min, Interface 5 min, Optimizations 15 min.
A feature question sits between the two: a few parts inside a bigger product, with both a server API and a component API to sketch.
Checkpoints, not a stopwatch
You can't stare at a clock while you think, so use two or three checkpoints instead. A simple set for 45 minutes: requirements written down by minute 8, a box diagram by minute 16, and deep dives started by minute 25. If you miss a checkpoint by more than a few minutes, cut something, out loud.
Saying it out loud matters. "We're at 22 minutes and I haven't touched performance, so I'll keep the API short: one paginated endpoint, and I can expand it later if you want" sounds like someone who is in control. Quietly running over sounds like someone who is lost.
Check your understanding · Exercise 2
It is minute 24 of a 45-minute interview for "Design a chat app". You have requirements and a box diagram, but no data model or API yet. What is the best move? Select all that apply.
R: Requirements
Requirements turn a one-line prompt into something you can design. You get them by asking questions, even when the prompt seems clear. The answers decide almost everything that follows, so this is the cheapest place to avoid a wrong turn.
Sort what you learn into three lists and write them where the interviewer can see them. Written requirements become your contract: later, when you choose between two designs, you point back at them.
Functional requirements: what it does
Functional requirements are the things a user can do. Write them as short user actions, three to six of them, most important first. For a news feed: "see a list of posts from people I follow", "scroll to load older posts", "like a post", "create a text post with an image".
Keep the list short on purpose. Each item becomes a part of your design, so ten items means ten parts and no time for depth. If the interviewer lists many features, ask which three matter most and put the rest under out of scope.
Non-functional requirements: how well it works
Non-functional requirements describe quality: speed, scale, devices, accessibility, reliability. They are where frontend interviews are won, because they decide the deep dives. Give each one a number whenever you can. "Fast" means nothing; "first posts visible in under 2.5 seconds on a mid-range phone on 4G" is something you can design for.
| Quality | Vague | With a number |
|---|---|---|
| Load speed | It should load fast. | Largest Contentful Paint (LCP, when the main content appears) of 2.5 s or less for 75% of visits. |
| Responsiveness | Typing shouldn't lag. | Interaction to Next Paint (INP, the delay after a tap or key press) of 200 ms or less. |
| Visual stability | No jumping. | Cumulative Layout Shift (CLS, how much the page jumps) of 0.1 or less, so images and ads reserve their space. |
| Scale of data | Lots of posts. | Up to 5,000 items in one list; 20 per page; images up to 2 MB before resizing. |
| Freshness | Real time. | New messages appear within 1 second; feed updates within 30 seconds are fine. |
| Size | Lightweight. | The widget adds under 30 KB of gzipped JavaScript to the page. |
| Accessibility | Accessible. | Meets WCAG 2.2 AA (the Web Content Accessibility Guidelines, level AA): full keyboard use, screen reader labels, 4.5 to 1 text contrast. |
You do not need the interviewer to give you the numbers. If they say "you decide", propose them yourself: "I'll aim for the Core Web Vitals good thresholds: LCP within 2.5 seconds, INP within 200 ms, CLS at most 0.1." Proposing a sensible number shows you know what good looks like.
The questions that change the design most
Some questions matter far more than others, because one answer changes the whole design. Ask those first. A good test: if both possible answers lead to the same design, the question can wait.
| Question | If the answer is small | If the answer is big |
|---|---|---|
| How many items can the list hold? | Up to 100: render them all. | Thousands: paginate, and virtualize the list (render only what is on screen). |
| Which devices? | Desktop only: hover, big screens, fast CPU. | Mobile web too: touch, small screens, slow CPU, flaky network, smaller bundles. |
| How fresh must data be? | Minutes: fetch on load, refresh on focus. | Under a second: a push channel such as WebSockets or server-sent events. |
| Must it work offline? | No: show an error and a retry button. | Yes: a service worker, a local store such as IndexedDB, and a queue of unsent writes. |
| Who can see it? | Logged-in users only: render on the client. | Public and found by search engines: render HTML on the server. |
| How many languages? | One: plain strings. | Many, including right-to-left: message catalogs, logical CSS properties, locale-aware dates and numbers. |
Out of scope: say what you will skip
The third list is just as useful. Out of scope is what you and the interviewer agree not to design today: login, the admin panel, payments, server databases. Saying it protects your time and shows you know those parts exist. Without it, a vague prompt grows until it eats the interview.
Decision The interviewer answers "what do you think?" to your questions. How do you settle the requirements?
What we pick: Assume and say it for most questions, and offer a fork for the one or two questions that change the design the most. Both keep you moving and show judgement, which is what this part is scored on.
Check your understanding · Exercise 3
For "Design a photo gallery", which of these are non-functional requirements? Select all that apply.
A: Architecture
Architecture is the big picture: the main parts of the system, what each one is responsible for, and how data moves between them. In a frontend interview it is a drawing of boxes and arrows, and it should fit on half a whiteboard. If it needs the whole board, the boxes are too small.
The boxes most frontend designs share
Most frontend designs, from a widget to a whole app, use the same handful of boxes. Learn them as a starting kit, then rename and add to them for each problem.
- Server or API. Where the data comes from. One box is usually enough. Add a CDN (content delivery network, servers near the user that serve static files and cached responses) if images or scripts matter.
- Data layer or API client. The only part that talks to the network. It builds requests, handles retries and errors, and turns responses into the client's data shape.
- Store or cache. Where the client keeps data it has fetched, so two views showing the same post share one copy. In code this may be a library like TanStack Query, Redux, or a simple context.
- Controller or container. The glue for one feature: it reads from the store, tells the data layer what to fetch, and passes plain data down to the views.
- Views. The components the user sees. Given data and callbacks, they render. They do not fetch.
For each box, say its job in one sentence as you draw it. "The feed store holds posts by ID and the order of IDs for the feed." If you need "and" three times, the box does too much: split it. If two boxes have the same job, merge them.
Client versus server: where does each part run?
A frontend design is mostly about the client, but it must say where the line with the server sits. Two decisions draw that line. First, where the HTML is rendered: on the server for fast first paint and search engines, or in the browser for rich, app-like screens. Second, where the logic sits: filtering 50 items can happen in the browser; ranking a feed of a million posts belongs on the server.
You can also add a thin server that belongs to the frontend team, often called a backend for frontend (BFF). It calls several backend services and returns exactly what one screen needs in one response. Mention it when a screen would otherwise need five requests to draw.
Data flow: draw the arrows with a direction
Arrows matter as much as boxes. Draw them with a direction and say what travels on them. A good default for the client is one-way flow: user events go up from views to the controller, the controller asks the data layer, the data layer updates the store, and the store's new data flows down into the views.
Then add the second kind of flow if the problem has it: data the server pushes without being asked, such as new chat messages over a WebSocket. Draw it as its own arrow into the store, because it arrives at any time and must merge with what is already there.
Think first
A candidate draws one big box called "App" with an arrow to "Server". What is missing, and what would you add?
It shows no responsibilities, so the interviewer can't tell where fetching, caching, or rendering happen. Split "App" into at least a data layer that talks to the server, a store that holds fetched data, and the views that display it, with a controller per feature if there are several.
Then label the arrows: "GET /feed?cursor" from the data layer to the server, "posts by ID" from the store to the views, and "like clicked" from a view back up. Now the drawing tells a story the rest of the interview can build on.
D: Data model
The data model is the list of things the client knows about, their important fields, and where each piece of state lives. It is short, but it is the step people skip most, and skipping it makes the API and the deep dives vague.
Entities: the nouns of the problem
An entity is a kind of thing with an identity, like a Post, a User, or a Message. Find them by reading your functional requirements and underlining the nouns. Most frontend questions have two to five.
For each entity, list only the fields that drive a decision. A Post has dozens of fields in real life; in the interview, id, author, createdAt, body, imageUrl, and likeCount are enough, because they decide sorting, rendering, image loading, and the like button.
type User = { id: string; name: string; avatarUrl: string };
type Post = {
id: string;
authorId: string; // points to a User, not a copy of it
createdAt: string; // ISO date, used for order and "2h ago"
body: string; // user text: render as text, never as HTML
image?: { url: string; width: number; height: number };
likeCount: number;
likedByMe: boolean; // drives the button state
};
type FeedState = {
postIds: string[]; // the order, from the server
nextCursor: string | null;
status: "idle" | "loading" | "error";
};
likedByMe is what an optimistic like (one shown before the server confirms it) flips.feed.postIds hold only IDs, so a change to one post shows everywhere that post appears.Where each piece of state lives
This is the part that shows real frontend thinking. The same value behaves very differently depending on where you keep it. There are five common homes, and choosing well removes whole classes of bugs.
| Home | Good for | Lives until | Example |
|---|---|---|---|
| Server | The source of truth for shared data. | Forever, for every device. | Posts, likes, messages. |
| Client cache or store | A copy of server data, shared by all views. | The tab closes or the data goes stale. | The feed's posts by ID. |
| URL | State a user should be able to share, bookmark, or get back with the Back button. | The user navigates away. | Search query, filters, current tab, page. |
| Browser storage | State that should survive a reload or going offline. | Cleared by the user or the browser. | A draft post in localStorage, offline messages in IndexedDB. |
| Component | Short-lived UI state only one component cares about. | The component unmounts. | Is the menu open, the text being typed, hover. |
Two rules cover most cases. First, keep server state (copies of server data) apart from UI state (what the user is doing right now). They change for different reasons and need different tools.
Second, store shared entities once, by ID, and let lists hold IDs. A store kept this way is called normalized. Then a like on a post updates the feed, the post page, and the profile at the same time, because there is only one copy.
Check your understanding · Exercise 4
In a chat app, which pairings of state and home are good choices? Select all that apply.
I: Interface
The interface is how the parts talk to each other. In a frontend design there are two kinds. The server API is the contract between the client and the server: requests and responses. The component API is the contract between a component and the code that uses it: props in, events out.
App questions lean on the server API. Component questions, like "design a date picker", lean almost entirely on the component API, because the component may never call a server itself. Know which one your question needs and spend your minutes there.
The server API: one or two calls, done well
You do not need every endpoint. Pick the one or two calls that the hard parts depend on and give each one four things: the method and path, what it sends, what it returns, and how it fails. Name the fields that drive a decision, like the cursor for paging or the version number for conflict checks.
GET /api/feed?cursor=p_9f2c&limit=20
200 OK
{
"posts": [ { "id": "p_9f1a", "authorId": "u_7", ... } ],
"users": { "u_7": { "name": "Asha", "avatarUrl": "..." } },
"nextCursor": "p_9e77" // null when there are no older posts
}
POST /api/posts/p_9f1a/like -> 204 No Content
DELETE /api/posts/p_9f1a/like -> 204 No Content
Say why you chose the shape. "Cursor and not page number, because new posts are added at the top while the user scrolls, and page 2 would then repeat posts from page 1." One reason like this is worth more than five extra endpoints.
Decision Which protocol should the client use to talk to the server?
What we pick: Default to REST for reads and writes, and say so in one sentence. Mention GraphQL when one screen pulls from many sources. Add a push channel only when a requirement needs updates within seconds, like chat or live scores, and keep REST for everything else.
The component API: props in, events out
For a component, the interface is its props. Group them into three kinds: the data it shows, the events it reports, and the options that change how it looks or behaves. Then decide one key question: is it controlled (the parent owns the value and passes it in) or uncontrolled (the component keeps the value itself)? Good library components support both.
type AutocompleteProps<T> = {
// data
fetchSuggestions: (query: string, signal: AbortSignal) => Promise<T[]>;
getLabel: (item: T) => string;
// controlled or uncontrolled value
value?: T | null;
defaultValue?: T | null;
// events
onSelect: (item: T) => void;
onQueryChange?: (query: string) => void;
// options
minChars?: number; // default 2
debounceMs?: number; // default 200
renderItem?: (item: T, active: boolean) => React.ReactNode;
label: string; // required, for screen readers
};
AbortSignal lets the component cancel an old request when the user keeps typing. Making label required is an accessibility decision written into the API.Check your understanding · Exercise 5
Which of these are strong things to say while defining the interface for an infinite news feed? Select all that apply.
O: Optimizations and deep dives
Optimizations are where the interview is decided. By now you have a design that works. This part shows whether you can make it work well: fast on a cheap phone, usable with a keyboard and a screen reader, safe, and calm when the network fails.
The trap is to list everything you know: "lazy loading, code splitting, memoization, CDN, compression, service workers...". A list like that takes a minute and earns almost nothing, because it shows you have heard of things, not that you can use them. Instead, pick two or three areas and go deep.
The areas to choose from
| Area | What it covers | A deep question in it |
|---|---|---|
| Network performance | What loads first, caching, prefetching, payload size, request count. | How do you show the first 10 posts in under 2.5 s on 4G? |
| Rendering performance | Long lists, re-renders, layout work, main-thread time. | How do you scroll 5,000 rows at 60 frames per second? |
| Accessibility | Keyboard use, focus, roles and labels, live announcements, contrast, reduced motion. | How does a screen reader user know 3 new suggestions appeared? |
| Internationalization | Translated strings, plural rules, dates and numbers, right-to-left layout, long words. | What breaks when the UI is shown in Arabic or German? |
| Security | Cross-site scripting (XSS), user HTML, tokens, cross-site request forgery (CSRF), third-party scripts. | A post body can contain <script>: how do you render it safely? |
| Offline and reliability | Errors, retries, timeouts, offline queues, conflict handling. | The user likes 3 posts in a tunnel: what happens when they're back online? |
| User experience states | Loading, empty, error, partial, and stale states, not just the happy path. | What does the user see while page 2 loads, and if it fails? |
How to pick the two or three
Pick the areas where this problem is under the most strain. Three questions find them quickly, and each one points back at earlier RADIO steps. That is why the earlier steps matter: they tell you where to dig.
- Which non-functional requirement is hardest to meet? "5,000 items" points at rendering. "Messages within 1 second" points at the push channel and reconnects. "Works offline" points at storage and sync.
- What is special about this problem? Every app needs loading states. Only an autocomplete has out-of-order responses on every keystroke; only an editor has two people typing in the same place. The special part is the most interesting deep dive.
- What is the interviewer hinting at? If they asked twice about mobile, or said "lots of users", they are telling you what they want to score. Follow the hint.
The shape of a good deep dive
A deep dive is a small story, and it has the same five beats every time. Practise them until they are automatic. With two or three deep dives in about 15 minutes, each beat gets about a minute.
- The problem, with a number. "Rendering 5,000 post cards creates about 200,000 DOM nodes, and scrolling janks on a mid-range phone."
- The options. "Paginate with a Load more button, use
content-visibility: auto, or virtualize the list." - Your choice and why. "Virtualize, because the feed is endless and we need steady memory."
- How it works, briefly. "Render only the rows in view plus a few above and below, measure each row once, and keep scroll position when new posts load."
- The cost and how you'd check it. "Find-in-page and screen readers can't see unrendered rows, so I'd keep
aria-setsizeandaria-posinseton each row. I'd check with a performance trace on a throttled phone."
Deep dives for News feed:
- Network. Images and pages: what loads first, image sizes, cursor paging.
- Rendering. A long list: virtualize, and keep the scroll position steady as posts load.
- UX states. Loading, empty, error, and "new posts" states at the top.
Check your understanding · Exercise 6
For "Design a search autocomplete", which would make the strongest deep dives? Select all that apply.
Adapting RADIO to component and app questions
Frontend design questions come in roughly three sizes, and RADIO bends to each. A component question asks for one reusable piece of UI: an autocomplete, a modal, a date picker, an image carousel. An app question asks for a whole product: a news feed, a chat app, an email client. A feature question sits in between: a comment section, a notification bell, a checkout form inside a bigger site.
The five letters stay the same. What changes is how much time each one gets and what you draw for it. Spot the size in the first minute, because it tells you where to spend the next 40.
| Letter | Component question | App question |
|---|---|---|
| Requirements | Who uses it (other developers and end users), which interactions, how many items, which browsers, how much it may add to the bundle. | Core user flows, scale of data and users, devices, freshness, offline, search engines. |
| Architecture | Small: the component's inner parts (input, list, popup), and maybe a data source. Often 3 or 4 boxes. | Large: pages, routing, rendering strategy, store, data layer, server, CDN, push channel. |
| Data model | Internal state: open or closed, active index, value, query, loading. | Entities and their relations, the normalized store, URL state, offline storage. |
| Interface | The main event: props, events, controlled versus uncontrolled, render slots, theming. | Mostly server API: endpoints, pagination, errors, real-time messages. |
| Optimizations | Accessibility, keyboard, focus, rendering many items, bundle size, browser quirks. | Load speed, caching, long lists, real time, offline, security, i18n. |
Component questions: think like a library author
For a component, your user is two people: the developer who drops it into their app, and the person who clicks it. The developer cares about the props, how to style it, how big it is, and whether it works with their state. The end user cares about keyboard support, screen readers, touch, and speed.
So the Interface step becomes the centre of the design, and accessibility is almost always one of your deep dives. A good check: could another team use your component without reading its source? If the answer needs "well, you'd have to...", the API needs work.
App questions: think like a tech lead
For an app, the challenge is breadth. There are more parts, more data, and more ways to fail, and you will not cover them all. Requirements must cut scope hard, Architecture must show the whole system in one picture, and the deep dives pick the two or three places the app is under strain.
App questions also bring up decisions that component questions never do: how pages are rendered (server or client), how routes are split into bundles, how the store is shaped across features, and how the client gets updates. You do not need to deep dive all of them, but you should name your choice for each in a sentence.
Check your understanding · Exercise 7
You are asked to "Design a modal dialog component for our design system". Where should most of your time go? Select all that apply.
Driving the conversation, and the mistakes that sink people
An interviewer can only score what they hear and see. A great idea you keep in your head counts for nothing. So the skill here is not only designing, but designing out loud in a way that is easy to follow and easy to steer.
Good candidates drive. They say where they are going, check in at the end of each part, and invite the interviewer to redirect them. The interviewer becomes a teammate in a design review, not an examiner waiting for mistakes.
The loop: propose, explain, check in
Each RADIO part runs through the same small loop. You propose something concrete, explain the reason and the main trade-off, then check in. If the interviewer agrees, you move on; if they push back or hint, you adjust and loop again. The check-in is one sentence, not a request for permission.
Phrases that do real work
| Moment | What to say |
|---|---|
| Start | "Before I design anything, I'd like to ask a few questions to pin down scope. Then I'll sketch the parts, the data, and the API, and spend most of the time on the hardest parts." |
| Moving on | "That covers requirements. Moving to the architecture." |
| Making a choice | "I could do A or B. A is simpler; B handles the 5,000-item case. Given our requirements, I'll go with B." |
| Unsure | "I'm not certain of the exact browser support for that; I'd check MDN, and if it's missing I'd fall back to X." |
| Time check | "We're at about 25 minutes. I'd like to spend the rest on two deep dives: list performance and offline likes." |
| Check-in | "Does that level of detail work, or would you like me to go deeper here?" |
| Wrap-up | "To sum up: a virtualized feed with a normalized store, cursor paging, and optimistic likes. Next I'd look at image loading." |
Taking hints
Interviewers drop hints when they want you somewhere else. "Interesting, and what if the user is on a train?" means "talk about offline and flaky networks". "How would that feel with 10,000 rows?" means "talk about rendering performance". Treat each question as a direction, not a test of your first answer.
When a hint shows your design has a hole, say so plainly and fix it: "Good point, my current design would re-render every row on each like. Let me change the store so each row subscribes only to its own post." Changing your mind with a reason is a strong signal. Defending a weak choice is a weak one.
Mistakes that sink good candidates
- Designing before asking. Answering the wrong question well scores worse than answering the right question roughly.
- Going silent. Long pauses leave the interviewer with nothing to score. Think out loud: "I'm weighing pagination against virtualization..."
- Using RADIO as a script. Reading out headings and filling each one equally sounds rehearsed and wastes time on easy parts.
- Listing instead of choosing. Naming ten techniques is not a design. Pick one, say why, and name its cost.
- Designing the backend. Twenty minutes on database sharding in a frontend interview is twenty minutes not spent on what they came to score.
- Only the happy path. No loading, empty, error, or offline states. Real products spend much of their code on these.
- Buzzwords you can't defend. If you say "islands architecture" or "CRDT", expect a follow-up. Only use terms you can explain in two sentences.
- Ignoring the clock. Reaching deep dives at minute 38 leaves no room for the part that decides the level.
Think first
Halfway through, the interviewer says "What happens if two tabs are open?" You hadn't thought about it. What do you do?
Treat it as a hint and think out loud. Name what could break: two tabs can each hold their own copy of the data, so a like in one tab leaves the other stale, and two tabs may both open a WebSocket.
Then propose a fix with its cost: "I'd refetch on visibilitychange when a tab becomes visible, which is cheap. If they need live sync, a BroadcastChannel can pass updates between tabs, and one tab can own the socket." Finally, check in: "Is that the case you had in mind?"
A worked example: "Design a search autocomplete"
Let's run the whole framework on one small question, with the minute marks, so you can see how the parts connect and how little time the basics need. The prompt: "Design the search box with suggestions for our online bookshop." The step-through below follows the same run.
The autocomplete answer, minute by minuteStep 1 of 7: Read the prompt, minutes 0 to 3
Read the prompt, minutes 0 to 3: "Design the search box with suggestions for our bookshop." Write R A D I O down the side of the board and say the plan in one sentence.
Minutes 3 to 7: requirements
The candidate asks five questions and writes down the answers. It is a feature in the shop that should be reusable later, and it suggests book titles and authors, up to 8.
Half the traffic is mobile. Speed is left to the candidate ("you decide"), and the interviewer asks them to assume the site must meet WCAG AA.
- Functional: show up to 8 suggestions as the user types; pick one with mouse, touch, or keyboard; pressing Enter with no pick runs a full search.
- Non-functional: suggestions within 400 ms after typing stops on 4G; no flicker or wrong results; full keyboard and screen reader support; under 10 KB of gzipped JavaScript.
- Out of scope: the search results page, the ranking algorithm on the server, spelling correction.
Minutes 7 to 12: architecture
Four boxes. The input reports what the user types. A controller debounces typing (waits until typing pauses), checks a small cache, and calls the suggest API through a data layer. A listbox popup shows the results.
Data flows one way: keystrokes go up to the controller, suggestions come down to the popup. The server is one box labelled "suggest API, behind a CDN".
aria-activedescendant, so typing never stops.Minutes 12 to 20: data model and interface
The state is small: query, items, activeIndex (which suggestion is highlighted, or -1), isOpen, and status (idle, loading, error). A cache maps each query to its items, keeps the last 50, and drops the oldest first. The query does not go in the URL; the results page will put it there.
GET /api/suggest?q=harr&limit=8
200 OK
Cache-Control: public, max-age=300
{ "query": "harr",
"items": [ { "id": "b_101", "label": "Harry Potter and the...", "kind": "book" },
{ "id": "a_42", "label": "Harriet Evans", "kind": "author" } ] }
Cache-Control response header lets the browser and the CDN reuse an answer for five minutes, so popular prefixes never reach the server.The component API takes fetchSuggestions, onSelect, label, and an optional renderItem, as in the interface chapter. The candidate says one sentence on why fetchSuggestions receives an AbortSignal: so old requests can be cancelled.
Minutes 20 to 40: three deep dives
The candidate proposes three deep dives, and the interviewer agrees. Each follows the five beats from the optimizations chapter: problem, options, choice, how it works, cost.
- Request count. Typing "harry potter" is 12 keystrokes, which could be 12 requests. A 200 ms debounce plus a 2-character minimum and the cache usually cut it to 2 or 3. Cost: 200 ms of added delay, which leaves about 200 ms for a request served from the CDN and still fits the 400 ms target.
- Out-of-order responses. The response for "har" can arrive after the one for "harr" and overwrite it. Fix: abort the old request with
AbortController, and also drop any response whosequerydoes not match the current input. Cost: almost none. - Accessibility. Use the combobox pattern from the WAI-ARIA Authoring Practices (the W3C guide to accessible widgets): the input has
role="combobox",aria-autocomplete="list",aria-expanded, andaria-controlspointing at arole="listbox"ofrole="option"items; arrow keys updatearia-activedescendantto the highlighted option, so focus stays in the input; Escape closes; a polite live region says "8 suggestions". Cost: careful testing with a screen reader such as VoiceOver or NVDA.
Just before minute 40, the candidate names what they would do next: highlight the matched letters using text nodes, never innerHTML, so a book title cannot inject script; and keep the popup inside the viewport on small screens. Then they sum up in one sentence. Notice that no step was skipped, yet the basics took 17 minutes and the deep dives took 20.
Check your understanding · Exercise 8
In the worked example, which choices trace straight back to a written requirement? Select all that apply.
Summary
- RADIO stands for Requirements, Architecture, Data model, Interface, and Optimizations. Each part builds on the one before.
- It is a checklist for running the interview, not a template to read out. Strong answers sound like a story of decisions with RADIO underneath.
- In 45 minutes you get about 37 minutes of design. Cover the first four parts correctly and quickly, and save about 15 minutes for deep dives (about 20 in a 60-minute slot).
- Write requirements in three lists: functional, non-functional with real numbers, and out of scope. Ask first the questions whose answer changes the design.
- Draw a few boxes with one job each and arrows with a direction. Name the entities, store shared data once by ID, and put each piece of state in the right home: server, store, URL, browser storage, or component.
- Define one or two API calls well, with why and how they fail. For components, the props and events are the design.
- Pick two or three deep dives where the problem is under strain, and run each as problem, options, choice, how it works, and cost.
- Drive the conversation: propose, explain, check in, take hints, and watch the clock out loud.
In the interview
Questions interviewers ask about this. Answer each out loud first, then compare.
Question 1
The interviewer says "Design Instagram" and stops talking. What do you do in the first two minutes?
Say the plan out loud: "I'll start with a few questions to pin down scope, sketch the main parts, the data, and the API, then spend most of the time on the two or three hardest parts." Write R A D I O down the side of the board.
Then cut the prompt down. Instagram is huge, so ask which flows matter: "Should I focus on the home feed, posting a photo, or stories?" Ask the questions that change the design most: how many posts a feed can hold, mobile web or desktop, how fresh the feed must be. Write the answers as functional, non-functional with numbers, and out of scope.
Question 2
Why does RADIO put requirements first and optimizations last?
Each part depends on the one before it. You can't pick the parts without knowing what the system must do; you can't name the data without knowing which parts hold it; you can't define the API without the data it carries.
Optimizations come last because they are chosen by the earlier steps: the hardest non-functional requirement and the part that is special to the problem tell you where to dig. Optimizing first means tuning a design that may be wrong.
Question 3
How do you choose which deep dives to do?
Look for strain. Which non-functional requirement is hardest to meet (5,000 items, under-a-second updates, offline)? What is special about this problem compared with any other app (out-of-order responses in an autocomplete, conflicts in an editor)? What has the interviewer asked about twice?
Pick two or three, offer them to the interviewer before starting, and run each one as problem with a number, options, choice, how it works, and cost. Depth on three beats a list of ten.
Question 4
How does your approach differ between "design a date picker" and "design a chat app"?
The date picker is a component question. Architecture is small (input, calendar grid, popup), the interface is the centre (value and onChange, controlled and uncontrolled, min and max dates, locale, render slots), and the deep dives are usually keyboard and screen reader support, internationalization (week start, calendars, right-to-left), and time zones.
The chat app is an app question. Requirements must cut scope, architecture shows the store, data layer, push channel, and server, the data model has users, conversations, and messages, the interface is mostly server API plus socket events, and deep dives are delivery and ordering, reconnects, offline sending, and long message lists.
Question 5
Isn't following a framework going to make your answer sound robotic?
Only if you use it as a script. RADIO is a checklist: it reminds you what a complete answer must cover and in roughly what order, so nothing is forgotten and the clock goes to the hard parts.
The answer itself should sound like a story of decisions, where each choice leads to the next: "because the list is long I'll virtualize, so the store must give items by index, so the API pages with a cursor." Follow the interviewer's hints even when they jump ahead, and just come back to any letter you skipped.
References
- GreatFrontEnd: Front End System Design Guide Where the RADIO name comes from, with worked questions.
- web.dev: Web Vitals The LCP, INP, and CLS thresholds to quote as non-functional requirements.
- WAI-ARIA Authoring Practices: Combobox pattern The keyboard and ARIA rules used in the worked example.
- WCAG 2.2 The accessibility standard behind "meets WCAG AA".
- MDN: AbortController Cancelling old requests in the autocomplete deep dive.
- TanStack Query: Overview A common way to separate server state from UI state in the data model.
Read next
- What interviewers look for, by levelThe six areas interviewers typically score in a frontend system design round, how the bar rises from junior to staff, and how to make the signals of your target level visible, minute by minute.
- Component questions vs app questionsFrontend design prompts come in two shapes, a reusable component or a whole product, and each needs a different emphasis and a different use of your 45 minutes.
- Back-of-the-envelope numbers for frontendQuick, rough math with round numbers (bytes over the network, CPU time on a cheap phone, memory in a long-lived tab, and requests per second at the server) that turns "this might be slow" into a reason to pick one design over another.
- REST for frontendsA way to shape an HTTP API around resources and a few standard verbs, so the frontend can fetch, cache, retry, and handle errors in the same predictable way everywhere.
- Pagination: offset, cursor, and keysetWays to load a long list one piece at a time, and why the choice decides whether users see duplicates, miss items, or wait on slow deep pages when the list changes.
- Core Web VitalsThree numbers, measured on real users, that say whether a page loads fast (LCP), reacts fast (INP), and stays still (CLS): what each one measures, what makes it bad, and how to fix it.