🔥

Top 43 Svelte / SvelteKit Interview Questions & Answers (2026)

43 Questions 20 Beginner 13 Intermediate 10 Advanced

About Svelte / SvelteKit

Top 50 Svelte and SvelteKit interview questions covering reactivity, components, stores, routing, SSR, deployment, and Svelte 5 runes. Companies hiring for Svelte / SvelteKit roles test this knowledge at every stage — from first-round screens that check the basics to final-round conversations about real-world trade-offs.

What to Expect in a Svelte / SvelteKit Interview

Expect a mix of conceptual and practical Svelte / SvelteKit questions: clear definitions and core-concept checks for junior roles, hands-on scenario questions for mid-level roles, and architecture or trade-off discussions for senior roles. Interviewers usually move from foundational topics toward the kind of problems you'd actually face on the job.

How to Use This Guide

Work through the Svelte / SvelteKit questions in order — Beginner, then Intermediate, then Advanced — so each concept builds on the last. Every question has its own page; bookmark the ones that trip you up and revisit them the day before your interview.

Curated by Tech Baithak Editorial Team  ·  Last updated: June 2026

Beginner 20 questions

Core concepts every Svelte / SvelteKit developer must know.

01

What is Svelte?

Svelte is a modern JavaScript framework for building user interfaces, created by Rich Harris. Unlike React or Vue which run in the browser, Svelte is a compiler — it transforms your component code into efficient, framework-free JavaScript at build time. This means no virtual DOM, no runtime overhead, and smaller bundle sizes. Svelte components are written in .svelte files containing HTML, a <script> block, and a <style> block. State and reactivity are handled directly through variable assignments rather than hooks or reactive data wrappers. The result is highly performant applications with less code. Svelte was introduced in 2016 and gained significant adoption with version 3 (2019) which introduced its declarative reactivity model.

Open this question on its own page
02

How does Svelte differ from React and Vue?

The fundamental difference is the compilation approach. React and Vue ship a framework runtime to the browser — the virtual DOM, reconciliation algorithm, and reactive system run in the user's browser on every interaction. Svelte compiles components to plain JavaScript at build time — the browser executes only the minimal update logic needed, with no runtime overhead. Practical differences: Svelte has no virtual DOM (direct DOM updates), smaller bundle sizes (no framework runtime), less boilerplate (reactivity via assignment, not useState/ref), and scoped styles by default. Tradeoffs: smaller ecosystem than React, fewer job postings, and the compilation model can make debugging more complex. Svelte is excellent for performance-critical or bundle-size-sensitive applications.

Open this question on its own page
03

What is a Svelte component?

A Svelte component is a .svelte file containing three optional sections: <script>: JavaScript logic, imports, props, state, and reactive declarations. Template (HTML): the markup that defines the component's DOM structure, using Svelte's template syntax for conditional rendering, loops, and event binding. <style>: CSS that is scoped by default — styles only apply to elements within this component. Example: <script> let count = 0; </script> <button on:click={() => count++}>{count}</button> <style> button { color: blue; } </style>. Each component is a self-contained unit. Svelte compiles this single file into an optimized JavaScript module. Parent components pass data to children via props; children communicate up via dispatched events or bound variables.

Open this question on its own page
04

How does reactivity work in Svelte?

Svelte's reactivity is based on variable assignment — assigning a new value to a variable automatically triggers DOM updates. let count = 0; function increment() { count++; } — Svelte's compiler tracks that count is used in the template and generates code to update the DOM when count changes. This is different from React (where you call setState) or Vue (where you use reactive objects). Reactive declarations ($:) create computed values and side effects: $: doubled = count * 2;doubled is automatically recalculated whenever count changes. $: console.log(count); runs the statement whenever its dependencies change. Array mutations require reassignment to trigger updates: items = [...items, newItem] — push alone won't work.

Open this question on its own page
05

What are Svelte props?

In Svelte, props are variables exported from the component's <script> block. The export let syntax declares a prop: <script> export let name; export let count = 0; </script>. The default value (count = 0) is used when the parent doesn't provide a value. Parent usage: <Child name="Alice" count={5} />. Props are reactive — when the parent updates the value, the child re-renders. Spread props: <Child {...user} /> passes all properties of an object as props. Svelte's prop system is simpler than React's: there is no destructuring pattern, no defaultProps, and no prop-types — just exported variables with optional defaults. For one-way data flow, use props; for two-way binding, use the bind: directive.

Open this question on its own page
06

What are Svelte lifecycle functions?

Svelte provides lifecycle functions for component initialization, updates, and cleanup. Import from svelte: onMount: runs after the component is first rendered to the DOM. The primary place for setup code requiring DOM access, API calls, and subscriptions. Return a cleanup function to run on destroy. onDestroy: runs when the component is removed from the DOM. Clean up subscriptions, timers, and event listeners. beforeUpdate: runs before the DOM updates. Access the current (pre-update) DOM state. afterUpdate: runs after the DOM updates — access the updated DOM. Example: import { onMount, onDestroy } from 'svelte'; onMount(() => { const timer = setInterval(() => count++, 1000); return () => clearInterval(timer); }). Lifecycle functions must be called during component initialization (synchronously in the script), not conditionally or asynchronously.

Open this question on its own page
07

What are Svelte stores?

Svelte stores are reactive state containers for sharing state between components. The svelte/store module provides: writable: mutable store: import { writable } from 'svelte/store'; export const count = writable(0);. Update: count.set(5) or count.update(n => n + 1). Subscribe: count.subscribe(value => console.log(value)). readable: immutable from outside — only the store creator can update it. Good for timers, WebSocket connections. derived: computed from one or more stores: const doubled = derived(count, $count => $count * 2). In Svelte components, prefix a store with $ to auto-subscribe and auto-unsubscribe: <p>{$count}</p> — equivalent to subscribing in onMount and unsubscribing in onDestroy.

Open this question on its own page
08

What is the $: syntax in Svelte?

The $: prefix (reactive statement) is Svelte's syntax for reactive declarations and statements. It runs whenever its dependencies change. Reactive declaration: $: doubled = count * 2; — creates a variable doubled that is always count * 2, automatically updated when count changes. Reactive statement: $: console.log('count changed:', count); — runs the statement when count changes, similar to a useEffect watching count in React. Reactive block: $: { console.log(a); console.log(b); } — runs whenever a or b changes. Svelte's compiler analyzes dependencies automatically — you don't declare them explicitly. The $: syntax is valid JavaScript (a labeled statement) that Svelte intercepts and transforms during compilation.

Open this question on its own page
09

What is SvelteKit?

SvelteKit is the official application framework for Svelte — the equivalent of Next.js for React or Nuxt for Vue. It provides everything needed for production web apps: File-based routing (create +page.svelte files in the src/routes/ directory). Server-side rendering (SSR), static site generation (SSG), and client-side rendering — all configurable per-page. Server endpoints (+server.js) for API routes. Load functions for data fetching before rendering. Form actions for progressive enhancement. Layouts for shared UI across pages. Adapters for deploying to different platforms (Node.js, Cloudflare, Vercel, Netlify, static). SvelteKit is built on Vite for fast development and optimized production builds. It is the recommended way to build full-featured Svelte applications.

Open this question on its own page
10

How does file-based routing work in SvelteKit?

SvelteKit uses a file-system based router in the src/routes/ directory. Each route is a directory containing special files. +page.svelte: the page component (rendered as HTML). +page.js/+page.server.js: data loading functions. +layout.svelte: shared layout for all pages in this directory and subdirectories. +server.js: API endpoint (GET/POST/etc. handlers). Route examples: src/routes/+page.svelte/. src/routes/about/+page.svelte/about. src/routes/blog/[slug]/+page.svelte/blog/:slug. src/routes/(app)/dashboard/+page.svelte/dashboard (parentheses create route groups that don't affect the URL). Optional segments: [[optional]]. Rest parameters: [...path]. This convention eliminates boilerplate router configuration.

Open this question on its own page
11

What is a SvelteKit load function?

A load function in SvelteKit fetches data needed for a page before it renders. Export a load function from +page.js (runs on client and server) or +page.server.js (runs only on server). The data returned is available in the page as the data prop. +page.server.js: export async function load({ params, fetch }) { const post = await fetch(\`/api/posts/\${params.slug}\`); return { post: await post.json() }; }. +page.svelte: <script> export let data; </script> <h1>{data.post.title}</h1>. Server load functions run on the server (can access databases, read files, use private environment variables) and their data is serialized and sent to the client. They also run during navigation — SvelteKit calls them before transitioning to preserve the SPA feel while loading fresh data.

Open this question on its own page
12

What are Svelte event directives?

Svelte uses the on: directive to listen to DOM events. Basic: <button on:click={handleClick}>. Inline: <button on:click={() => count++}>. Modifiers change behavior: on:click|preventDefault={handler} calls event.preventDefault(). on:click|stopPropagation={handler} stops bubbling. on:click|once={handler} fires only once. on:click|self={handler} fires only if the element itself was clicked (not a child). Multiple modifiers: on:click|preventDefault|stopPropagation. Component events: child components dispatch events: import { createEventDispatcher } from 'svelte'; const dispatch = createEventDispatcher(); dispatch('message', { text: 'hello' });. Parent listens: <Child on:message={handleMessage} />. Event forwarding: <button on:click> (no handler) forwards the event to the parent.

Open this question on its own page
13

What are Svelte conditional and loop template blocks?

Svelte provides template blocks for logic in markup. {#if}: {#if user.isAdmin} <AdminPanel /> {:else if user.isEditor} <EditorPanel /> {:else} <UserPanel /> {/if}. {#each}: {#each items as item, index (item.id)} <div>{index}: {item.name}</div> {:else} <p>No items</p> {/each}. The (item.id) is a key for efficient DOM reconciliation — similar to React's key prop. {#await}: handle promises: {#await promise} <Loading /> {:then data} <p>{data}</p> {:catch error} <p>Error: {error.message}</p> {/await}. {#key}: destroy and recreate a block when an expression changes. These blocks compile to efficient DOM manipulation code with no runtime overhead.

Open this question on its own page
14

What are Svelte bindings?

Svelte bindings create two-way data flow between DOM elements/components and variables. bind:value: <input bind:value={name}>name updates when the user types; the input value updates when name changes programmatically. Works for <textarea>, <select>, checkboxes (bind:checked), radio buttons, and number inputs. bind:this: <canvas bind:this={canvasEl}> — assigns the DOM element to a variable for direct access. Component bindings: bind to a child's exported variable: <NumberInput bind:value={count} />. Media bindings: bind:currentTime, bind:paused, bind:duration on <video>/<audio>. Bindings make form handling simple — no need for change event handlers just to sync state with inputs.

Open this question on its own page
15

What are Svelte transitions and animations?

Svelte has built-in support for transitions and animations. Transitions apply when elements enter or leave the DOM. Import from svelte/transition: <div transition:fade>, <p in:fly="{{ y: 200 }}" out:fade>. Built-in transitions: fade, fly, slide, scale, draw (SVG paths), blur. Custom transitions are functions that return a css function: function custom(node, params) { return { duration: 300, css: t => \`transform: scale(\${t})\` } }. Animations: the animate: directive animates elements when they reorder within an {#each} block: <div animate:flip>. Actions (use:): reusable DOM behaviors: <div use:tooltip={params}>. Transitions are compiled to efficient CSS animations, offloaded to the GPU. They are one of Svelte's most delightful features for creating smooth UIs with minimal code.

Open this question on its own page
16

What is the difference between +page.js and +page.server.js in SvelteKit?

Both are SvelteKit load function files but run in different environments. +page.js (universal load): runs on the server during SSR and in the browser during client navigation. Has access to the fetch function (a special SvelteKit fetch that can make relative requests). Cannot access server-only things like filesystem or private environment variables. Used when loading public API data. +page.server.js (server load): runs only on the server. Has access to locals (set by hooks), server-side database access, private environment variables, and cookies. Data is serialized and sent to the client. Also exports form actions for handling HTML form submissions. Can set cookies on the response. Rule of thumb: use +page.server.js for anything requiring authentication, database access, or secrets. Use +page.js for public API data that the client can also fetch during navigation.

Open this question on its own page
17

What are SvelteKit hooks?

SvelteKit hooks are functions defined in src/hooks.server.js (or hooks.client.js) that intercept requests and responses. handle: runs on every request. export async function handle({ event, resolve }) { event.locals.user = await getUser(event.cookies); return resolve(event); }. Use it for authentication, logging, A/B testing, and adding data to event.locals (passed to load functions and actions). handleFetch: intercepts fetch calls in load functions — modify the request, add auth headers, or redirect to different endpoints. handleError: called when an unexpected error occurs — log to your error tracking service, return a safe error message. hooks.client.js: handleError for client-side errors. Hooks run before routing, making them ideal for request-level cross-cutting concerns like authentication and request logging.

Open this question on its own page
18

What are SvelteKit form actions?

Form actions in SvelteKit are server-side functions that handle HTML form submissions. Defined in +page.server.js: export const actions = { default: async ({ request, cookies }) => { const data = await request.formData(); const email = data.get('email'); await createUser(email); redirect(303, '/dashboard'); }, login: async ({ request }) => { ... }, logout: async ({ cookies }) => { cookies.delete('session'); } };. In the page, use HTML forms: <form method="POST"><input name="email"><button>Submit</button></form>. For named actions: <form method="POST" action="?/login">. Use the enhance action for progressive enhancement — works without JavaScript (pure HTML form) and enhances with client-side JavaScript when available. Return validation errors: return fail(400, { errors: { email: 'Invalid' } }). Form actions are SvelteKit's server-first approach to mutations.

Open this question on its own page
19

What is Svelte 5 and what are runes?

Svelte 5 (released 2024) introduces a new reactivity model called runes — special functions prefixed with $ that the compiler recognizes. Runes replace the implicit reactivity of let, $:, and stores with explicit, portable signals. $state(): declares reactive state: let count = $state(0); — replaces let count = 0 with compiler tracking. $derived(): computed value: let doubled = $derived(count * 2); — replaces $: doubled = count * 2. $effect(): side effects: $effect(() => { console.log(count); }); — replaces $: { console.log(count); }. $props(): declare props: let { name, count = 0 } = $props(); — replaces export let. Runes work in .svelte files and regular .svelte.js/.svelte.ts files, enabling reactive logic outside components. Svelte 4 syntax is still supported.

Open this question on its own page
20

How do you handle forms in SvelteKit with use:enhance?

use:enhance is a SvelteKit action that progressively enhances HTML form submissions with client-side JavaScript. Without it, form submissions cause a full page reload (pure HTML behavior). With it, submissions are intercepted, sent via fetch, and the page is updated in place. Basic usage: import { enhance } from '$app/forms'; <form method="POST" use:enhance>. This handles the default action, updates the form store with action return values, and re-runs load functions on success. Custom callback: use:enhance={({ formData, cancel }) => { loading = true; return async ({ result, update }) => { loading = false; await update(); } }}. The outer function runs before submission (can cancel()); the returned function runs after the response. This pattern maintains the progressive enhancement principle — forms work without JavaScript (server handles submission) and are enhanced when JavaScript is available.

Open this question on its own page
Intermediate 13 questions

Practical knowledge for developers with hands-on experience.

01

What are Svelte custom stores and the store contract?

Any object that implements the store contract is compatible with Svelte's $ auto-subscription syntax. The contract requires a subscribe method that: accepts a subscriber function, calls it immediately with the current value, calls it again whenever the value changes, and returns an unsubscribe function. Custom store example: function createCounter() { const { subscribe, set, update } = writable(0); return { subscribe, increment: () => update(n => n + 1), reset: () => set(0) }; }. The returned object has subscribe (required) plus custom methods. Usage: const counter = createCounter(); $counter; counter.increment();. Custom stores encapsulate state and its update logic, providing a clean API to consumers. They are Svelte's equivalent of custom hooks in React — reusable stateful logic that any component can use.

Open this question on its own page
02

How does SSR (Server-Side Rendering) work in SvelteKit?

SvelteKit renders pages on the server by default for the initial page load. The process: 1. Load function: SvelteKit calls the page's load function (in +page.server.js or +page.js) on the server to fetch data. 2. Render: SvelteKit renders the Svelte component tree to an HTML string using the loaded data. 3. Hydration: the HTML is sent to the browser with embedded JavaScript. The browser renders the HTML immediately (fast FCP) then "hydrates" — attaches JavaScript to make the page interactive. Subsequent navigations: SvelteKit intercepts link clicks and fetches only the JSON data from load functions, then renders the new page client-side (SPA navigation). Configure rendering per page: export const ssr = false; disables SSR for that page (CSR only). export const prerender = true; generates static HTML at build time. export const csr = false; disables JavaScript entirely (pure HTML).

Open this question on its own page
03

What are SvelteKit adapters?

SvelteKit adapters transform the built SvelteKit app for deployment to a specific platform. They bridge SvelteKit's output and the target runtime. Configure in svelte.config.js: import adapter from '@sveltejs/adapter-node'; export default { kit: { adapter: adapter() } }. Available adapters: adapter-node: Node.js HTTP server (Heroku, VPS, Docker). adapter-vercel: Vercel serverless functions with edge support. adapter-netlify: Netlify functions. adapter-cloudflare: Cloudflare Workers and Pages. adapter-static: pre-renders entire site as static HTML/JS (no server needed, deploy to GitHub Pages, S3). adapter-auto: automatically detects the deployment platform. Each adapter generates the right output format — Node.js server file, serverless function ZIP, or static files. Adapters make SvelteKit platform-agnostic while optimizing for each target.

Open this question on its own page
04

What is the difference between prerendering, SSR, and CSR in SvelteKit?

SvelteKit supports three rendering modes configurable per-page: SSR (Server-Side Rendering): default. The server renders HTML for each request using the current data. Good for dynamic content (user-specific pages, frequently changing data). Prerendering (SSG): pages are rendered to HTML files at build time. Deploy as static files. Good for content that changes rarely (blog posts, docs). Enable: export const prerender = true. SvelteKit discovers all pages at build time and generates HTML for each. Dynamic routes can be prerendered with entries. CSR (Client-Side Rendering): the server sends a shell HTML with JavaScript; the browser renders everything. No server needed after initial HTML. Enable: export const ssr = false. Good for auth-gated dashboards where SEO isn't needed. You can mix: most pages SSR, blog posts prerendered, user dashboard CSR. The default "SSR with client-side navigation" provides the best balance of SEO and UX.

Open this question on its own page
05

How do you manage environment variables in SvelteKit?

SvelteKit has a built-in environment variable system with strict client/server separation. $env/static/private: server-only environment variables available at build time. Import: import { DATABASE_URL } from '$env/static/private';. These are replaced with their values at build time and never sent to the browser. $env/static/public: public variables (must be prefixed PUBLIC_ in .env) available everywhere. $env/dynamic/private: server-only variables evaluated at runtime (not build time). Required for serverless deployments where env vars might change per environment. $env/dynamic/public: runtime public variables. SvelteKit prevents private variables from being imported in client code — it throws a build error. Define variables in .env, .env.local, or deployment platform. VITE_ prefix: variables prefixed with VITE_ are exposed to client-side Vite code but use PUBLIC_ prefix for SvelteKit's module system.

Open this question on its own page
06

What are Svelte actions (use:)?

Svelte actions are reusable behaviors applied to DOM elements with the use: directive. An action is a function that receives the DOM node and optional parameters. Example tooltip action: function tooltip(node, params) { const tip = createTooltip(params.text); node.addEventListener('mouseenter', showTip); node.addEventListener('mouseleave', hideTip); return { update(newParams) { tip.setText(newParams.text); }, destroy() { tip.remove(); node.removeEventListener('mouseenter', showTip); node.removeEventListener('mouseleave', hideTip); } }; }. Usage: <button use:tooltip={{ text: 'Click me' }}>. Actions replace React's imperative DOM manipulation patterns — instead of useRef + useEffect, define an action once and attach it declaratively. Common actions from the svelte-use library: click-outside detection, intersection observer, drag-and-drop, clipboard, media queries.

Open this question on its own page
07

What is SvelteKit's approach to authentication?

SvelteKit authentication typically uses cookies and server hooks. Pattern: 1. Login action: verify credentials in a form action, set a session cookie: cookies.set('session', token, { path: '/', httpOnly: true, secure: true, sameSite: 'strict', maxAge: 3600 }). 2. Server hook: validate the session cookie on every request and set the user in event.locals: export async function handle({ event, resolve }) { const session = event.cookies.get('session'); event.locals.user = session ? await validateSession(session) : null; return resolve(event); }. 3. Load function: access locals.user in server load functions, redirect unauthenticated users. 4. Page layout: pass user to all pages via layout load function. Popular libraries: Auth.js (formerly NextAuth) has a SvelteKit adapter, Lucia is a lightweight auth library built for SvelteKit. JWT-based stateless auth is also common — store the JWT in an HttpOnly cookie.

Open this question on its own page
08

What are Svelte slots and named slots?

Slots allow parent components to inject content into child component templates. Basic slot: <!-- Card.svelte --> <div class="card"><slot /></div>. Parent: <Card><p>Hello</p></Card>. Named slots: multiple injection points: <!-- Modal.svelte --> <div><slot name="header" /><slot /><slot name="footer" /></div>. Parent: <Modal><h2 slot="header">Title</h2><p>Body</p><button slot="footer">Close</button></Modal>. Default slot content: fallback when no content is provided: <slot>Default content</slot>. Slot props: expose data from child to injected content: <slot item={currentItem} />. Parent: <Component let:item><p>{item.name}</p></Component>. In Svelte 5, slots are replaced by snippets ({#snippet} and {@render}) which are more flexible.

Open this question on its own page
09

How does SvelteKit handle API routes?

SvelteKit API routes are created by adding +server.js files in the routes directory. Export named functions corresponding to HTTP methods: export async function GET({ params, url }) { const data = await db.query(params.id); return new Response(JSON.stringify(data), { headers: { 'Content-Type': 'application/json' } }); }. Alternatively, use the built-in json() helper: import { json } from '@sveltejs/kit'; return json(data);. Handle POST: export async function POST({ request }) { const body = await request.json(); ... }. Error responses: import { error } from '@sveltejs/kit'; throw error(404, 'Not found');. API routes support GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS. They share the hooks infrastructure (authentication via event.locals). Unlike form actions (for form submissions), API routes are for programmatic API access from client-side JavaScript or external clients.

Open this question on its own page
10

What is Svelte's context API?

Svelte's context API provides a way to pass data deep into the component tree without prop drilling, but unlike stores, context is scoped to a component subtree (not global). setContext: sets a value in the current component's context, available to all descendants: import { setContext } from 'svelte'; setContext('user', currentUser);. getContext: retrieves a value from the nearest ancestor that set it: import { getContext } from 'svelte'; const user = getContext('user');. Context is not reactive by default — if you need reactive context, store a writable store in context. Use cases: theme providers, user context for deeply nested components, component library configuration. Difference from stores: stores are application-global; context is component-tree-scoped (multiple instances of a component each get their own context). Context values are only accessible during component initialization.

Open this question on its own page
11

What is the difference between client-side navigation and page reloads in SvelteKit?

SvelteKit provides client-side navigation for a smooth SPA-like experience. When a user clicks a <a> link on the same origin, SvelteKit intercepts it, runs the target page's load functions, and renders the new page without a full page reload — preserving the scroll position, open connections, and JavaScript state. Under the hood, SvelteKit fetches only the JSON data (from load functions), not the full HTML. Control navigation with import { goto } from '$app/navigation';: goto('/dashboard'). Disabling client navigation: <a href="/external" data-sveltekit-reload> forces a full page reload. data-sveltekit-noscroll prevents scroll reset. data-sveltekit-preload-data="hover" preloads data when hovering for instant navigation. Full page reloads happen only for external links, links with data-sveltekit-reload, and explicit invalidateAll() calls that cause full rerender.

Open this question on its own page
12

How do you implement error handling in SvelteKit?

SvelteKit has a structured error handling system. Expected errors: throw with the error() helper in load functions or actions: import { error } from '@sveltejs/kit'; throw error(404, 'Post not found');. SvelteKit renders the nearest +error.svelte page. Create error pages at different route levels. Unexpected errors: unhandled exceptions in load functions. The handleError hook in hooks.server.js catches them: export function handleError({ error, event }) { Sentry.captureException(error); return { message: 'Something went wrong' }; }. The returned object becomes the error page's $page.error. +error.svelte: import { page } from '$app/stores'; <h1>{$page.error.message}</h1>. Client-side errors: hooks.client.js handleError for client-side navigation errors. This system ensures users always see a meaningful error page rather than a blank screen or cryptic message.

Open this question on its own page
13

What are Svelte compile options and configuration?

Svelte is configured in svelte.config.js at the project root. Key options: kit.adapter: deployment adapter. kit.alias: path aliases (e.g., $lib maps to src/lib by default). kit.csrf: CSRF protection for form actions (enabled by default). kit.paths.base: base path for deploying to a subdirectory. compilerOptions: Svelte compiler options — runes: true (opt-in to Svelte 5 runes mode), accessors: true (generate getters/setters for all component props). Vite configuration is in vite.config.js. The src/app.html is the HTML template — add global head tags, meta, and the body placeholder %sveltekit.body%. TypeScript is configured with tsconfig.json — SvelteKit generates a tsconfig.json based on your config. src/app.d.ts defines TypeScript types for Locals, PageData, and Platform.

Open this question on its own page
Advanced 10 questions

Deep expertise questions for senior and lead roles.

01

How does Svelte 5's reactivity model with $state differ from Svelte 4?

Svelte 5 uses an explicit fine-grained reactivity system based on signals (similar to Solid.js), unlike Svelte 4's compile-time implicit reactivity. Svelte 4: the compiler tracks which variables are used in templates and wraps assignments with invalidation calls. Works automatically but is limited — reactive logic cannot be extracted into plain .js files. Svelte 5: $state() creates a reactive state object that uses JavaScript Proxy at runtime. Deep reactivity: let user = $state({ name: 'Alice', address: { city: 'NY' } }) — mutating user.address.city = 'LA' is reactive without reassignment. Reactive logic can live in .svelte.js files and be imported anywhere. $derived.by(): for complex derived computations: let sorted = $derived.by(() => [...items].sort()). The key improvement: runes make reactivity portable beyond .svelte files — write reusable reactive classes and functions in regular TypeScript.

Open this question on its own page
02

What is SvelteKit's data loading waterfall problem and how do you solve it?

A data loading waterfall occurs when load functions execute sequentially — each waits for the previous to complete. Layout load functions run before page load functions, creating serial execution. Solutions: Parallel loading with Promise.all: within a single load function, fetch in parallel: const [users, posts] = await Promise.all([fetchUsers(), fetchPosts()]). Return promises without awaiting: SvelteKit allows returning unawaited promises from load functions — SvelteKit awaits them in parallel and uses streaming to send data as it resolves: return { users: fetchUsers(), posts: fetchPosts() }. Use {#await data.users} in the template. Streaming with HTML response: for server load functions, deferred/streamed data allows the browser to start rendering while waiting for slow data. Avoid over-fetching in layouts: only put truly shared data in layout loads; page-specific data belongs in page loads. Cache: use depends/invalidate for fine-grained cache control to avoid refetching unchanged data.

Open this question on its own page
03

How do you implement real-time features in SvelteKit?

Real-time features in SvelteKit via multiple approaches: Server-Sent Events (SSE): server pushes events to clients over a persistent HTTP connection. Create a +server.js endpoint that returns a ReadableStream: return new Response(new ReadableStream({ start(controller) { const send = (data) => controller.enqueue(\`data: \${JSON.stringify(data)}\n\n\`); const interval = setInterval(() => send(getUpdate()), 1000); request.signal.addEventListener('abort', () => clearInterval(interval)); } }), { headers: { 'Content-Type': 'text/event-stream' } }). Client subscribes with new EventSource('/events'). WebSockets: SvelteKit doesn't have built-in WS support, but add them in the Vite plugin or via the adapter's hooks (e.g., adapter-node exposes the HTTP server). PartyKit: a platform purpose-built for SvelteKit real-time — add WebSocket rooms with a single import. Polling: simplest — use invalidate() to refresh load function data periodically.

Open this question on its own page
04

What is the SvelteKit shallow routing feature?

Shallow routing (introduced in SvelteKit 1.15+) allows pushing URL changes to the browser history without triggering a full page navigation (no load functions re-run). It is used for modals, drawers, and dialogs that should be URL-addressable (sharing the URL reopens the modal) without replacing the entire page. Use replaceState or pushState from $app/navigation: import { pushState } from '$app/navigation'; pushState('?photo=1', { showModal: true });. The state object is available in $page.state: {#if $page.state.showModal} <Modal /> {/if}. On popstate (back button), SvelteKit restores the previous state. This enables patterns like: clicking a product card changes the URL to ?product=123, showing a modal with details. Closing the modal goes back. Sharing the URL shows the same modal. This is the native browser way to handle stateful UI without heavyweight routing libraries.

Open this question on its own page
05

How does SvelteKit handle static asset optimization?

SvelteKit uses Vite for asset optimization during builds. JavaScript/CSS: Rollup-based bundling, tree-shaking, code splitting by route, and minification. Images: the @sveltejs/enhanced-img package provides the <enhanced:img> component that automatically generates srcset for responsive images, converts to WebP/AVIF, and adds width/height to prevent layout shift. Static assets: files in static/ are served as-is with cache headers. Files imported in components get content-hashed filenames: import logo from './logo.png'/assets/logo.a1b2c3.png. Fonts: import in CSS; Vite optimizes them. Preloading: SvelteKit generates <link rel="preload"> hints for critical resources. Service Worker: src/service-worker.js enables offline support and custom caching strategies. Adapter-specific optimization: adapter-vercel splits bundles for Vercel's edge network; adapter-cloudflare optimizes for Workers' memory constraints.

Open this question on its own page
06

What is Svelte's approach to accessibility?

Svelte has built-in accessibility warnings at compile time — if you write inaccessible HTML, the compiler warns you during development. Checks include: missing alt text on images, non-descriptive button/link labels, invalid ARIA attributes, missing lang attribute, and interactive elements without accessible roles. These warnings appear in the terminal and can be configured in compilerOptions.warningFilter. Svelte-specific a11y patterns: Svelte's transition system respects the prefers-reduced-motion media query: import { prefersReducedMotion } from 'svelte/motion'; or use @media (prefers-reduced-motion: reduce) in CSS. SvelteKit's router announces route changes to screen readers via a live region — this is often missing in custom SPA routers. Focus management: SvelteKit moves focus to the main content on navigation. Best practice: use semantic HTML elements (<nav>, <main>, <button>), leverage ARIA roles only when semantic elements are insufficient, and test with screen readers (NVDA, VoiceOver) and keyboard navigation.

Open this question on its own page
07

How do you optimize SvelteKit performance for production?

SvelteKit production optimization strategies: Prerender aggressively: static HTML is fastest — prerender all pages that don't need per-request data. Streaming SSR: return unresolved promises from load functions; SvelteKit streams HTML with deferred data — the browser renders what's available immediately. Code splitting: SvelteKit splits bundles per route automatically — users only download code for pages they visit. Link preloading: data-sveltekit-preload-data="hover" fetches data on hover for instant-feeling navigation. Svelte 5 runes: fine-grained reactivity only updates exactly what changed, no unnecessary component re-renders. CSS: Svelte's scoped CSS is tree-shaken — unused component styles are not included. Image optimization: use <enhanced:img> for automatic WebP/AVIF conversion and responsive sizes. Cache headers: set long cache headers on immutable assets (content-hashed), short TTL on dynamic content. Edge deployment: deploy to Cloudflare Workers or Vercel Edge for global low-latency SSR. Measure: use Lighthouse, Web Vitals, and the Vite bundle analyzer to identify actual bottlenecks.

Open this question on its own page
08

What is the SvelteKit module system and $lib, $app imports?

SvelteKit provides several virtual module aliases for clean imports. $lib: resolves to src/lib — your shared components, utilities, and stores. import Button from '$lib/components/Button.svelte'; instead of relative paths. $app/stores: built-in stores — page (current URL, route params, data), navigating (navigation in progress), updated (whether the deployed app has changed). $app/navigation: navigation functions — goto, invalidate, invalidateAll, preloadData, pushState, replaceState, beforeNavigate, afterNavigate. $app/environment: browser (true in browser), dev (true in dev mode), building (true during static prerender). $app/forms: enhance, applyAction, deserialize. $env/static/private, $env/static/public, etc.: environment variables. Custom aliases are configured in svelte.config.js under kit.alias.

Open this question on its own page
09

How does SvelteKit handle internationalization (i18n)?

SvelteKit doesn't have built-in i18n but integrates well with libraries. Paraglide.js (by Inlang, built for SvelteKit): compile-time i18n with tree-shaken translations — each page only includes the strings it uses. Uses a messages/ folder with JSON locale files. No runtime overhead. svelte-i18n: runtime i18n with stores, plural forms, and date/number formatting. URL-based locale routing: the recommended pattern — prefix routes with locale: /en/about, /de/about. Implement in hooks.server.js: detect locale from URL, set in event.locals, make available to load functions. Redirect root / based on Accept-Language header. SvelteKit route groups: src/routes/[lang]/ with a layout that validates the locale param. Static prerendering: prerender each locale separately for maximum performance. export const prerender = true; export function entries() { return SUPPORTED_LOCALES.map(lang => ({ lang })); }.

Open this question on its own page
10

What are Svelte 5 snippets and how do they replace slots?

Snippets are Svelte 5's replacement for slots, offering more flexibility. They are reusable chunks of template that can be passed to components or used locally. Defining a snippet: {#snippet header(title)} <h1>{title}</h1> {/snippet}. Rendering a snippet: {@render header('My Title')}. Passing snippets to components: snippets defined in a parent's scope can be passed as props: <Table {header} {row} {footer} />. Inside the Table component: let { header, row, footer } = $props(); {@render header()}. Improvements over slots: Parameters: snippets can accept arguments (like render props in React). Portability: snippets can be passed to any component, not just the direct parent. Default snippets: the content between component tags is the default snippet: <Component>This is the default snippet</Component>, accessed as children prop. Conditional rendering: {#if children} {@render children()} {/if}. Snippets make component APIs more explicit and flexible than slots.

Open this question on its own page
Back to All Topics 43 questions total