Amazon Frontend Interview Questions
Front-End Engineer loop: UI coding plus Leadership Principles.
Amazon has a dedicated Front-End Engineer role alongside the general SDE role. Its interviews test the same things in a web setting: coding, problem solving and design, with UI work in place of some backend questions.
Two things set the loop apart. Every interviewer also asks behavioural questions mapped to Amazon's Leadership Principles, and they count as much as the technical ones. And UI coding is often done in plain JavaScript, HTML and CSS, without a framework.
- Questions
- 15, 5 with free answers
- Interview rounds
- 4
- Last reviewed
- October 2026
Amazon frontend interview process
The usual shape of the loop. A guide to what to prepare, not a promise of what you will get.
- 1
Online assessment
Coding problems, sometimes with a work-style survey.
- 2
Phone screen
A coding problem or a small UI task, plus Leadership Principles questions.
- 3
Interview loop
Usually four or five interviews: UI coding, data structures and algorithms, and frontend system design for experienced levels. Each includes behavioural questions.
- 4
Bar raiser
One interviewer from outside the hiring team, who judges long-term fit against the Leadership Principles.
What interviewers tend to look for
- Building a component with the DOM API directly: events, delegation, state kept in plain variables.
- Prepared stories for the Leadership Principles, told as situation, action and result.
- Edge cases and accessibility in everything you build.
- Performance thinking for pages with very high traffic.
Your Amazon mock interview
15 questions. Type an answer under each one and an AI reviewer scores it and tells you what you missed. Stuck on one? Ask for a hint. A free account gets 3 AI replies a day.
Your mock interview
0 of 15 answered
Answer a question and your score shows up here.
JavaScript
6 questions- Question 1 of 15JavaScript
Amazon interviewer
What is a closure? Give a practical use for one.
Model answer
A closure is a function together with the scope it was created in. The function keeps access to the variables of that scope even after the outer function has returned.
function createCounter() { let count = 0; // private: nothing outside can touch it return { increment: () => ++count, value: () => count, }; } const counter = createCounter(); counter.increment(); counter.value(); // 1Practical uses: private state as above, function factories, and utilities such as
debounceandmemoize, which keep a timer or a cache between calls.The cost to mention: a closure keeps its captured variables alive for as long as the function is reachable, so a long-lived callback holding a large object is a memory leak.
- Question 2 of 15JavaScript
Amazon interviewer
What is event delegation? Explain bubbling and capturing.
Model answer
A DOM event travels in three phases: down from
windowto the target (capturing), at the target, then back up towindow(bubbling). Listeners run in the bubbling phase unless you pass{ capture: true }.Delegation uses bubbling: you put one listener on a common ancestor and work out which child was clicked.
list.addEventListener('click', (event) => { const item = event.target.closest('li[data-id]'); if (!item || !list.contains(item)) return; select(item.dataset.id); });Benefits: one listener instead of hundreds, and it keeps working for items added later.
Details that come up:
stopPropagationstops the event travelling,preventDefaultcancels the browser's default action, and a few events such asfocusandblurdo not bubble (usefocusinandfocusout). - Question 3 of 15JavaScript
Amazon interviewer
What is the difference between debounce and throttle? Implement debounce.
Model answer
Debounce waits until the calls stop for a set time, then runs once. Use it for a search box or for saving after the user stops typing. Throttle runs at most once per interval while the calls keep coming. Use it for scroll, resize and drag handlers.
function debounce(fn, wait) { let timer; return function (...args) { clearTimeout(timer); timer = setTimeout(() => fn.apply(this, args), wait); }; }Common follow-ups: keep
thisand the arguments (done above), add acancelmethod, add aleadingoption that fires on the first call, and then write throttle. - Question 4 of 15JavaScript
Amazon interviewer
Flatten a nested array without using Array.prototype.flat.
Model answer
function flatten(array, depth = Infinity) { const result = []; for (const item of array) { if (Array.isArray(item) && depth > 0) { result.push(...flatten(item, depth - 1)); } else { result.push(item); } } return result; } flatten([1, [2, [3, [4]]]]); // [1, 2, 3, 4] flatten([1, [2, [3, [4]]]], 1); // [1, 2, [3, [4]]]Follow-ups: write it iteratively with a stack so that very deep nesting cannot overflow the call stack, and flatten an object into dot-separated keys (
{ a: { b: 1 } }to{ 'a.b': 1 }). - Question 5 of 15JavaScript
Amazon interviewer
Implement a memoize function.
Model answer
function memoize(fn, resolver = (...args) => JSON.stringify(args)) { const cache = new Map(); return function (...args) { const key = resolver(...args); if (!cache.has(key)) { cache.set(key, fn.apply(this, args)); } return cache.get(key); }; }The discussion is about the cache key and the cache size:
JSON.stringifyfails on functions and circular objects, and treats{a:1,b:2}and{b:2,a:1}as different. That is why the resolver is a parameter.- The cache grows without limit. Cap it with an LRU policy for long-running pages.
- For a single object argument, a
WeakMaplets the entry be garbage collected with the object. - Only memoize pure functions. Memoizing an async function caches the promise, including a rejected one.
- Question 6 of 15JavaScript
Amazon interviewer
What does a setTimeout inside a
for (var i ...)loop print, and how do you fix it?Model answer
for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 0); } // 3, 3, 3varis function-scoped, so there is oneishared by all three callbacks. They run after the loop has finished, wheniis already 3.Fixes, in the order you would reach for them:
- Use
let. It creates a new binding for each iteration, so the output is 0, 1, 2. - Pass the value in:
setTimeout((n) => console.log(n), 0, i). - Wrap the body in an immediately invoked function that takes
ias a parameter. This is the pre-ES6 answer.
- Use
React
3 questions- Question 7 of 15React
Amazon interviewer
What makes a component re-render, and how do you cut unnecessary re-renders?
Model answer
A component re-renders when its own state changes, when its parent re-renders, or when a context it reads changes. A changed prop is not a separate cause: props change because the parent rendered.
A re-render is React calling the function again. It is not a DOM update, and most are cheap. Measure with the React DevTools Profiler before changing anything.
When one is a real problem, in rough order of preference:
- Move state down into the component that uses it, so fewer components sit below it.
- Pass expensive content as
children. Elements created by a parent that did not re-render are reused as they are. - Wrap a costly child in
React.memoand give it stable props. - Split a large context, or use a store that lets components subscribe to a slice.
- Virtualise long lists.
- Question 8 of 15React
Amazon interviewer
What is the difference between a controlled and an uncontrolled component?
Model answer
In a controlled input, React state holds the value. You pass
valueandonChange, and every keystroke goes through state. That makes validation, formatting and conditional UI easy.In an uncontrolled input, the DOM holds the value. You give it a
defaultValueand read the result on submit, through a ref orFormData.// Controlled <input value={email} onChange={(e) => setEmail(e.target.value)} /> // Uncontrolled <form onSubmit={(event) => { event.preventDefault(); const data = new FormData(event.currentTarget); save(data.get('email')); }} > <input name="email" defaultValue="" /> </form>Uncontrolled inputs re-render less, which is why form libraries such as React Hook Form use them, and React 19 form actions work the same way. A file input is always uncontrolled.
The warning to recognise: an input whose
valuegoes fromundefinedto a string has switched from uncontrolled to controlled. Start it with an empty string. - Question 9 of 15React
Amazon interviewer
How would you render a list of 10,000 rows without the page slowing down?
Model answer
Render only the rows that are on screen. This is called windowing or virtualisation.
The container gets the full scroll height (row count times row height). From the scroll position you work out which rows are visible, render those plus a few extra above and below, and position them with a transform. Scrolling changes which twenty or so rows exist.
In practice use a library such as TanStack Virtual or react-window. Writing a fixed-height version by hand is a common interview task.
Things to raise:
- Rows of unknown height have to be measured after they render.
- Fetch the data in pages too. Virtualising 10,000 rows you downloaded in one request only solves half the problem.
- Use stable keys and memoised rows.
- The browser's find-in-page cannot see rows that are not rendered, and screen readers need
aria-rowcountandaria-rowindex. content-visibility: autoin CSS is a cheaper option for moderately long pages.
CSS
2 questions- Question 10 of 15CSS
Amazon interviewer
Explain the CSS box model and box-sizing.
Model answer
Every element is a box made of four layers: content, padding, border and margin.
box-sizingdecides whatwidthandheightmeasure. With the default,content-box, they set the content area only, so a 200px wide box with 20px padding and a 1px border takes 242px. Withborder-box, the padding and border are included in the 200px. That is easier to reason about, which is why most projects start with:*, *::before, *::after { box-sizing: border-box; }Related points that get asked:
- Vertical margins of adjacent block elements collapse into the larger of the two. This does not happen inside flex or grid containers.
- Inline elements ignore
width,heightand vertical margins.inline-blockaccepts them. outlineis drawn outside the border and does not take up space.
- Question 11 of 15CSS
Amazon interviewer
How many ways can you centre an element horizontally and vertically?
Model answer
/* 1. Grid: the shortest */ .parent { display: grid; place-items: center; } /* 2. Flexbox */ .parent { display: flex; justify-content: center; align-items: center; } /* 3. Absolute positioning, size unknown */ .child { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } /* 4. Absolute positioning with auto margins, size known */ .child { position: absolute; inset: 0; margin: auto; width: 200px; height: 100px; }Interviewers usually want you to explain one of them. In the third,
topandleftmove the child's corner to the middle of the parent, and the transform shifts it back by half of its own size, because percentages intranslaterefer to the element itself.For horizontal centring only:
margin-inline: autoon a block with a width, ortext-align: centerfor inline content.
Browser, performance and system design
3 questions- Question 12 of 15Browser, performance and system design
Amazon interviewer
What happens between typing a URL and seeing the page?
Model answer
- DNS turns the domain into an IP address.
- The browser opens a connection: a TCP and TLS handshake, or QUIC for HTTP/3.
- It sends the request and the server starts streaming HTML back.
- The parser builds the DOM as HTML arrives. CSS is downloaded and parsed into the CSSOM. CSS blocks rendering, and a plain
scripttag blocks the parser until it has downloaded and run. - DOM and CSSOM are combined into the render tree, which holds only what is visible.
- Layout works out the size and position of every box, paint fills in the pixels, and compositing puts the layers on screen.
- JavaScript then runs, and in a framework app it hydrates the page so that it responds to input.
This sequence is called the critical rendering path. Most performance work is shortening it: fewer and smaller render-blocking files,
deferon scripts, inlining the CSS needed for the first screen, compression, a CDN close to the user, and caching so that repeat visits skip the network.Interviewers often pick one step and go deeper, so know at least one well.
- Question 13 of 15Browser, performance and system design
Amazon interviewer
How do you make a web page accessible?
Model answer
- Use the right HTML element. A
buttonis focusable, works with Enter and Space and is announced as a button. Adivwith a click handler does none of that. The same goes fornav,main, headings in order, and alabelfor every input. - Keyboard. Everything must be reachable and usable without a mouse, in a sensible order, with a visible focus ring. When a dialog opens, move focus into it, keep it there, and return it to the trigger on close.
- Text alternatives. Images need
alttext, or an emptyaltif they are decorative. Icon-only buttons need an accessible name. - Colour. Body text needs a contrast ratio of at least 4.5 to 1, and colour should never be the only signal.
- ARIA, when HTML is not enough.
aria-expandedon a toggle,aria-livefor updates that appear without a page load, roles for custom widgets. No ARIA is better than wrong ARIA. - Motion and zoom. Respect
prefers-reduced-motion, and make sure the page works at 200% zoom.
For testing: use the page with the keyboard only, run an automated checker such as axe or Lighthouse, and try a screen reader on the main flows. Automated tools catch only part of the problems.
- Use the right HTML element. A
- Question 14 of 15Browser, performance and system design
Amazon interviewer
Frontend system design: design an infinite-scrolling news feed.
Model answer
- API: cursor-based pagination (
?cursor=abc&limit=20). Offsets break when new posts are inserted at the top. - First load: render the first page on the server so that content appears without waiting for JavaScript.
- Loading more: an
IntersectionObserveron a sentinel near the end of the list fetches the next page. Guard against sending the same request twice. - Long lists: virtualise, so that scrolling through thousands of posts does not keep thousands of DOM nodes.
- State: store posts by id, with the feed as an ordered list of ids. A like then updates one record wherever the post is shown.
- Interactions: update optimistically and roll back if the request fails.
- Media: lazy-load images, reserve their space with an aspect ratio, and serve sizes that fit the device.
- New posts: receive them over SSE or a WebSocket, but show a "New posts" button instead of pushing content down while someone is reading.
- Resilience: skeletons while loading, a retry row on failure, and scroll position restored when the user comes back from a post.
Then cover accessibility (
role="feed", working keyboard navigation), the metrics you would track (LCP, INP while scrolling, memory over a long session) and the trade-offs of each choice. - API: cursor-based pagination (
Machine coding
1 question- Question 15 of 15Machine coding
Amazon interviewer
Build a star rating component.
Model answer
Props:
value,max(default 5),onChangeandreadOnly. Keep one extra piece of state,hovered, separate from the selected value, so that moving the mouse previews a rating without changing it.function StarRating({ value, max = 5, onChange, readOnly = false }) { const [hovered, setHovered] = useState(0); const shown = hovered || value; return ( <div role="radiogroup" aria-label="Rating" onMouseLeave={() => setHovered(0)}> {Array.from({ length: max }, (_, i) => i + 1).map((star) => ( <button key={star} type="button" role="radio" aria-checked={star === value} aria-label={star + ' out of ' + max} disabled={readOnly} onMouseEnter={() => setHovered(star)} onClick={() => onChange(star === value ? 0 : star)} > {star <= shown ? '★' : '☆'} </button> ))} </div> ); }- Clicking the current rating again clears it. Ask whether that is wanted.
- It must work with the keyboard and announce its value. Styled radio inputs are the simplest fully accessible build.
- It is a controlled component: the parent owns
value.
Follow-ups: half stars (work out from the pointer position which half was clicked), a read-only display with fractional fill such as 3.7, and a custom icon.
Practise for Amazon
Reading answers is the easy half. These problems run in the browser against real tests.
