“Design Linear” is a senior+ frontend system-design prompt that captures the modern SaaS-app shape — fast keyboard-driven UI, offline-first sync, real-time collaboration, and the polish that defines the Linear / Notion / Height tier. The interview tests whether you can decompose a complex product into a clean state architecture without losing the snappy feel.
Clarify scope
- Issue tracking only or also docs, projects, cycles, roadmap?
- Real-time multi-user updates?
- Offline support?
- Web only or desktop / mobile too?
- Keyboard-first or mouse-friendly?
The data model
{
workspaceId,
workspace: { teams, members, projects, settings },
issuesById: Map<id, Issue>,
issuesByTeam: Map<teamId, Set<id>>,
issuesByProject: Map<projectId, Set<id>>,
filtersByView: Map<viewId, Filter>,
presence: Map<userId, status>
}
Issues are the leaf type. Views (Active, Backlog, custom filters) reference issues by ID. Updates to one issue propagate cleanly to all views.
The killer feature: keyboard speed
Linear’s differentiator is keyboard navigation:
- Cmd+K — command palette (search issues, run commands)
- J/K to move between issues
- Number keys to set priority
- L to add labels
- S to set status
- P to set project
- Cmd+Enter to create
Implement as a global key handler that respects focused element (do not steal keys from text inputs). Each shortcut maps to a command in the command registry.
The command palette
- Single keyboard shortcut opens it (Cmd+K)
- Searches issues, projects, members, settings, and commands
- Fuzzy match across all entity types
- Run command directly without opening the issue
- “New issue: …” inline create from the palette
Power users live in the palette. Make it instant; lazy-load anything that is not in the visible result list.
Real-time sync
- WebSocket subscription to the workspace
- Each change broadcast to all online users
- Optimistic local updates; reconcile on server confirmation
- Conflict resolution: latest-write-wins per field
- Linear uses an internal sync engine that’s well-published; the principles are CRDT-adjacent
Offline support
- Persist state to IndexedDB on every meaningful change
- Reads work fully offline; cached state hydrates the UI
- Writes queue locally; flush to server on reconnect
- Per-mutation idempotency key prevents duplicates
- UX: subtle “Offline” indicator; do not block work
The issue list view
- Virtualized (react-virtual or TanStack Virtual)
- Group by status, priority, assignee, project
- Inline edit (click status badge → menu, no modal)
- Drag-to-reorder within group
- Multi-select with Shift+Click and Cmd+Click
- Bulk actions on multi-select
The issue detail view
- Metadata sidebar (status, priority, assignee, project, labels)
- Description with rich-text editor (Markdown + slash commands)
- Comments thread
- Activity log (status changes, comments, edits)
- Sub-issues / linked issues
Filters and views
- Filter combinations (AND/OR) on multiple fields
- Saved views with shareable URLs
- “My issues”, “Recently updated”, “No assignee” common filters
- Filter UI integrated with command palette (“Filter by…”)
Cycles and projects
- Cycles = time-boxed sprints with start/end dates
- Projects = larger groupings of issues with progress tracking
- Roadmap view = projects laid out on a timeline
- Status auto-rolls up from issues to projects
Performance
- Memoize issue components by ID
- Debounce filter recomputation; do not re-filter on every keystroke
- Pre-warm rendering of commonly-visited views
- Use a single global store, not per-view stores (avoids duplication)
The Electron / web split
- Linear ships a desktop Electron app and a web app from the same codebase
- Native integrations: global hotkey, system tray, menu bar
- Same React tree; thin native wrapper
Notifications
- In-app inbox (mention, assigned, status change)
- Email digest (daily summary)
- Slack integration (per-team channel)
- Per-category preferences
What separates senior from staff
Senior candidates draw the data model and discuss virtualization. Staff candidates address the keyboard-first interaction model, the command palette as a unification primitive, and the offline-first sync architecture. Principal candidates discuss the desktop / web codebase split and the tradeoffs of optimistic UI under conflict.
Frequently Asked Questions
How does Linear keep the UI so snappy?
Single store, in-memory primary, indexed-by-id rather than denormalized. Optimistic mutations resolve immediately. Server confirmations reconcile silently in the background. The detail is in the discipline.
What about Jira-style customization?
Linear deliberately avoids deep customization to keep the UI clean. The interview tradeoff: customization vs simplicity is a real product-design question worth raising.
Should I use Linear’s open-source sync engine?
It is not fully open-source. Yjs + a small custom layer is a reasonable substitute. The architectural principles are publicly described in Linear’s engineering blog.