“Build a Twitter timeline” is one of the most popular frontend system design questions at FAANG, mid-tier social, and FinTech companies. The interviewer wants to see if you understand the unique problems of a feed: infinite scroll without jank, real-time updates without losing scroll position, optimistic actions (like, reply, retweet), and accessibility on a feed that’s constantly changing.
Functional requirements
- Display a vertical feed of tweets/posts
- Infinite scroll — load more as user scrolls down
- Real-time updates — new posts appear without manual refresh
- Optimistic actions: like, retweet, reply (bookmark, share)
- Quoted tweets and threads
- Media (images, videos) inline
Non-functional
- 60fps scroll on mid-range devices
- Smooth on 100+ items in DOM
- Network-resilient — actions queue offline
- Accessible (screen readers, keyboard nav)
Architecture
Three layers: data layer (state management), render layer (virtualized list), action layer (optimistic updates).
Virtualization
Never render 1000 tweets in the DOM. Use a windowed list (react-window, react-virtualized, TanStack Virtual). Render only the ~20 visible items + a small overscan buffer.
Tradeoff: fixed-height items are easier; variable-height (long tweets, multi-image) require dynamic measurement. Modern libraries handle this with intersection observers and ResizeObserver.
Infinite scroll
Use IntersectionObserver to detect when the user is ~3 viewports from the bottom. Trigger a fetch for the next page. Append to the in-memory list. Update the virtualized list — items continue rendering smoothly.
State management
For a non-trivial timeline:
- Server state (tweets, like counts) → React Query / SWR / Apollo
- Client state (which tweets are selected, expanded) → Zustand / Redux
- Cursor-based pagination — never offset, which breaks under inserts
Real-time updates
Two strategies:
- Polling: every 30–60 seconds, fetch tweets newer than last seen. Simple, reliable.
- WebSocket / SSE: server pushes new tweets. Lower latency, more complex.
Either way, do not auto-prepend new tweets at the top — that hijacks the user’s reading. Show a “X new tweets” banner; user taps to expand.
Optimistic updates
For likes/retweets:
- User taps the like button
- Update local state immediately — like count +1, button highlighted
- Send POST to server in background
- If server fails, revert state and show error toast
- If server succeeds, replace optimistic state with server-canonical
React Query and Apollo both have first-class support for this pattern.
Media handling
- Use
loading="lazy"for off-screen images - Provide intrinsic width/height to prevent layout shift
- Use srcset for responsive images
- Pause autoplay videos when out of viewport
Accessibility
- Each tweet is a
<article>with proper heading structure - Action buttons have explicit labels
- Live region announces new tweets to screen readers (without spamming)
- Keyboard nav — j/k to move between tweets, like/retweet keyboard shortcuts
Frequently Asked Questions
How do you handle a tweet being deleted while in view?
Replace with a “this tweet was deleted” placeholder. Maintain scroll position by keeping the same DOM node height.
What about user scroll position when new tweets arrive?
Anchor scroll position to the visible tweet (not absolute pixel). When new tweets prepend, the anchor stays in place. Native scroll anchoring (overflow-anchor CSS) helps.
How do you test this?
Cypress / Playwright for end-to-end. Visual regression with Percy / Chromatic. Performance via Lighthouse. Accessibility via axe-core in CI.