Top 30 Intermediate Frontend Dev Interview Questions and Answers
30 intermediate multiple-choice Frontend Dev interview questions, past the definitions: how the pieces fit together, what breaks in practice, and the trade-off behind a choice. They come from 30 bites in the Frontend Dev library, the middle slice of the 537 Frontend Dev interview questions in the library. Answer them here or read straight down. Every question carries the correct option, why it is correct, and a link to the bite it came from.
Frontend web development and UI engineering
30 questions. Pick an answer, or open “Show the answer” to read it.
Answers are graded in your browser. Nothing is saved, and no XP or streak is earned here. The app keeps score.
Question 1 of 30
What happens when TypeScript cannot infer a type and noImplicitAny is disabled?
Show the answer
Answer: c · The compiler silently assigns the any type, disabling further static analysis for that value
When noImplicitAny is disabled, TypeScript silently falls back to any for uninferrable values, which opts them out of static checking and allows runtime errors to go undetected. Option B describes what happens when the flag is enabled, making it a tempting reversal.
Read the full bite: What is noImplicitAny and why is it best practice?
Question 2 of 30
A user-agent stylesheet sets a button to black with a high-specificity selector, and an author stylesheet sets it to blue with a low-specificity selector. What is the final color?
Show the answer
Answer: b · Blue, because author styles originate from a higher origin than user-agent styles, and origin is evaluated before specificity.
The cascade evaluates origin before specificity, so an author rule always beats a user-agent rule regardless of selector weight. Option A represents the common misconception that specificity trumps origin, while D incorrectly invokes source order when origin already differs.
Read the full bite: Describe the full CSS cascade precedence order
Question 3 of 30
When a reactive variable changes in Svelte, how is the update triggered differently than in Vue 3's runtime Proxy system?
Show the answer
Answer: a · By compiler transforms that turn assignments into explicit update calls
Svelte resolves dependencies at build time by transforming assignments into explicit update logic in the compiled output, so no runtime tracker is needed. Option B is tempting because Vue 3 uses runtime Proxies, but Svelte does not use them at all.
Read the full bite: Compare and contrast Vue 3 and Svelte reactivity systems
Question 4 of 30
Which operation is valid on a variable of type unknown without first narrowing its type?
Show the answer
Answer: b · Assigning a string value to the unknown variable
Any value can be assigned to an unknown variable, but you cannot read properties, call methods, or assign it to a narrower type without narrowing first. Options A and D confuse unknown with any, which is assignable to all types, while B requires narrowing because the compiler cannot guarantee the method exists.
Question 5 of 30
When a dynamic list reorders and items have local state, what happens if array indices are used as React keys?
Show the answer
Answer: d · React reuses component instances by position, causing state from one data item to appear on another.
Array indices tie identity to position, so React reuses the wrong component instance after reorder or deletion and state ends up attached to the wrong data item. Option B is wrong because React does not reset state when keys are unstable—it incorrectly preserves it on the reused instance.
Read the full bite: What is the purpose of React's key prop and index key risks?
Question 6 of 30
When handling a parameter typed as string or string array, which approach correctly narrows the value at runtime?
Show the answer
Answer: d · Check whether Array.isArray(arg) is true
Array.isArray is the recognized type guard that safely narrows the union within the block. Checking typeof against array is a runtime bug because typeof returns object for arrays, never array.
Read the full bite: How do you type and guard a string-or-string-array argument?
Question 7 of 30
Why does Angular treat dependency injection as a runtime architectural layer rather than relying on ES module imports like Vue?
Show the answer
Answer: c · It enables runtime resolution of service lifetimes and implementation swapping without changing consumer code or direct file coupling.
Angular's DI is a runtime inversion-of-control system that supports scoped lifetimes, tree-shakable providers, and test-time substitution without modifying consumer code. The boilerplate distractor is wrong because DI still requires constructor declarations; its architectural value lies in runtime indirection and hierarchical resolution, not syntax savings.
Read the full bite: Why is DI central to Angular architecture versus Vue's module system?
Question 8 of 30
In React, when is an early return with if/else preferable to an inline ternary inside JSX?
Show the answer
Answer: a · When branches are large, structurally different, or to reduce nesting
Early returns improve readability when branches are large, structurally different, or deeply nested. Option B actually describes when an inline ternary is the better choice, not an early return.
Read the full bite: Describe two patterns for conditional rendering in JSX
Question 9 of 30
Two adjacent block-level siblings in normal flow have margin-bottom: 30px and margin-top: 20px. What is the resulting vertical space between them?
Show the answer
Answer: d · 30px, because the larger of the adjacent margins is used
Margin collapsing means adjacent vertical margins in normal flow combine into a single margin equal to the largest value, so 30px is rendered. The 50px option reflects the common misconception that margins always add together.
Read the full bite: What is margin collapsing? Give a sibling scenario and prevention.
Question 10 of 30
Why would wrapping two table cells in a Fragment be preferable to wrapping them in a div?
Show the answer
Answer: a · Fragments avoid creating an invalid HTML structure since they do not add an extra DOM node.
A div placed directly inside a table row creates invalid HTML, while a Fragment groups children without introducing any DOM node. Claiming a performance benefit is a common misconception; the primary reason to use Fragments is structural and semantic correctness, not optimization.
Read the full bite: What is a React Fragment and why use it over a div?
Question 11 of 30
When reactive state changes in a Svelte component, how does the compiled application update the browser DOM?
Show the answer
Answer: d · It executes pre-generated imperative statements that directly mutate the affected DOM nodes.
Svelte compiles components into imperative vanilla JavaScript that retains direct references to DOM nodes and executes precise update statements when state changes, so no intermediate tree is ever created. The distractor suggesting a hidden virtual DOM is wrong because the compiler deliberately avoids emitting any diffing or reconciliation runtime, generating direct DOM manipulation code instead.
Read the full bite: How does Svelte update the DOM without a Virtual DOM?
Question 12 of 30
Which statement correctly distinguishes a pseudo-element from a pseudo-class?
Show the answer
Answer: d · A pseudo-element styles a part or generated sub-part not present in the DOM
Pseudo-elements such as ::before style virtual parts not in the DOM, while pseudo-classes select existing elements by state. Only pseudo-elements use double colons in modern syntax, so the last option is wrong.
Read the full bite: Pseudo-class versus pseudo-element in CSS
Question 13 of 30
When publishing a TypeScript library, why might you export an interface instead of a type alias for a config object?
Show the answer
Answer: a · Interfaces allow consumers to safely augment the shape via declaration merging.
Interfaces support declaration merging, allowing consumers to safely augment public library types, whereas type aliases are closed. Option D is wrong because type aliases can absolutely describe objects with methods and properties; they are not limited to primitives or unions.
Read the full bite: Key differences: type alias vs interface for object shapes
Question 14 of 30
A team passes a user object through Layout, Header, Navigation, and finally to UserMenu. What is the strongest argument for replacing this with Context or composition?
Show the answer
Answer: a · Layout, Header, and Navigation are coupled to a prop they ignore, making refactors and reuse harder.
Prop drilling is primarily a maintenance and coupling problem: intermediaries must accept and forward props they do not use, so renaming the prop or reusing those components elsewhere becomes painful. Option B is tempting but wrong because the card explicitly warns against confusing drilling with runtime performance issues like excessive re-renders.
Read the full bite: Explain prop drilling and why it's a problem
Question 15 of 30
In a specificity conflict between `#header` and a selector with eleven classes, which statement is true?
Show the answer
Answer: a · The `#header` selector wins because the ID column outweighs any number of classes
The card explains that specificity is a tuple where the leftmost nonzero column wins, so one ID always beats any number of classes. Option D is tempting because it reflects the common error of collapsing the tuple into a single integer.
Read the full bite: How is CSS specificity calculated for a complex selector?
Question 16 of 30
When initializing UI handlers on a page with external images, which distinction between DOMContentLoaded and window.load matters most?
Show the answer
Answer: d · DOMContentLoaded fires after deferred scripts run but does not wait for images, letting handlers bind earlier
DOMContentLoaded fires after HTML parsing and deferred scripts complete, so you can bind UI handlers before heavy assets like images finish, whereas window.load waits for all subresources. The most tempting distractor reverses the two events: window.load is the one that waits for every asset, not DOMContentLoaded.
Read the full bite: Describe the difference between DOMContentLoaded and window.load
Question 17 of 30
To avoid CORS errors when calling a local backend from an Angular app in development, what should you do?
Show the answer
Answer: a · Create a proxy file, register it under serve proxyConfig in angular.json, and restart ng serve
The Angular CLI dev server proxies requests to the backend only when you register a proxy configuration file in angular.json under the serve target and restart ng serve. Changing environment.ts to hit the backend directly does not resolve CORS because the browser still sees a cross-origin request.
Read the full bite: How do you configure Angular CLI dev server proxying?
Question 18 of 30
Which CSS approach makes a background image completely fill its container while preserving its original aspect ratio?
Show the answer
Answer: d · background-size: cover; background-repeat: no-repeat;
background-size: cover scales the image until it fills the entire container and preserves its aspect ratio by cropping excess, whereas 100% 100% forces the image to match the container's exact dimensions and stretches it out of proportion.
Read the full bite: Which CSS background properties make a hero image cover its container?
Question 19 of 30
You need to increment a React state variable three times within a single event handler. Which approach produces the correct final value?
Show the answer
Answer: c · Call setCount(prev => prev + 1) three times sequentially
Option C uses the functional updater so React queues each increment against the latest pending state. Option B fails because all three calls read the same closed-over value from the render snapshot, so each computes 0 + 1.
Read the full bite: What will count be after three setCount calls in a row?
Question 20 of 30
Which TypeScript approach correctly handles clicks on a ul containing li elements with nested child elements?
Show the answer
Answer: b · Add one click listener to the ul, use (event.target as HTMLElement).closest('li') to find the list item, and guard against null.
Option B correctly leverages event delegation and safely walks up from nested elements via closest('li'), guarding against clicks on the ul padding. Option D is tempting but fails when event.target is a nested span rather than the li itself.
Read the full bite: Describe event delegation and implement a single ul click handler in TypeScript
Question 21 of 30
Why does Vite pre-bundle an ESM package like lodash-es during development?
Show the answer
Answer: b · To collapse hundreds of internal ESM files into a single module and avoid an HTTP request waterfall.
Pre-bundling lodash-es merges its hundreds of tiny ESM files into one module, preventing a 600+ request waterfall that would congest the browser. The other choices describe separate concerns: A and B address CommonJS conversion, while D confuses pre-bundling with tree-shaking.
Read the full bite: Explain Vite dependency pre-bundling, startup speed, and CommonJS handling
Question 22 of 30
You add a click listener to a parent with addEventListener('click', fn, true). When does fn run relative to a child element's default listener if the child is clicked?
Show the answer
Answer: c · fn runs before the child listener during event capture
Passing true as the third argument registers the parent listener for the capture phase, which fires as the event travels downward from the root, so it executes before the child's bubble-phase listener. Option B describes the default behavior when the third argument is omitted or false, not capture.
Read the full bite: Explain DOM event capturing and bubbling with addEventListener
Question 23 of 30
Which method correctly adds a top-to-bottom black gradient overlay—fully opaque at the top to half-transparent at the bottom—directly over a background image without extra DOM elements?
Show the answer
Answer: b · background-image: linear-gradient(rgb(0 0 0), rgb(0 0 0 / 0.5)), url(img.jpg);
In a comma-separated background-image list, the first layer renders closest to the viewer, so the gradient must be declared before the url to remain visible. Option D reverses that stacking order and hides the gradient behind the photo, while C adds unnecessary markup and D dims the entire image uniformly instead of creating a controlled fade.
Read the full bite: Create a vertical black gradient overlay on a background image
Question 24 of 30
Which behavior is a default Angular CLI production build optimization configured in angular.json?
Show the answer
Answer: c · It strips unused library code and minifies scripts and styles
The production target in angular.json sets optimization to true, which enables dead code elimination and minification. AOT compilation is used in both development and production in modern Angular, so it is not a production-only optimization.
Read the full bite: Describe two key Angular CLI production build optimizations
Question 25 of 30
Which approach correctly fetches data inside useEffect while preventing memory leaks when the component unmounts?
Show the answer
Answer: a · Create an async function inside the effect, invoke it, and return a cleanup function that aborts the request.
Creating an async function inside the effect allows the outer callback to remain synchronous and return an abort cleanup function. Declaring the useEffect callback itself as async is a common mistake because it returns a Promise, breaking React's cleanup contract.
Read the full bite: How do you fetch data with useEffect and prevent memory leaks?
Question 26 of 30
A useEffect subscribes to an external store. When a dependency changes and the effect must re-run, when does the cleanup function execute?
Show the answer
Answer: d · Immediately before the effect re-runs with the new dependency values
React runs the cleanup function immediately before re-executing an effect when dependencies change, tearing down the previous render's side effects to prevent memory leaks and stale subscriptions. The most tempting distractor assumes cleanup is only for unmount, but that ignores the re-run scenario and fails under React 18 Strict Mode, which intentionally double-invokes effects to expose missing teardown logic.
Read the full bite: What is the purpose of the useEffect cleanup function?
Question 27 of 30
What is a key architectural difference between adapter-static and adapter-node?
Show the answer
Answer: a · adapter-static pre-renders pages into HTML files at build time, whereas adapter-node produces a Node server for dynamic requests
adapter-static outputs static HTML for CDN deployment while adapter-node creates a running Node server capable of SSR and API routes. A is tempting but wrong because Vite handles bundling; an adapter only repackages the already-bundled output for a specific platform.
Read the full bite: What is a SvelteKit adapter and how do adapter-static and adapter-node differ?
Question 28 of 30
After storing parent.childNodes in a variable, a developer appends a new child and sees the stored length increase without reassignment. What explains this?
Show the answer
Answer: d · The stored reference is a live NodeList, but querySelectorAll returns a static snapshot that would not update.
childNodes is a live NodeList that mutates in place, while querySelectorAll returns a static snapshot that never updates. A is tempting because many developers assume all NodeLists share the same binding behavior, but querySelectorAll specifically captures a point-in-time copy.
Read the full bite: What are the key differences between NodeList and HTMLCollection?
Question 29 of 30
When choosing font-display: swap over block for body text, what key user experience trade-off should you expect?
Show the answer
Answer: c · Swap shows fallback text almost immediately but risks layout shift when the custom font arrives, while block hides text briefly to avoid initial metric changes.
Swap displays fallback text within an extremely short block period but risks cumulative layout shift when the custom font metrics replace the fallback, whereas block hides text for a short block period to preserve initial visual stability. Distractor B is tempting but wrong because swap increases, not prevents, layout shift risk.
Read the full bite: What is font-display and how do swap and block differ?
Question 30 of 30
What is the key difference between useState(expensive()) and useState(() => expensive()) during re-renders?
Show the answer
Answer: a · The direct call executes on every render but React discards its result after mount, while the function runs only once during initialization.
JavaScript evaluates the direct argument before React can intercept it, so expensive() wastes cycles on every render even though React throws away the result after mount; the initializer function runs only once. Option D is tempting but wrong because lazy initialization does not prevent re-renders, it only avoids repeating expensive setup work inside them.
Read the full bite: Why pass a function to useState for expensive initial values?
Could you explain these out loud?
That is what an interview actually tests. Tezvyn gives you questions like these with what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.