Machine coding

Build an Autocomplete Component

← Back to Machine coding

Difficulty: 🟡 Medium · Est. time: 45m · Tags: #input #async #a11y #debounce

Asked at: Google, Meta, Amazon, Airbnb · Related: System design: Autocomplete · debounce/throttle


1. The Question

Build a reusable autocomplete/typeahead input that fetches suggestions as the user types, is keyboard-accessible, and handles loading/error/empty states.

2. Requirements

Functional

Non-functional

3. Component API

type AutocompleteProps<T> = {
  value: string;
  onChange: (value: string) => void;
  onSelect: (item: T) => void;
  fetchSuggestions: (query: string, signal: AbortSignal) => Promise<T[]>;
  getLabel: (item: T) => string;
  debounceMs?: number;   // default 250
  minChars?: number;     // default 1
};

4. Implementation Notes & Trade-offs

Debounce → a useDebouncedValue(value, 250) hook (or a debounced effect). Query only after the user pauses.

Race conditions → each fetch gets an AbortController; abort the previous one before firing a new one. Also guard by comparing the resolved query to the current input before setting state.

Highlighted index → track activeIndex; wire aria-activedescendant to the option id. Reset on new results. Scroll the active option into view.

Accessibility (combobox) → input has role="combobox", aria-expanded, aria-controls={listboxId}, aria-autocomplete="list". Listbox has role="listbox"; options role="option" with aria-selected. Announce result counts via aria-live="polite".

Match highlighting → split each label on the query and wrap matches in <mark> — never innerHTML (XSS).

Edge cases → empty input clears results; trailing whitespace; rapid backspace (cache hits); no-results message; error retry; click-outside via a pointerdown listener; don't lose focus on option click (use onMouseDown preventDefault).

Cleanup → abort in-flight requests and clear timers on unmount.

5. What Interviewers Probe

  • Debounce vs throttle here?
  • How do you kill stale responses? (AbortController + query guard)
  • Full keyboard model + focus handling.
  • ARIA combobox correctness.
  • Why not dangerouslySetInnerHTML for highlighting?
  • How do you make it reusable (headless vs styled)?

6. Curated Resources

ESC

Type to search across every question bank.

navigate open 3,610 questions indexed