LLD Framework: How to Approach Any Design Problem

A repeatable 5-step process for frontend LLD interviews โ€” requirements, API design, data model, class structure, and edge cases.

must medium โฑ 20 min lldframeworkapproachrequirementsapi-design
Mastery:
Why interviewers ask this
LLD is common at mid/senior frontend interviews. Interviewers want to see structured thinking โ€” not just code, but the process of arriving at a clean design.

LLD (Low-Level Design) is about the structure of the code โ€” classes, interfaces, APIs, and how components interact. Frontend LLD problems ask you to design a component, a utility, or a small system with real TypeScript/JavaScript code.

The 5-step framework

Use this every time โ€” interviewers want to see process, not just output.

Step 1: Clarify requirements (2 min)

Before writing any code, ask:

  • What is the core use case? (Never skip this โ€” know what youโ€™re building.)
  • What are the must-have vs nice-to-have features?
  • What constraints apply? (browser support, performance, accessibility, TypeScript?)
  • What does the public API look like โ€” class, function, hook, or component?
Example: "Design an autocomplete"
Questions to ask:
  - Remote data or local?
  - Single select or multi-select?
  - Keyboard navigation required?
  - Debounce needed?
  - What should the component expose to the parent?

Step 2: Define the public API

Write the interface/signature before the implementation. This is what the consumer of your design sees:

// For a class-based utility
interface DebounceOptions { leading?: boolean; trailing?: boolean; }
function debounce<T extends (...args: any[]) => any>(
  fn: T,
  ms: number,
  options?: DebounceOptions
): T & { cancel(): void; flush(): void }

// For a React component
interface AutocompleteProps<T> {
  options: T[];
  value: T | null;
  onChange: (value: T | null) => void;
  getLabel: (option: T) => string;
  onSearch?: (query: string) => Promise<T[]>;  // remote
  placeholder?: string;
  disabled?: boolean;
}

Step 3: Design the data model

Identify:

  • What state does this need?
  • What is derived vs stored?
  • What events/callbacks cross the boundary?
// Autocomplete internal state
interface AutocompleteState<T> {
  query: string;          // current input value
  options: T[];           // current list of options to display
  selectedIndex: number;  // keyboard focus position (-1 = none)
  isOpen: boolean;        // dropdown visible
  isLoading: boolean;     // async fetch in progress
}

Step 4: Sketch the structure

Talk through your component/class hierarchy before coding:

<Autocomplete>
  โ”œโ”€โ”€ <Input>         (controlled, fires onInput for debounced search)
  โ”œโ”€โ”€ <Dropdown>      (conditionally rendered, handles click-outside)
  โ”‚   โ””โ”€โ”€ <OptionList>
  โ”‚       โ””โ”€โ”€ <OptionItem> ร— N
  โ””โ”€โ”€ (keyboard handler lives at Autocomplete level)

Or for a utility/class:

EventEmitter
  โ”œโ”€โ”€ on(event, fn) โ†’ unsubscribe fn
  โ”œโ”€โ”€ off(event, fn)
  โ”œโ”€โ”€ emit(event, ...args)
  โ””โ”€โ”€ once(event, fn) โ†’ auto-removes after one call

Step 5: Code the core, talk through the rest

Code the most interesting or risky parts:

  • The state management logic
  • The key algorithm (debounce, virtual scroll, event dispatch)
  • The tricky edge case

Then say out loud what youโ€™d do for the rest rather than coding everything:

โ€œIโ€™d add keyboard navigation next โ€” ArrowUp/Down would update selectedIndex, Enter would select. Iโ€™d also add onClickOutside to close the dropdown.โ€

What interviewers evaluate

DimensionWhat they look for
CorrectnessDoes the core logic work?
API designIs it clean and ergonomic for consumers?
ExtensibilityCan new features be added without rewriting?
Edge casesEmpty state, error state, loading, accessibility
TypeScriptGenerics, proper types, no any unless justified
CommunicationDo you explain your decisions?

LLD vs HLD (quick distinction)

LLDHLD
FocusClasses, functions, APIs, stateServers, databases, queues, services
OutputTypeScript/JavaScript codeArchitecture diagrams, sequence flows
ScaleOne component or utilityEntire distributed system
Time frame20โ€“40 min40โ€“60 min
Asked atFrontend SDE-2+Full-stack / backend SDE-2+

The framework in 30 seconds
Requirements โ†’ API signature โ†’ Data model โ†’ Component/class structure โ†’ Code the core, talk through the rest. Speak every decision out loud. Interviewers give more credit for explaining your tradeoffs than for writing perfect code in silence.

Likely follow-up questions
  • How do you identify the boundaries of a LLD problem?
  • What is the difference between LLD and HLD?
  • How do you handle extensibility in a component design?
  • When would you use composition over inheritance?

References