{"id":5299,"date":"2026-09-03T10:23:00","date_gmt":"2026-09-03T02:23:00","guid":{"rendered":"https:\/\/arc.dev\/employer-blog\/?p=5299"},"modified":"2026-09-03T10:23:34","modified_gmt":"2026-09-03T02:23:34","slug":"svelte-vs-sveltekit","status":"publish","type":"post","link":"https:\/\/arc.dev\/employer-blog\/svelte-vs-sveltekit\/","title":{"rendered":"Svelte vs SvelteKit: When to Reach for the Meta-Framework (and How It Changes Architecture)"},"content":{"rendered":"\n<p>Written for Svelte 5 and SvelteKit 2.70.3. SvelteKit 3 is in release candidate (3.0.0-next.24) as of August 2026; stable release expected with no further breaking changes. Version-specific notes are flagged inline.<\/p>\n\n\n\n<p>Plenty of teams talk about &#8220;Svelte vs SvelteKit&#8221; like it&#8217;s a version number choice, similar to picking Vue 2 or Vue 3. It isn&#8217;t. Svelte is a compiler that turns your components into plain JavaScript, while SvelteKit is the application framework built on top of it, adding file-based routing, server rendering, data loading, API endpoints, and deployment adapters.<\/p>\n\n\n\n<p><strong>Pick the wrong one, and you don&#8217;t flip a config flag later; you re-architect: routing, data fetching, and deployment all change shape.<\/strong><\/p>\n\n\n\n<p>The two-question heuristic:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Does this need URLs?<\/li>\n\n\n\n<li>Does this need a server?<\/li>\n<\/ol>\n\n\n\n<p>If both answers are no, plain Svelte is enough. If either is yes, you&#8217;ll eventually rebuild toward SvelteKit. Everything else in this guide is detail.<\/p>\n\n\n\n<p>That&#8217;s why this question shows up in technical interviews. Engineers who have shipped production Svelte can tell you why a widget stays on plain Svelte while a dashboard needs +page.server.js. Engineers who have only followed a tutorial reach for SvelteKit every time, or never.<\/p>\n\n\n\n<p><strong>In this guide:<\/strong><\/p>\n\n\n\n<p>Svelte vs SvelteKit: what each layer handles<\/p>\n\n\n\n<p>Svelte as the UI compiler<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>How .svelte components combine HTML, CSS, and JavaScript<\/li>\n\n\n\n<li>Reactivity, props, events, and direct DOM updates<\/li>\n\n\n\n<li>What compile-time output means for bundle size<\/li>\n<\/ul>\n\n\n\n<p>What SvelteKit adds to Svelte<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>File-based routing in src\/routes<\/li>\n\n\n\n<li>Server primitives: +page.server.js, +server.js, and hooks.server.js<\/li>\n\n\n\n<li>Data loading, form actions, and progressive enhancement<\/li>\n<\/ul>\n\n\n\n<p>Project cases that favor each choice<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use plain Svelte for embedded widgets and component libraries<\/li>\n\n\n\n<li>Use SvelteKit for searchable multi-page sites and full-stack products<\/li>\n\n\n\n<li>How a pricing calculator and SaaS dashboard lead to different choices<\/li>\n<\/ul>\n\n\n\n<p>Architecture trade-offs after adopting SvelteKit<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Choose SSR, SSG, prerendering, or CSR per route<\/li>\n\n\n\n<li>Place sensitive data fetching on the server and public work on the client<\/li>\n\n\n\n<li>Plan code splitting, preloading, and hydration costs<\/li>\n<\/ul>\n\n\n\n<p>A scenario-based selection matrix<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Decision table: embedded widget, internal tool, marketing site, SaaS product, library, and static blog<\/li>\n\n\n\n<li>SvelteKit vs Next.js vs Nuxt<\/li>\n\n\n\n<li>Common mistakes teams make when choosing between them<\/li>\n<\/ul>\n\n\n\n<p>Recent SvelteKit updates and a fast starting point<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>How Svelte 5 runes affect new SvelteKit code<\/li>\n\n\n\n<li>What to watch in routing, load APIs, and the adapter ecosystem<\/li>\n\n\n\n<li>Create a project with npx sv create and inspect the generated structure<\/li>\n<\/ul>\n\n\n\n<p>Frequently Asked Questions<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Svelte vs SvelteKit: what each layer handles<\/strong><\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>Capability<\/strong><\/td><td><strong>Plain Svelte<\/strong><\/td><td><strong>SvelteKit<\/strong><\/td><\/tr><tr><td>Component compilation<\/td><td>\u2714<\/td><td>\u2714<\/td><\/tr><tr><td>Scoped CSS<\/td><td>\u2714<\/td><td>\u2714<\/td><\/tr><tr><td>Reactivity ($state, $derived)<\/td><td>\u2714<\/td><td>\u2714<\/td><\/tr><tr><td>Custom elements (Web Components)<\/td><td>\u2714<\/td><td>\u2714<\/td><\/tr><tr><td>File-based routing<\/td><td>\u2717<\/td><td>\u2714<\/td><\/tr><tr><td>Server-side rendering<\/td><td>\u2717<\/td><td>\u2714<\/td><\/tr><tr><td>Static site generation<\/td><td>\u2717<\/td><td>\u2714<\/td><\/tr><tr><td>Server load functions<\/td><td>\u2717<\/td><td>\u2714<\/td><\/tr><tr><td>Form actions<\/td><td>\u2717<\/td><td>\u2714<\/td><\/tr><tr><td>API endpoints (+server.js)<\/td><td>\u2717<\/td><td>\u2714<\/td><\/tr><tr><td>Deployment adapters<\/td><td>\u2717<\/td><td>\u2714<\/td><\/tr><tr><td>Environment variable guards ($env\/static\/private)<\/td><td>\u2717<\/td><td>\u2714<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Svelte as the UI compiler<\/strong><\/h2>\n\n\n\n<p><strong>What is Svelte?<\/strong> Svelte is a compiler that turns your components into plain JavaScript at build time. Unlike React or Vue, there&#8217;s no runtime library shipped to the browser, as Svelte compiles its reactivity away. You write components in .svelte files with HTML, CSS, and JavaScript in one place.<\/p>\n\n\n\n<p><strong>What is SvelteKit?<\/strong> SvelteKit is the application framework built on top of Svelte. It adds file-based routing, server-side rendering, data loading, form handling, API endpoints, and deployment adapters. If Svelte is the component compiler, SvelteKit is everything you need to turn those components into a deployed web application.<\/p>\n\n\n\n<p>That distinction matters for what ships to the browser. React and Vue send a runtime library along with your code, though Vue 3.6&#8217;s Vapor Mode, currently in release candidate, offers opt-in compilation with no virtual DOM for compatible components. Svelte mostly sends your code, and has done so since version 1.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>How<\/strong> <strong>.svelte<\/strong><strong> components combine HTML, CSS, and JavaScript<\/strong><\/h3>\n\n\n\n<p>A .svelte file holds three parts: a &lt;script&gt; block, markup, and a &lt;style&gt; block. You write regular HTML, regular CSS, and regular JavaScript in one file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;!-- Counter.svelte --&gt;\n\n&lt;script&gt;\n\n&nbsp;&nbsp;let { initialCount = 0 } = $props()\n\n&nbsp;&nbsp;let count = $state(initialCount)\n\n&lt;\/script&gt;\n\n&lt;button onclick={() =&gt; count++}&gt;\n\n&nbsp;&nbsp;Clicks: {count}\n\n&lt;\/button&gt;\n\n&lt;style&gt;\n\n&nbsp;&nbsp;button {\n\n&nbsp;&nbsp;&nbsp;&nbsp;font-size: 1rem;\n\n&nbsp;&nbsp;&nbsp;&nbsp;padding: 0.5rem 1rem;\n\n&nbsp;&nbsp;}\n\n&lt;\/style&gt;<\/code><\/pre>\n\n\n\n<p>Styles are scoped to the component by default. Svelte adds a class hash during compilation, so a .button rule in one component won&#8217;t leak into another. No CSS-in-JS library required.<\/p>\n\n\n\n<p>Markup supports control flow blocks like {#each}, {#if}, and {#await} directly in the template. Built-in transition: and animate: directives handle enter\/exit animations without a separate animation package.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Reactivity, props, events, and direct DOM updates<\/strong><\/h3>\n\n\n\n<p>Svelte 5 uses <a href=\"https:\/\/svelte.dev\/docs\/svelte\/what-are-runes\">runes<\/a> for reactivity. You declare state with $state(), derived values with $derived(), side effects with $effect(), and props with $props(). Earlier versions used let plus the $: label, and plenty of production code still runs that way.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;script&gt;\n\n&nbsp;&nbsp;let price = $state(100)\n\n&nbsp;&nbsp;let quantity = $state(1)\n\n&nbsp;&nbsp;let total = $derived(price * quantity)\n\n&nbsp;&nbsp;$effect(() =&gt; {\n\n&nbsp;&nbsp;&nbsp;&nbsp;console.log(`Total updated: ${total}`)\n\n&nbsp;&nbsp;})\n\n&lt;\/script&gt;\n\n&lt;input type=\"number\" bind:value={price} \/&gt;\n\n&lt;input type=\"number\" bind:value={quantity} \/&gt;\n\n&lt;p&gt;Total: {total}&lt;\/p&gt;<\/code><\/pre>\n\n\n\n<p>Before runes, the primary tool for shared reactive state was Svelte stores: writable(), readable(), and derived() from svelte\/store. A writable store holds a value any component can subscribe to; a readable store exposes a value without allowing external writes; derived creates a computed value from one or more stores.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ src\/lib\/stores.js\n\nimport { writable, derived } from 'svelte\/store'\n\nexport const count = writable(0)\n\nexport const doubled = derived(count, $count =&gt; $count * 2)<\/code><\/pre>\n\n\n\n<p>Stores still work in Svelte 5 and are common in production codebases. They sit alongside setContext\/getContext as the two pre-rune approaches to cross-component state. Runes ($state in .svelte.js files) are the direction for new code, but don&#8217;t rewrite working stores for the sake of it.<\/p>\n\n\n\n<p>Components pass data down through props and communicate up through callback props or events. For state shared across a tree without prop drilling, setContext() and getContext() handle it.<\/p>\n\n\n\n<p>The compiler knows at build time which DOM nodes depend on which values. When a value changes, Svelte updates exactly those nodes; no reconciliation pass needed.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>What compile-time output means for bundle size<\/strong><\/h3>\n\n\n\n<p>Because reactivity is compiled in, a small Svelte app ships very little framework code. A counter component compiles to a handful of DOM instructions rather than a component tree plus a runtime that walks it.<\/p>\n\n\n\n<p>The practical effect shows up on small, embedded surfaces. Drop one interactive UI component into an existing page, and you add kilobytes, not a framework bundle.<\/p>\n\n\n\n<p>The gap narrows on large apps, since your own component code dominates. But for isolated widgets, compile-time output is the whole reason to choose Svelte.<\/p>\n\n\n\n<p>The numbers are real. A minimal Svelte counter component ($state, a button, a display) compiles to roughly 1\u20132 kB of JavaScript. The equivalent in React requires React and ReactDOM (roughly 45 kB minified, 14 kB gzipped for the runtime alone) before your component code. For a single embedded widget in an existing page, the difference is whether you&#8217;re adding a script tag or adding a framework.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>What SvelteKit adds to Svelte<\/strong><\/h2>\n\n\n\n<p>SvelteKit is the app framework built around Svelte. It handles the parts a component framework deliberately leaves out: routing, server code, data loading, form handling, and deployment.<\/p>\n\n\n\n<p>Think of it as everything between &#8220;I have components&#8221; and &#8220;I have a deployed web application.&#8221; If you&#8217;re coming from React, SvelteKit fills the role Next.js does. From Vue, it&#8217;s Nuxt.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>File-based routing in <\/strong><strong>src\/routes<\/strong><\/h3>\n\n\n\n<p>Routes live in src\/routes, and folder structure defines URLs. You don&#8217;t need a route config file.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>src\/routes\/+page.svelte renders \/<\/li>\n\n\n\n<li>src\/routes\/about\/+page.svelte renders \/about<\/li>\n\n\n\n<li>src\/routes\/blog\/[slug]\/+page.svelte renders \/blog\/anything, with slug available as a param<\/li>\n\n\n\n<li>src\/routes\/+layout.svelte wraps every child route with shared UI<\/li>\n\n\n\n<li>src\/routes\/(marketing)\/ groups routes without adding a URL segment<\/li>\n\n\n\n<li>src\/routes\/+error.svelte renders when a route throws<\/li>\n<\/ul>\n\n\n\n<p>src\/routes\/<\/p>\n\n\n\n<p>\u251c\u2500\u2500 +layout.svelte&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \u2192 wraps all routes<\/p>\n\n\n\n<p>\u251c\u2500\u2500 +page.svelte&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \u2192 \/<\/p>\n\n\n\n<p>\u251c\u2500\u2500 about\/<\/p>\n\n\n\n<p>\u2502 &nbsp; \u2514\u2500\u2500 +page.svelte&nbsp; &nbsp; &nbsp; &nbsp; \u2192 \/about<\/p>\n\n\n\n<p>\u251c\u2500\u2500 blog\/<\/p>\n\n\n\n<p>\u2502 &nbsp; \u251c\u2500\u2500 +page.svelte&nbsp; &nbsp; &nbsp; &nbsp; \u2192 \/blog<\/p>\n\n\n\n<p>\u2502 &nbsp; \u2514\u2500\u2500 [slug]\/<\/p>\n\n\n\n<p>\u2502 &nbsp; &nbsp; &nbsp; \u251c\u2500\u2500 +page.svelte&nbsp; &nbsp; \u2192 \/blog\/:slug<\/p>\n\n\n\n<p>\u2502 &nbsp; &nbsp; &nbsp; \u2514\u2500\u2500 +page.server.js \u2192 server load for \/blog\/:slug<\/p>\n\n\n\n<p>\u251c\u2500\u2500 (marketing)\/&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \u2192 route group, no URL segment<\/p>\n\n\n\n<p>\u2502 &nbsp; \u2514\u2500\u2500 contact\/<\/p>\n\n\n\n<p>\u2502 &nbsp; &nbsp; &nbsp; \u2514\u2500\u2500 +page.svelte&nbsp; &nbsp; \u2192 \/contact<\/p>\n\n\n\n<p>\u2514\u2500\u2500 api\/<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u2514\u2500\u2500 products\/<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u2514\u2500\u2500 +server.js&nbsp; &nbsp; &nbsp; \u2192 \/api\/products (GET, POST, etc.)<\/p>\n\n\n\n<p>SvelteKit code-splits per route automatically. Users downloading \/about don&#8217;t download the dashboard bundle.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Server primitives: <\/strong><strong>+page.server.js<\/strong><strong>, <\/strong><strong>+server.js<\/strong><strong>, and <\/strong><strong>hooks.server.js<\/strong><\/h3>\n\n\n\n<p>These three files decide what runs where, and they carry most of SvelteKit&#8217;s architectural weight.<\/p>\n\n\n\n<p>+page.server.js runs only on the server. Put database queries, secret API keys, and session checks here. Its <a href=\"https:\/\/svelte.dev\/tutorial\/kit\/universal-load-functions\">load function<\/a> returns data that the matching +page.svelte receives as props.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ src\/routes\/blog\/&#91;slug]\/+page.server.js\n\nimport { db } from '$lib\/server\/db'\n\nimport { error } from '@sveltejs\/kit'\n\nexport async function load({ params }) {\n\n&nbsp;&nbsp;const post = await db.post.findUnique({ where: { slug: params.slug } })\n\n&nbsp;&nbsp;if (!post) error(404, 'Post not found')\n\n&nbsp;&nbsp;return { post }\n\n}<\/code><\/pre>\n\n\n\n<p>+server.js creates an API endpoint. Export GET, POST, PATCH, or DELETE functions, and you have a JSON route living next to the page that consumes it. That&#8217;s how you serve a mobile client or webhook from the same codebase.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ src\/routes\/api\/products\/+server.js\n\nimport { json } from '@sveltejs\/kit'\n\nimport { db } from '$lib\/server\/db'\n\nexport async function GET({ url }) {\n\n&nbsp;&nbsp;const category = url.searchParams.get('category')\n\n&nbsp;&nbsp;const products = await db.product.findMany({ where: { category } })\n\n&nbsp;&nbsp;return json(products)\n\n}<\/code><\/pre>\n\n\n\n<p>hooks.server.js intercepts every request. Authentication checks, request logging, and setting event.locals for downstream loads all happen there.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Data loading, form actions, and progressive enhancement<\/strong><\/h3>\n\n\n\n<p>A load function in +page.js runs on both server and client. The same function in +page.server.js runs only on the server. Choosing between the two is a security and performance decision, not a style preference, and the <a href=\"https:\/\/svelte.dev\/tutorial\/kit\/using-both-load-functions\">official SvelteKit tutorial on combining both load types<\/a> explains exactly when each applies.<\/p>\n\n\n\n<p>Form actions handle mutations. You export an actions object from +page.server.js, point a &lt;form method=&#8221;POST&#8221;&gt; at it, and it works with JavaScript disabled.<\/p>\n\n\n\n<p>Add use:enhance from $app\/forms, and SvelteKit upgrades that same form to a client-side submit with no full-page reload. The HTML form remains the fallback, which is the practical meaning of progressive enhancement here.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;!-- src\/routes\/contact\/+page.svelte --&gt;\n\n&lt;script&gt;\n\n&nbsp;&nbsp;import { enhance } from '$app\/forms'\n\n&nbsp;&nbsp;let { form } = $props()\n\n&lt;\/script&gt;\n\n&lt;form method=\"POST\" use:enhance&gt;\n\n&nbsp;&nbsp;&lt;input name=\"email\" type=\"email\" required \/&gt;\n\n&nbsp;&nbsp;&lt;button type=\"submit\"&gt;Subscribe&lt;\/button&gt;\n\n&nbsp;&nbsp;{#if form?.success}\n\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;p&gt;You're subscribed.&lt;\/p&gt;\n\n&nbsp;&nbsp;{\/if}\n\n&lt;\/form&gt;\n\n\/\/ src\/routes\/contact\/+page.server.js\n\nexport const actions = {\n\n&nbsp;&nbsp;default: async ({ request }) =&gt; {\n\n&nbsp;&nbsp;&nbsp;&nbsp;const data = await request.formData()\n\n&nbsp;&nbsp;&nbsp;&nbsp;await subscribe(data.get('email'))\n\n&nbsp;&nbsp;&nbsp;&nbsp;return { success: true }\n\n&nbsp;&nbsp;}\n\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Project cases that favor each choice<\/strong><\/h2>\n\n\n\n<p>The two questions from the top of this guide play out most clearly in concrete scenarios.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Use plain Svelte for embedded widgets and component libraries<\/strong><\/h3>\n\n\n\n<p>Plain Svelte fits when your UI lives inside something else. A React app that needs one complex chart, a Rails page that needs an interactive configurator, a WordPress site with a booking form.<\/p>\n\n\n\n<p>It also fits component libraries. If you&#8217;re publishing a design system for other teams, you want compiled components and a package.json, not routing and adapters.<\/p>\n\n\n\n<p>The API that makes widget embedding work is customElement: true in &lt;svelte:options&gt;. Set it, and Svelte compiles the component as a real Web Component \u2014 a custom HTML element you can drop into any page regardless of its framework or lack of one:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;svelte:options customElement=\"my-counter\" \/&gt;\n\n&lt;script&gt;\n\n&nbsp;&nbsp;let count = $state(0)\n\n&lt;\/script&gt;\n\n&lt;button onclick={() =&gt; count++}&gt;Clicks: {count}&lt;\/button&gt;<\/code><\/pre>\n\n\n\n<p>Then, in any HTML page: &lt;my-counter&gt;&lt;\/my-counter&gt;. No React wrapper, no Svelte runtime on the host page.<\/p>\n\n\n\n<p>Small single-page tools qualify too. An internal calculator, a QA checklist, a data converter, anything with one screen and no URLs to manage.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Use SvelteKit for searchable multi-page sites and full-stack products<\/strong><\/h3>\n\n\n\n<p>SEO is the clearest signal. Client-side rendering means crawlers and social preview bots get an empty HTML shell first. SSR or prerendering sends real content in the initial response.<\/p>\n\n\n\n<p>Setting titles and meta descriptions in SvelteKit is done through the Metadata API \u2014 export a load function that returns an object, or use &lt;svelte:head&gt; directly in a component for simpler cases:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;!-- In any +page.svelte --&gt;\n\n&lt;svelte:head&gt;\n\n&nbsp;&nbsp;&lt;title&gt;My Blog Post&lt;\/title&gt;\n\n&nbsp;&nbsp;&lt;meta name=\"description\" content=\"A post about SvelteKit routing.\" \/&gt;\n\n&lt;\/svelte:head&gt;<\/code><\/pre>\n\n\n\n<p>For dynamic metadata (per-post titles, Open Graph images), return title and description from your +page.server.js load function and pass them to &lt;svelte:head&gt; via props. This is what makes SvelteKit&#8217;s SEO story concrete: real &lt;title&gt; and &lt;meta&gt; tags in the initial HTML response, visible to any crawler.<\/p>\n\n\n\n<p>Server-side data fetching is the second signal. If a page needs a database row, a private API key, or a session check before it renders, you need server code. SvelteKit gives you that in the same repo.<\/p>\n\n\n\n<p>Multi-page structure is the third. Once you have five routes with shared layouts and per-route code splitting, hand-rolling a router costs more than adopting SvelteKit.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>How a pricing calculator and SaaS dashboard lead to different choices<\/strong><\/h3>\n\n\n\n<p>Say a marketing team wants an interactive pricing calculator on an existing static landing page. It has no routes, no server data, and no SEO value beyond the page it sits on. Compile it with plain Svelte, ship a small bundle, and drop the script tag into the existing HTML. Adding SvelteKit here means adding a build target, an adapter, and a deployment story for one widget.<\/p>\n\n\n\n<p>Now say you&#8217;re building a SaaS product: authenticated dashboard routes, per-user data loaded server-side, Stripe webhooks, and a public marketing site sharing the same components. SvelteKit handles it all: Guard routes in hooks.server.js, load user data in +page.server.js, receive webhooks in +server.js, and prerender marketing pages.<\/p>\n\n\n\n<p>Same language, same components, completely different architecture.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Architecture trade-offs after adopting SvelteKit<\/strong><\/h2>\n\n\n\n<p>Adopting SvelteKit doesn&#8217;t just add features. It moves several decisions from &#8220;we&#8217;ll figure it out&#8221; to &#8220;we decide this per route, on purpose.&#8221;<\/p>\n\n\n\n<p>Teams that skip these decisions end up with an app that server-renders a dashboard nobody can cache, or a marketing site that ships an empty shell to Googlebot.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Choose SSR, SSG, prerendering, or CSR per route<\/strong><\/h3>\n\n\n\n<p>SvelteKit defaults to SSR, then hydrates. You override per route with export const prerender = true or export const ssr = false in +page.js, or set defaults in +layout.js.<\/p>\n\n\n\n<p><strong>Server-Side Rendering (SSR)<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Pro: fresh data on every request, good for dashboards and anything personalized<\/li>\n\n\n\n<li>Pro: real HTML in the first response, so crawlers and preview bots see content<\/li>\n\n\n\n<li>Con: you pay server compute per request<\/li>\n\n\n\n<li>Con: slow upstream APIs directly slow your TTFB (Time to First Byte); the metric that measures how long until the browser receives the first byte of the HTML response<\/li>\n<\/ul>\n\n\n\n<p><strong>Static Site Generation \/ Prerendering (SSG)<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Pro: fastest and cheapest to serve, since it&#8217;s files on a CDN<\/li>\n\n\n\n<li>Pro: no server to scale or keep online<\/li>\n\n\n\n<li>Con: content is stale until the next build<\/li>\n\n\n\n<li>Con: build times grow with page count, which hurts at thousands of pages<\/li>\n\n\n\n<li>Con: can&#8217;t render per-user content<\/li>\n<\/ul>\n\n\n\n<p><strong>Client-Side Rendering (CSR)<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Pro: simplest mental model, no server runtime to reason about<\/li>\n\n\n\n<li>Pro: good for authenticated internal tools where SEO doesn&#8217;t matter<\/li>\n\n\n\n<li>Con: worst LCP (Largest Contentful Paint), since users wait for JS before seeing anything, and INP (Interaction to Next Paint) can suffer too if heavy hydration blocks the main thread<\/li>\n\n\n\n<li>Con: crawlers get an empty shell<\/li>\n<\/ul>\n\n\n\n<p>A common working setup: prerender marketing and docs, SSR the app shell and anything personalized, disable SSR on heavy client-only screens like a canvas editor.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Place sensitive data fetching on the server and public work on the client<\/strong><\/h3>\n\n\n\n<p>A load in +page.js may run in the browser. Anything it imports can end up in the client bundle, including that API key you thought was safe.<\/p>\n\n\n\n<p>Put secrets, database calls, and authorization checks in +page.server.js or +layout.server.js. Import secrets from $env\/static\/private, which SvelteKit refuses to bundle into client code.<\/p>\n\n\n\n<p>Use the universal load in +page.js for public data, or for values that can&#8217;t be serialized, like a class instance or a component reference.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Plan code splitting, preloading, and hydration costs<\/strong><\/h3>\n\n\n\n<p>SvelteKit splits code by route out of the box. Preloading is what makes those splits feel instant: data-sveltekit-preload-data=&#8221;hover&#8221; fetches a route&#8217;s data when the user hovers a link, before the click lands.<\/p>\n\n\n\n<p>Hydration still costs something. Server-rendered HTML appears fast, but the page isn&#8217;t interactive until the JS loads and attaches. Heavy routes with large component trees feel the gap most.<\/p>\n\n\n\n<p>Two levers help. Move work into load so it happens on the server, and mark genuinely static routes with prerender = true so they skip hydration-heavy paths entirely.<\/p>\n\n\n\n<p>Deployment is the last trade-off, and it&#8217;s an <a href=\"https:\/\/svelte.dev\/docs\/kit\/adapters\">adapter<\/a> choice:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>Adapter<\/strong><\/td><td><strong>Runtime<\/strong><\/td><td><strong>Node APIs available?<\/strong><\/td><td><strong>Best for<\/strong><\/td><\/tr><tr><td>adapter-auto<\/td><td>Depends on platform<\/td><td>Depends<\/td><td>Prototypes; verifies platform automatically<\/td><\/tr><tr><td>adapter-node<\/td><td>Node.js (long-running server)<\/td><td>\u2714 Full<\/td><td>Self-hosted VPS, Docker, Railway<\/td><\/tr><tr><td>adapter-static<\/td><td>None (files only)<\/td><td>\u2717<\/td><td>Fully prerendered sites; no dynamic routes<\/td><\/tr><tr><td>adapter-vercel<\/td><td>Serverless or edge<\/td><td>Partial (serverless: \u2714; edge: \u2717)<\/td><td>Vercel deployments; includes ISR support<\/td><\/tr><tr><td>adapter-netlify<\/td><td>Netlify Functions or edge<\/td><td>Partial (functions: \u2714; edge: \u2717)<\/td><td>Netlify deployments<\/td><\/tr><tr><td>adapter-cloudflare<\/td><td>Cloudflare Workers<\/td><td>\u2717 (Workers runtime only)<\/td><td>Fastest cold starts; no Node-only drivers<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><strong>The column that matters most:<\/strong> if you import a Node-only database driver (like the native pg client) and pick an edge adapter, you get a build or runtime error \u2014 not a dev-time warning. Confirm Node API availability before committing to an adapter.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>A scenario-based selection matrix<\/strong><\/h2>\n\n\n\n<p>Framework choice gets easier when you stop asking &#8220;which is better&#8221; and start matching a scenario to its constraints.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Decision table: embedded widget, internal tool, marketing site, SaaS product, library, and static blog<\/strong><\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>Scenario<\/strong><\/td><td><strong>Use Svelte<\/strong><\/td><td><strong>Use SvelteKit<\/strong><\/td><td><strong>Why<\/strong><\/td><\/tr><tr><td>Embedded widget in a non-Svelte page<\/td><td>\u2714<\/td><td>X<\/td><td>No routes, no server data. Compile to a small bundle and drop it in.<\/td><\/tr><tr><td>Internal admin tool (auth required)<\/td><td>Possible<\/td><td>\u2714<\/td><td>Needs routing and server-side auth checks. SEO doesn&#8217;t matter, so ssr = false is fine on heavy screens.&nbsp;<\/td><\/tr><tr><td>Marketing site<\/td><td>X<\/td><td>\u2714<\/td><td>SEO and first paint depend on real HTML. Prerender with adapter-static.<\/td><\/tr><tr><td>Full SaaS product<\/td><td>X<\/td><td>\u2714<\/td><td>Auth, per-route data loading, API endpoints, and a shared marketing site in one codebase.<\/td><\/tr><tr><td>Component library<\/td><td>\u2714<\/td><td>Only for packaging<\/td><td>Consumers want components, not routing. Use @sveltejs\/package if you want the tooling.<\/td><\/tr><tr><td>Static blog<\/td><td>X<\/td><td>\u2714<\/td><td>Prerendered routes plus dynamic [slug] pages. Deploys as static files.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><strong>The short version:<\/strong> If the thing you&#8217;re building has URLs or touches a server, use SvelteKit. If it&#8217;s a self-contained piece of UI living inside something else, plain Svelte keeps your bundle small and your build simple. Everything else is a detail you can decide later.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>SvelteKit vs Next.js vs Nuxt<\/strong><\/h3>\n\n\n\n<p>SvelteKit, Next.js, and Nuxt solve the same category of problem: routing, rendering, data loading, and deployment for a component framework. They are not drop-in equivalents.<\/p>\n\n\n\n<p>Next.js has React Server Components, which stream server-rendered components and keep their code entirely off the client. SvelteKit has no direct equivalent, and its answer is that compiled Svelte ships so little JS that the gap is smaller than it looks. Both positions are defensible depending on the app.<\/p>\n\n\n\n<p>Nuxt sits closest to SvelteKit in structure: file-based routes, server routes, and a deployment layer. The real differences are ecosystem depth and hiring pool, not capability.<\/p>\n\n\n\n<p>Practical read: SvelteKit&#8217;s smaller ecosystem means more first-party solutions and fewer third-party libraries. That&#8217;s less setup work and less choice paralysis, but occasionally more code you write yourself.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Common mistakes teams make when choosing between them<\/strong><\/h3>\n\n\n\n<p>Two patterns show up in code reviews and interviews, and both signal the same gap.<\/p>\n\n\n\n<p>The first is reaching for SvelteKit by default. A single embedded widget doesn&#8217;t need an adapter, a routing tree, or a deployment target. Adding all three creates ongoing maintenance for zero user-facing benefit.<\/p>\n\n\n\n<p>The second is avoiding SvelteKit when SSR is clearly required. Building a public product catalog as a client-rendered SPA, then trying to bolt on prerendering after launch, means rewriting data loading from scratch.<\/p>\n\n\n\n<p><strong>Strong engineers explain the trade-off in operational terms:<\/strong> hydration cost, build time at scale, server spend per request, how long a new hire takes to find where a route&#8217;s data comes from.&nbsp;<\/p>\n\n\n\n<p>When we vet <a href=\"http:\/\/arc.dev\/hire-developers\/svelte\">Svelte<\/a> and SvelteKit engineers at Arc, that reasoning matters more than framework trivia. We ask about real scenarios, like where to place a load function that touches a payment API, because the answer reveals whether someone has shipped this or read about it.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Recent SvelteKit updates and a fast starting point<\/strong><\/h2>\n\n\n\n<p>SvelteKit moves at a steady pace, and most recent SvelteKit updates trace back to Svelte 5 landing underneath it rather than to SvelteKit itself. If you want the changes as they land, the <a href=\"https:\/\/svelte.dev\/blog\">official Svelte blog&#8217;s release recaps<\/a> are the most reliable source, and more current than most third-party roundups.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>How Svelte 5 runes affect new SvelteKit code<\/strong><\/h3>\n\n\n\n<p><a href=\"https:\/\/arc.dev\/employer-blog\/svelte-5-runes-migration-guide\/\">Svelte 5<\/a> replaced implicit reactivity with runes. New components use $state(), $derived(), $effect(), and $props() instead of top-level let and the $: label.<\/p>\n\n\n\n<p>Inside SvelteKit, this mostly changes how you handle data from a load function. You declare it with let { data } = $props(), and reactive values derived from it use $derived().<\/p>\n\n\n\n<p>Runes also work in .svelte.js and .svelte.ts files, so shared reactive state can live outside components. Svelte 5 still supports the older syntax, so existing codebases can follow the <a href=\"https:\/\/svelte.dev\/docs\/svelte\/v5-migration-guide\">official migration guide<\/a> and move over incrementally rather than all at once.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>What to watch in routing, load APIs, and the adapter ecosystem<\/strong><\/h3>\n\n\n\n<p><strong>SvelteKit 3 is in release candidate<\/strong> (3.0.0-next.24 as of August 2026). The team has stated a stable release will follow with no further breaking changes. If you&#8217;re starting a new project, the RC is worth trying; if you&#8217;re maintaining a production app on SvelteKit 2, the migration guide at next.svelte.dev covers the breaking changes, and npx sv@next migrate sveltekit-3 automates most of them. The current stable is 2.70.3.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Load APIs:<\/strong> the split between universal load in +page.js and server-only load in +page.server.js is stable. One concrete change to know: invalidateAll is deprecated in SvelteKit 3 in favor of refreshAll. The difference is that refreshAll does not reset page.state to an empty object, which is usually what you want when using shallow routing. If you&#8217;re on SvelteKit 2, invalidateAll still works; update before moving to 3.<\/li>\n\n\n\n<li><strong>Remote functions:<\/strong> <a href=\"https:\/\/svelte.dev\/docs\/kit\/remote-functions\">SvelteKit&#8217;s remote functions <\/a>add type-safe ways to call server code directly from components (query, form, command, and prerender), cutting down on hand-written +server.js boilerplate for simple cases. They remain behind an experimental flag, but have seen a year of hardening: hydratable transport in 2.56, form submit validity in 2.57, submitted on remote forms in 2.69, and field.touched() in 3.0.0-next.6. Same verdict as before (check the docs for current stability before betting your core architecture on it), but the evidence is now concrete, not vague.<\/li>\n\n\n\n<li><strong>Adapters:<\/strong> adapter-vercel, adapter-netlify, and adapter-cloudflare are all maintained and production-ready. Runtime capabilities differ, so confirm Node API support before choosing.<\/li>\n\n\n\n<li><strong>Vite: <\/strong>SvelteKit 3 adds Vite 8 support, along with a config, alias, and TypeScript setup refresh. The faster bundling work comes from Rolldown (Rust-based bundler) and Oxc (Rust-based transformer) \u2014 these show up as shorter cold starts and build times. SvelteKit 3 also moves remote-function types to @sveltejs\/kit\/remote, which is a breaking import change from the experimental setup in 2.x.<\/li>\n\n\n\n<li><strong>TypeScript:<\/strong> SvelteKit generates route-specific types in .svelte-kit\/types, so PageServerLoad and PageData stay in sync with your file structure.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Create a project with <\/strong><strong>npx sv create<\/strong><strong> and inspect the generated structure<\/strong><\/h3>\n\n\n\n<p>Scaffold a project with npx sv create my-app. The CLI asks for a template, TypeScript preference, and optional add-ons like ESLint, Prettier, Tailwind, and Playwright; the full option list lives in the <a href=\"https:\/\/svelte.dev\/docs\/cli\/sv-create\">Svelte CLI docs<\/a>.<\/p>\n\n\n\n<p>Then run cd my-app, npm install, and npm run dev. Vite starts the dev server with hot module replacement, so edits appear in the browser without a page reload.<\/p>\n\n\n\n<p>What you get:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>src\/routes\/+page.svelte: your homepage<\/li>\n\n\n\n<li>src\/routes\/+layout.svelte: shared shell around every route<\/li>\n\n\n\n<li>src\/lib\/: shared code, importable as $lib\/&#8230;<\/li>\n\n\n\n<li>src\/app.html: the HTML template SvelteKit injects into<\/li>\n\n\n\n<li>svelte.config.js: adapter and config options<\/li>\n\n\n\n<li>vite.config.js: Vite and the Svelte plugin<\/li>\n\n\n\n<li>static\/: files served as-is<\/li>\n<\/ul>\n\n\n\n<p>One useful next step: add src\/routes\/api\/hello\/+server.js with an exported GET function returning JSON, then fetch it from a load function in +page.server.js. That single exercise walks you through routing, server code, and data loading in about ten minutes, and it&#8217;s more instructive than most SvelteKit tutorial series.&nbsp;<\/p>\n\n\n\n<p>For a longer walkthrough, the <a href=\"https:\/\/svelte.dev\/tutorial\/kit\/introducing-sveltekit\">official interactive SvelteKit tutorial<\/a> covers the same ground with a live browser editor.<\/p>\n\n\n\n<p><strong>Related reading:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/arc.dev\/employer-blog\/best-platforms-to-hire-next-js-developers\/\">Best Platforms to Hire Next.js Developers in 2026<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/arc.dev\/employer-blog\/best-platforms-to-hire-svelte-developers\/\">Best Platforms to Hire Svelte Developers in 2026<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/arc.dev\/hire-developers\/svelte\">Hire vetted Svelte developers on Arc<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Frequently Asked Questions<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Is SvelteKit required to use Svelte?<\/strong><\/h3>\n\n\n\n<p>No. Svelte compiles independently of SvelteKit. You can drop a compiled Svelte component into a React app, a WordPress site, or any HTML page with no routing, no server, and no adapter. SvelteKit becomes necessary only once you need routing, server-side rendering, or data loading across multiple pages.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Can I add SvelteKit to a project later if I start with plain Svelte?<\/strong><\/h3>\n\n\n\n<p>Yes, but expect real rework, not a quick upgrade. Moving to SvelteKit means restructuring your files into src\/routes, deciding which data fetching moves into load functions, and picking a deployment adapter. Projects that stay small and single-page rarely need to make this move.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Does SvelteKit replace Express, Fastify, or a separate backend?<\/strong><\/h3>\n\n\n\n<p>For many apps, yes. +server.js endpoints and form actions handle typical API and mutation work without a separate backend service. Teams with an existing backend, a different server language, or infrastructure needs SvelteKit adapters don&#8217;t cover often keep the two separate and use SvelteKit purely for the frontend.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Is SvelteKit good for SEO?<\/strong><\/h3>\n\n\n\n<p>Yes, when configured for it. SvelteKit&#8217;s default SSR sends real HTML to crawlers on the first request, and prerender = true on static routes goes further by serving pre-built files with no server-render step at all. A SvelteKit app configured for full client-side rendering loses that advantage, so the rendering choice per route determines SEO outcomes, not the framework by default.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>What&#8217;s the difference between a universal load function and a server load function?<\/strong><\/h3>\n\n\n\n<p>A universal load in +page.js can run on both the server and in the browser, which makes it suitable for public data and values that can&#8217;t be serialized across the network. A server load in +page.server.js runs only on the server, which is where secrets, database queries, and authorization checks belong.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Are Svelte 5 runes required in SvelteKit projects?<\/strong><\/h3>\n\n\n\n<p>Not yet. SvelteKit works with both Svelte 5&#8217;s runes and the older reactivity model from Svelte 4, so existing codebases can migrate incrementally. New projects scaffolded with npx sv create default to runes.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>How do I know if my team needs to hire specifically for SvelteKit experience versus general Svelte experience?<\/strong><\/h3>\n\n\n\n<p>If the role involves routing, server-side data loading, authentication, or deployment decisions, look for SvelteKit experience specifically; those are the skills plain Svelte doesn&#8217;t touch. If the role is building isolated components or a design system, general Svelte experience is usually enough.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>The real question isn&#8217;t which version<\/strong><\/h2>\n\n\n\n<p>Svelte and SvelteKit aren&#8217;t competing options. Svelte compiles your UI, while SvelteKit decides where that UI runs, how it gets its data, and how it reaches users.<\/p>\n\n\n\n<p>Picking between them is a call about routing, rendering, and server access, made before you write the first component. Engineers who explain that call in terms of hydration cost, build time, and server spend have shipped this stack. Engineers who answer &#8220;SvelteKit, it&#8217;s the newer one&#8221; haven&#8217;t.<\/p>\n\n\n\n<p>If you&#8217;re building or scaling a SvelteKit product, you need engineers who have made these calls in production: routing strategy, per-route rendering, where each load function belongs. <a href=\"https:\/\/arc.dev\/\"><strong>Arc<\/strong><\/a><strong> vets Svelte and SvelteKit engineers <\/strong>on exactly that judgment as part of technical screening, using real scenarios rather than framework trivia.<\/p>\n\n\n\n<p><a href=\"https:\/\/arc.dev\/hire-developers\/sveltekit\"><strong>Hire pre-vetted SvelteKit engineers through Arc<\/strong><\/a><strong>.<\/strong><\/p>\n\n\n\n<script type=\"application\/ld+json\">\n{\n  \"@context\": \"https:\/\/schema.org\",\n  \"@graph\": [\n    {\n      \"@type\": \"Article\",\n      \"headline\": \"Svelte vs SvelteKit: When to Reach for the Meta-Framework (and How It Changes Architecture)\",\n      \"description\": \"Svelte vs SvelteKit explained: the real architectural difference, when to use each, and how routing, SSR, and data loading change your build.\",\n      \"image\": {\n        \"@type\": \"ImageObject\",\n        \"url\": \"https:\/\/cdn-employer-wp.arc.dev\/wp-content\/uploads\/2026\/08\/svelte-vs-sveltekit-architecture-decision.png\"\n      },\n      \"author\": {\n        \"@type\": \"Organization\",\n        \"name\": \"Arc\",\n        \"url\": \"https:\/\/arc.dev\"\n      },\n      \"publisher\": {\n        \"@type\": \"Organization\",\n        \"name\": \"Arc\",\n        \"logo\": {\n          \"@type\": \"ImageObject\",\n          \"url\": \"https:\/\/cdn.arc.dev\/arc-next-landing\/images\/arc\/share-logo.png\"\n        }\n      },\n      \"datePublished\": \"2026-08-14\",\n      \"dateModified\": \"2026-08-25\",\n      \"mainEntityOfPage\": {\n        \"@type\": \"WebPage\",\n        \"@id\": \"https:\/\/arc.dev\/employer-blog\/svelte-vs-sveltekit\/\"\n      }\n    },\n    {\n      \"@type\": \"FAQPage\",\n      \"mainEntity\": [\n        {\n          \"@type\": \"Question\",\n          \"name\": \"Is SvelteKit required to use Svelte?\",\n          \"acceptedAnswer\": {\n            \"@type\": \"Answer\",\n            \"text\": \"No. Svelte compiles independently of SvelteKit. You can drop a compiled Svelte component into a React app, a WordPress site, or any HTML page with no routing, no server, and no adapter. SvelteKit becomes necessary only once you need routing, server-side rendering, or data loading across multiple pages.\"\n          }\n        },\n        {\n          \"@type\": \"Question\",\n          \"name\": \"Can I add SvelteKit to a project later if I start with plain Svelte?\",\n          \"acceptedAnswer\": {\n            \"@type\": \"Answer\",\n            \"text\": \"Yes, but expect real rework, not a quick upgrade. Moving to SvelteKit means restructuring your files into src\/routes, deciding which data fetching moves into load functions, and picking a deployment adapter. Projects that stay small and single-page rarely need to make this move.\"\n          }\n        },\n        {\n          \"@type\": \"Question\",\n          \"name\": \"Does SvelteKit replace Express, Fastify, or a separate backend?\",\n          \"acceptedAnswer\": {\n            \"@type\": \"Answer\",\n            \"text\": \"For many apps, yes. +server.js endpoints and form actions handle typical API and mutation work without a separate backend service. Teams with an existing backend, a different server language, or infrastructure needs SvelteKit adapters do not cover often keep the two separate and use SvelteKit purely for the frontend.\"\n          }\n        },\n        {\n          \"@type\": \"Question\",\n          \"name\": \"Is SvelteKit good for SEO?\",\n          \"acceptedAnswer\": {\n            \"@type\": \"Answer\",\n            \"text\": \"Yes, when configured for it. SvelteKit's default SSR sends real HTML to crawlers on the first request, and prerender equals true on static routes goes further by serving pre-built files with no server-render step. A SvelteKit app configured for full client-side rendering loses that advantage, so the rendering choice per route determines SEO outcomes.\"\n          }\n        },\n        {\n          \"@type\": \"Question\",\n          \"name\": \"What's the difference between a universal load function and a server load function?\",\n          \"acceptedAnswer\": {\n            \"@type\": \"Answer\",\n            \"text\": \"A universal load in +page.js can run on both the server and in the browser, which makes it suitable for public data and values that cannot be serialized across the network. A server load in +page.server.js runs only on the server, which is where secrets, database queries, and authorization checks belong.\"\n          }\n        },\n        {\n          \"@type\": \"Question\",\n          \"name\": \"Are Svelte 5 runes required in SvelteKit projects?\",\n          \"acceptedAnswer\": {\n            \"@type\": \"Answer\",\n            \"text\": \"Not yet. SvelteKit works with both Svelte 5 runes and the older reactivity model from Svelte 4, so existing codebases can migrate incrementally. New projects scaffolded with npx sv create default to runes.\"\n          }\n        },\n        {\n          \"@type\": \"Question\",\n          \"name\": \"How do I know if my team needs to hire specifically for SvelteKit experience versus general Svelte experience?\",\n          \"acceptedAnswer\": {\n            \"@type\": \"Answer\",\n            \"text\": \"If the role involves routing, server-side data loading, authentication, or deployment decisions, look for SvelteKit experience specifically. If the role is building isolated components or a design system, general Svelte experience is usually enough.\"\n          }\n        }\n      ]\n    }\n  ]\n}\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>Written for Svelte 5 and SvelteKit 2.70.3. SvelteKit 3 is in release candidate (3.0.0-next.24) as of August 2026; stable release expected with no further breaking changes. Version-specific notes are flagged inline. Plenty of teams talk about &#8220;Svelte vs SvelteKit&#8221; like it&#8217;s a version number choice, similar to picking Vue 2 or Vue 3. It isn&#8217;t. [&hellip;]<\/p>\n","protected":false},"author":15,"featured_media":5301,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[93],"tags":[],"class_list":["post-5299","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Svelte vs SvelteKit: When to Use the Meta-Framework - Arc Employer Blog<\/title>\n<meta name=\"description\" content=\"Svelte vs SvelteKit explained: the real architectural difference, when to use each, and how routing, SSR, and data loading change your build.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/arc.dev\/employer-blog\/svelte-vs-sveltekit\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Svelte vs SvelteKit: When to Use the Meta-Framework - Arc Employer Blog\" \/>\n<meta property=\"og:description\" content=\"Svelte vs SvelteKit explained: the real architectural difference, when to use each, and how routing, SSR, and data loading change your build.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/arc.dev\/employer-blog\/svelte-vs-sveltekit\/\" \/>\n<meta property=\"og:site_name\" content=\"Arc Employer Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/arcdotdev\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/arcdotdev\" \/>\n<meta property=\"article:published_time\" content=\"2026-09-03T02:23:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-09-03T02:23:34+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/arc.dev\/employer-blog\/wp-content\/uploads\/2026\/08\/svelte-vs-sveltekit-architecture-decision.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1536\" \/>\n\t<meta property=\"og:image:height\" content=\"1024\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"The Arc Team\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@arcdotdev\" \/>\n<meta name=\"twitter:site\" content=\"@arcdotdev\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"The Arc Team\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"24 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/svelte-vs-sveltekit\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/svelte-vs-sveltekit\\\/\"},\"author\":{\"name\":\"The Arc Team\",\"@id\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/#\\\/schema\\\/person\\\/08dd4743f5c0f965590e77094c5579bc\"},\"headline\":\"Svelte vs SvelteKit: When to Reach for the Meta-Framework (and How It Changes Architecture)\",\"datePublished\":\"2026-09-03T02:23:00+00:00\",\"dateModified\":\"2026-09-03T02:23:34+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/svelte-vs-sveltekit\\\/\"},\"wordCount\":4413,\"publisher\":{\"@id\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/svelte-vs-sveltekit\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/svelte-vs-sveltekit-architecture-decision.png\",\"articleSection\":[\"Development\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/svelte-vs-sveltekit\\\/\",\"url\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/svelte-vs-sveltekit\\\/\",\"name\":\"Svelte vs SvelteKit: When to Use the Meta-Framework - Arc Employer Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/svelte-vs-sveltekit\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/svelte-vs-sveltekit\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/svelte-vs-sveltekit-architecture-decision.png\",\"datePublished\":\"2026-09-03T02:23:00+00:00\",\"dateModified\":\"2026-09-03T02:23:34+00:00\",\"description\":\"Svelte vs SvelteKit explained: the real architectural difference, when to use each, and how routing, SSR, and data loading change your build.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/svelte-vs-sveltekit\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/svelte-vs-sveltekit\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/svelte-vs-sveltekit\\\/#primaryimage\",\"url\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/svelte-vs-sveltekit-architecture-decision.png\",\"contentUrl\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/svelte-vs-sveltekit-architecture-decision.png\",\"width\":1536,\"height\":1024,\"caption\":\"Svelte vs SvelteKit: When to Reach for the Meta-Framework (and How It Changes Architecture)\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/svelte-vs-sveltekit\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Svelte vs SvelteKit: When to Reach for the Meta-Framework (and How It Changes Architecture)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/#website\",\"url\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/\",\"name\":\"Arc Employer Blog\",\"description\":\"Insights on hiring and remote work\",\"publisher\":{\"@id\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/#organization\",\"name\":\"Arc.dev\",\"url\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/Arc-alternate-logo.png\",\"contentUrl\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/Arc-alternate-logo.png\",\"width\":512,\"height\":512,\"caption\":\"Arc.dev\"},\"image\":{\"@id\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/arcdotdev\",\"https:\\\/\\\/x.com\\\/arcdotdev\",\"https:\\\/\\\/www.instagram.com\\\/arcdotdev\\\/\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/arcdotdev\",\"https:\\\/\\\/www.youtube.com\\\/c\\\/Arcdotdev\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/#\\\/schema\\\/person\\\/08dd4743f5c0f965590e77094c5579bc\",\"name\":\"The Arc Team\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c1380473325c827343a6d47c7b5d6916c147171af99760766d2acb56da62ed02?s=96&d=mm&r=pg\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c1380473325c827343a6d47c7b5d6916c147171af99760766d2acb56da62ed02?s=96&d=mm&r=pg\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c1380473325c827343a6d47c7b5d6916c147171af99760766d2acb56da62ed02?s=96&d=mm&r=pg\",\"caption\":\"The Arc Team\"},\"description\":\"The Arc team provides articles and expert advice on tech careers and remote work. From helping beginners land their first junior role to supporting remote workers facing challenges at home or guiding mid-level professionals toward leadership, Arc covers it all!\",\"sameAs\":[\"https:\\\/\\\/arc.dev\\\/developer-blog\\\/\",\"https:\\\/\\\/www.facebook.com\\\/arcdotdev\",\"https:\\\/\\\/www.instagram.com\\\/arcdotdev\\\/\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/arcdotdev\",\"https:\\\/\\\/x.com\\\/arcdotdev\",\"https:\\\/\\\/www.youtube.com\\\/c\\\/Arcdotdev\"],\"url\":\"https:\\\/\\\/arc.dev\\\/employer-blog\\\/author\\\/thearcteam\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Svelte vs SvelteKit: When to Use the Meta-Framework - Arc Employer Blog","description":"Svelte vs SvelteKit explained: the real architectural difference, when to use each, and how routing, SSR, and data loading change your build.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/arc.dev\/employer-blog\/svelte-vs-sveltekit\/","og_locale":"en_US","og_type":"article","og_title":"Svelte vs SvelteKit: When to Use the Meta-Framework - Arc Employer Blog","og_description":"Svelte vs SvelteKit explained: the real architectural difference, when to use each, and how routing, SSR, and data loading change your build.","og_url":"https:\/\/arc.dev\/employer-blog\/svelte-vs-sveltekit\/","og_site_name":"Arc Employer Blog","article_publisher":"https:\/\/www.facebook.com\/arcdotdev","article_author":"https:\/\/www.facebook.com\/arcdotdev","article_published_time":"2026-09-03T02:23:00+00:00","article_modified_time":"2026-09-03T02:23:34+00:00","og_image":[{"width":1536,"height":1024,"url":"https:\/\/arc.dev\/employer-blog\/wp-content\/uploads\/2026\/08\/svelte-vs-sveltekit-architecture-decision.png","type":"image\/png"}],"author":"The Arc Team","twitter_card":"summary_large_image","twitter_creator":"@arcdotdev","twitter_site":"@arcdotdev","twitter_misc":{"Written by":"The Arc Team","Est. reading time":"24 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/arc.dev\/employer-blog\/svelte-vs-sveltekit\/#article","isPartOf":{"@id":"https:\/\/arc.dev\/employer-blog\/svelte-vs-sveltekit\/"},"author":{"name":"The Arc Team","@id":"https:\/\/arc.dev\/employer-blog\/#\/schema\/person\/08dd4743f5c0f965590e77094c5579bc"},"headline":"Svelte vs SvelteKit: When to Reach for the Meta-Framework (and How It Changes Architecture)","datePublished":"2026-09-03T02:23:00+00:00","dateModified":"2026-09-03T02:23:34+00:00","mainEntityOfPage":{"@id":"https:\/\/arc.dev\/employer-blog\/svelte-vs-sveltekit\/"},"wordCount":4413,"publisher":{"@id":"https:\/\/arc.dev\/employer-blog\/#organization"},"image":{"@id":"https:\/\/arc.dev\/employer-blog\/svelte-vs-sveltekit\/#primaryimage"},"thumbnailUrl":"https:\/\/arc.dev\/employer-blog\/wp-content\/uploads\/2026\/08\/svelte-vs-sveltekit-architecture-decision.png","articleSection":["Development"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/arc.dev\/employer-blog\/svelte-vs-sveltekit\/","url":"https:\/\/arc.dev\/employer-blog\/svelte-vs-sveltekit\/","name":"Svelte vs SvelteKit: When to Use the Meta-Framework - Arc Employer Blog","isPartOf":{"@id":"https:\/\/arc.dev\/employer-blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/arc.dev\/employer-blog\/svelte-vs-sveltekit\/#primaryimage"},"image":{"@id":"https:\/\/arc.dev\/employer-blog\/svelte-vs-sveltekit\/#primaryimage"},"thumbnailUrl":"https:\/\/arc.dev\/employer-blog\/wp-content\/uploads\/2026\/08\/svelte-vs-sveltekit-architecture-decision.png","datePublished":"2026-09-03T02:23:00+00:00","dateModified":"2026-09-03T02:23:34+00:00","description":"Svelte vs SvelteKit explained: the real architectural difference, when to use each, and how routing, SSR, and data loading change your build.","breadcrumb":{"@id":"https:\/\/arc.dev\/employer-blog\/svelte-vs-sveltekit\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/arc.dev\/employer-blog\/svelte-vs-sveltekit\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/arc.dev\/employer-blog\/svelte-vs-sveltekit\/#primaryimage","url":"https:\/\/arc.dev\/employer-blog\/wp-content\/uploads\/2026\/08\/svelte-vs-sveltekit-architecture-decision.png","contentUrl":"https:\/\/arc.dev\/employer-blog\/wp-content\/uploads\/2026\/08\/svelte-vs-sveltekit-architecture-decision.png","width":1536,"height":1024,"caption":"Svelte vs SvelteKit: When to Reach for the Meta-Framework (and How It Changes Architecture)"},{"@type":"BreadcrumbList","@id":"https:\/\/arc.dev\/employer-blog\/svelte-vs-sveltekit\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/arc.dev\/employer-blog\/"},{"@type":"ListItem","position":2,"name":"Svelte vs SvelteKit: When to Reach for the Meta-Framework (and How It Changes Architecture)"}]},{"@type":"WebSite","@id":"https:\/\/arc.dev\/employer-blog\/#website","url":"https:\/\/arc.dev\/employer-blog\/","name":"Arc Employer Blog","description":"Insights on hiring and remote work","publisher":{"@id":"https:\/\/arc.dev\/employer-blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/arc.dev\/employer-blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/arc.dev\/employer-blog\/#organization","name":"Arc.dev","url":"https:\/\/arc.dev\/employer-blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/arc.dev\/employer-blog\/#\/schema\/logo\/image\/","url":"https:\/\/arc.dev\/employer-blog\/wp-content\/uploads\/2022\/02\/Arc-alternate-logo.png","contentUrl":"https:\/\/arc.dev\/employer-blog\/wp-content\/uploads\/2022\/02\/Arc-alternate-logo.png","width":512,"height":512,"caption":"Arc.dev"},"image":{"@id":"https:\/\/arc.dev\/employer-blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/arcdotdev","https:\/\/x.com\/arcdotdev","https:\/\/www.instagram.com\/arcdotdev\/","https:\/\/www.linkedin.com\/company\/arcdotdev","https:\/\/www.youtube.com\/c\/Arcdotdev"]},{"@type":"Person","@id":"https:\/\/arc.dev\/employer-blog\/#\/schema\/person\/08dd4743f5c0f965590e77094c5579bc","name":"The Arc Team","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/c1380473325c827343a6d47c7b5d6916c147171af99760766d2acb56da62ed02?s=96&d=mm&r=pg","url":"https:\/\/secure.gravatar.com\/avatar\/c1380473325c827343a6d47c7b5d6916c147171af99760766d2acb56da62ed02?s=96&d=mm&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c1380473325c827343a6d47c7b5d6916c147171af99760766d2acb56da62ed02?s=96&d=mm&r=pg","caption":"The Arc Team"},"description":"The Arc team provides articles and expert advice on tech careers and remote work. From helping beginners land their first junior role to supporting remote workers facing challenges at home or guiding mid-level professionals toward leadership, Arc covers it all!","sameAs":["https:\/\/arc.dev\/developer-blog\/","https:\/\/www.facebook.com\/arcdotdev","https:\/\/www.instagram.com\/arcdotdev\/","https:\/\/www.linkedin.com\/company\/arcdotdev","https:\/\/x.com\/arcdotdev","https:\/\/www.youtube.com\/c\/Arcdotdev"],"url":"https:\/\/arc.dev\/employer-blog\/author\/thearcteam\/"}]}},"_links":{"self":[{"href":"https:\/\/arc.dev\/employer-blog\/wp-json\/wp\/v2\/posts\/5299","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/arc.dev\/employer-blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/arc.dev\/employer-blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/arc.dev\/employer-blog\/wp-json\/wp\/v2\/users\/15"}],"replies":[{"embeddable":true,"href":"https:\/\/arc.dev\/employer-blog\/wp-json\/wp\/v2\/comments?post=5299"}],"version-history":[{"count":0,"href":"https:\/\/arc.dev\/employer-blog\/wp-json\/wp\/v2\/posts\/5299\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/arc.dev\/employer-blog\/wp-json\/wp\/v2\/media\/5301"}],"wp:attachment":[{"href":"https:\/\/arc.dev\/employer-blog\/wp-json\/wp\/v2\/media?parent=5299"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/arc.dev\/employer-blog\/wp-json\/wp\/v2\/categories?post=5299"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/arc.dev\/employer-blog\/wp-json\/wp\/v2\/tags?post=5299"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}