Svelte Interview Questions
Common Svelte interview questions covering the compiler approach, reactivity, stores, SvelteKit, and testing.
A curated set of Svelte interview questions, ordered roughly from fundamentals to more advanced — the kind you'll actually be asked in real screens and on-sites.
Core concepts
Q: What fundamentally distinguishes Svelte from React and Vue? Svelte is a compiler, not a runtime library. React and Vue both ship a framework runtime to the browser that does its reconciliation work at runtime — a virtual DOM diff (React) or a reactivity graph (Vue). Svelte instead analyzes your components at build time and generates plain, targeted JavaScript that updates exactly the DOM nodes affected by a given change, with no virtual DOM, no diffing step, and no framework runtime shipped alongside your code. This typically produces smaller bundles and less per-update work done in the browser, at the cost of some things (like dynamically defining new components at runtime) being harder than in a runtime-based framework.
Q: How does Svelte's reactivity model differ from React's or Vue's?
A top-level let variable in a Svelte component is reactive automatically — no useState call, no ref() wrapper. The compiler statically detects assignments to that variable and generates the DOM-update code for wherever it's used. The catch is that only actual assignments are detected — mutating an array with .push() or a property on an object without reassigning the variable itself is invisible to Svelte's reactivity, unlike Vue's reactive(), which uses a runtime Proxy that can observe mutation directly.
Q: What does $: do, and how does Svelte know what it depends on?
$: marks a reactive statement — it re-runs automatically whenever any variable it references changes, similar in effect to Vue's computed()/watch() or a React useEffect with a correctly maintained dependency array. Unlike React, there's no explicit dependency array to write by hand: the Svelte compiler determines dependencies by statically analyzing which variables the labeled statement reads, and regenerates the appropriate re-run logic at build time.
Stores and state
Q: When would you reach for a Svelte store instead of component-local state?
Component-local state (a plain let inside one .svelte file) is right for anything that belongs to a single component or flows cleanly down through props to its children. A store is appropriate when state needs to be shared between components that aren't in a direct parent-child relationship — a logged-in user, a theme setting, a shopping cart — without threading props down through several intermediate layers that don't otherwise need that data.
Q: What does the $ prefix do when reading a store inside a .svelte file?
It's Svelte's auto-subscription syntax. Writing $count for a store named count tells the compiler to automatically subscribe to that store when the component mounts, unwrap it to its current value for use directly in script or markup, and unsubscribe automatically when the component is destroyed — all without writing a manual .subscribe()/unsubscribe() pair yourself. This $ shorthand only works inside .svelte files; a plain .js module must subscribe manually.
Trade-offs
Q: What are the practical trade-offs of choosing Svelte over React or Vue for a project?
Svelte tends to produce smaller bundles and less runtime overhead since most of its work happens at compile time, and its syntax (plain let variables, minimal boilerplate) is often considered easier to read for smaller-to-medium apps. The trade-off is a significantly smaller ecosystem — fewer third-party component libraries, fewer job listings, and fewer battle-tested large-scale patterns compared to React's ecosystem in particular. For a large team or a codebase that will rely heavily on a broad third-party library ecosystem, that ecosystem gap is often the deciding factor over the technical differences in reactivity model.
SvelteKit and testing
Q: What does SvelteKit add on top of plain Svelte, and why would you reach for it?
Plain Svelte is a component compiler with no built-in routing, no server-side rendering, and no data-loading convention. SvelteKit is the official application framework built on top of it — file-based routing generated from src/routes/, load functions that fetch data before a page renders (aware of SSR, unlike a plain fetch inside onMount), and a full build/deployment pipeline. Most real, full-page Svelte applications reach for SvelteKit the same way most real React apps reach for Next.js — plain Svelte alone is a better fit for an embedded widget or a component library than a full routed application.
Q: What problem do SvelteKit load functions solve that a plain fetch call inside a component's onMount doesn't?
A fetch call inside onMount only ever runs in the browser, after the component has already mounted — so the page's initial server-rendered HTML ships without that data, losing both SEO benefit and a fast meaningful first paint, and there's no way to avoid an extra loading state. A load function runs before the page component renders at all, on the server for the initial request (so the fetched data is present directly in the server-rendered HTML) and in the browser for subsequent client-side navigations, with its result handed to the page as a data prop — no manual loading-state juggling required for data that's already available before the component mounts.
Q: Why does @testing-library/svelte encourage querying by role or text instead of a CSS selector, and how do you test a dispatched custom event?
Querying by role or visible text mirrors how a real user or assistive technology perceives the page, so the test keeps passing through an internal refactor (like moving state into a store) as long as the component's observable behavior doesn't change — a CSS selector instead couples the test to markup structure that can change for unrelated reasons. To test a dispatched event, render() returns a component instance; calling component.$on("eventName", handlerFn) subscribes a mock function the same way a parent's on:eventName binding would, and the event's payload arrives at handlerFn's argument's .detail property, matching how dispatched events are consumed in real (non-test) Svelte code.