Machine Coding Interview Framework
A timed framework for FE machine coding rounds — scope MVP, shape state, ship happy path, then a11y and edge cases.
- interview
- machine-coding
Machine coding (UI coding) rounds fail when you paint first or over-engineer. Interviewers want a working product slice, readable state, and conscious tradeoffs.
What interviewers score
- Problem decomposition — MVP vs stretch
- State design — single source of truth
- Correct interactions under time
- Code hygiene — components, names, no soup
- Product polish — loading/error/empty, a11y basics
Timebox (45–60 minutes)
| Block | % | Do |
|---|---|---|
| Clarify & MVP | 10% | Write acceptance bullets |
| State & component tree | 10% | Sketch on paper/comments |
| Scaffold | 10% | Files, props, dead UI |
| Happy path | 40% | Core user journey works |
| Resilience | 15% | empty/error/loading |
| A11y + cleanup | 15% | keyboard, labels, remove logs |
If happy path isn’t working at 70% time, stop polishing CSS.
Clarify questions (ask early)
- Desktop only or responsive?
- Controlled data source (mock API vs local)?
- Persistence?
- Multi-select / keyboard requirements?
- Libraries allowed (React, lodash)?
Restate MVP as a checklist the interviewer can nod at.
State design worksheet
Entities: Item { id, title, ... }
Collections: items: Item[]
UI state: query, isOpen, selectedId, status: idle|loading|error
Derived: filtered = useMemo(...)
Updates: add / remove / toggle / setQuery
Rules of thumb:
- Server data vs ephemeral UI state separated
- Avoid duplicating derived fields
- IDs over index keys for lists — Keys
Component tree (example: autocomplete)
Autocomplete
├── Label + input (combobox)
├── Status text (aria-live)
└── Listbox
└── Option[]
Practice: Autocomplete search box.
Implementation order
- Static markup with semantic controls
- Local state for open/query
- Filter logic pure function (testable)
- Wire events
- Async if needed — debounce + abort
- Keyboard — arrows, Enter, Escape
- ARIA — expanded, active descendant
Debounce: Debounce implementation. Abort: AbortController.
UI states matrix
| State | UI |
|---|---|
| Idle empty query | Placeholder / instructions |
| Loading | Spinner + aria-busy |
| Success empty | “No results” |
| Success data | List |
| Error | Message + retry |
Never ship only the success path.
Accessibility minimum bar
- Real
<button>/<input> - Label association
- Focus visible
- Escape closes overlays
- Tab order makes sense
Patterns: Accessible combobox · Focus management · Modal.
Code quality signals
| Good | Bad |
|---|---|
| Small pure helpers | 200-line component |
| Explicit status union | isLoading + isError combos fighting |
| CSS modules / clear class names | Inline style chaos mid-round |
| Early return render | Nested ternary hell |
Common prompts → practice
| Prompt | Practice |
|---|---|
| Todo + filter | Todo app |
| Modal | Accessible modal |
| Infinite scroll | Infinite scroll feed |
| Tabs / accordion | Accordion |
| Dropdown | Custom dropdown |
| Kanban | Kanban board |
| Nested comments | Nested comments |
Hub: /machine-coding.
When stuck
- Hardcode data; make UI work
- Extract pure function; log inputs
- Delete broken abstraction; inline
- Say stretch goals you’ll skip
Closing speech (2 minutes)
“MVP: search filters list client-side with debounce. Stretch not done: server paging. A11y: combobox roles partial; Enter selects. Complexity filter O(n). Next would add virtualization for large n.”
Related on this site
- Whiteboarding UI components
- React interview questions
- How to structure answers
- Common mistakes
- Machine coding hub
- Interview hub
Further reading
Ship a narrow correct slice. Interviewers extend winners; they can’t extend a half-styled unfinished idea.