How to Use SvelteKit: The Beginner's Guide (First Project, File-Based Routing, Load Functions, Form Actions, and Deploy)

CodexFuse Team · 2026-10-31T03:57:27.257Z · 15 min read

How do you use SvelteKit?

You use SvelteKit by scaffolding a project with npx sv create, adding pages as +page.svelte files inside src/routes, sharing page furniture through +layout.svelte files, loading data with load functions, handling submissions with form actions, and deploying with an adapter. That is the whole beginner arc of learning how to use SvelteKit: create the project, learn the file-based routing, fetch data the SvelteKit way, post forms without an API client, and ship it.

  1. Create the project. Run npx sv create my-app, answer the prompts (template, TypeScript), then cd my-app && npm install.
  2. Start the dev server. npm run dev serves your app at localhost:5173 with instant reload.
  3. Add pages with files. src/routes/about/+page.svelte automatically becomes the /about route — no router config file exists.
  4. Share a layout. Put the nav and footer in src/routes/+layout.svelte with a {@render children()} slot for page content.
  5. Load data. A sibling +page.js or +page.server.js exports a load function; the page reads it via the data prop.
  6. Handle forms. Export actions from +page.server.js and post a plain <form method="POST"> — no fetch calls, no client state library.
  7. Deploy with an adapter. npx sv add sveltekit-adapter picks the adapter for Vercel, Netlify, Cloudflare, Node, Bun, or a static build, then npm run build ships it.

You will need Node.js (version ^20.19.0, ^22.13.0, or 24 and up, per the 2026 community guides) and a code editor. SvelteKit's own documentation recommends VS Code with the official Svelte extension — our VS Code beginner guide walks through the setup, including the extension step SvelteKit developers repeat on every machine.

What is SvelteKit, and how is it different from Svelte?

SvelteKit is the official full-stack application framework built on top of Svelte — the same relationship Next.js has to React. Svelte is the UI layer: a compiler that turns your components into lean, optimized plain JavaScript at build time, with no virtual DOM and no framework running in the browser. SvelteKit adds everything an app needs around that UI layer: file-based routing, server-side rendering, static site generation, data loading, form handling, and API routes.

The compiler-first design is the whole pitch. In React or Vue, the framework ships to the browser and does its diffing work at runtime. Svelte moves that work to build time, so the JavaScript that reaches your visitor is smaller and the page starts faster. Whether that trade-off matters for your project depends on what you build — but it is the reason developers who try Svelte tend to describe it as "the code does exactly what it looks like."

One thing to get right from the start — and the reason this SvelteKit for beginners guide exists: Svelte 5 (the current major line, which SvelteKit 2 pairs with) rewrote Svelte's reactivity as runes — $state, $props, and $derived. Many older guides still teach the pre-5 syntax ($: reactive statements, export let props, on:click handlers, <slot /> in layouts). Those patterns either warn or fail in a new project, which is exactly why this SvelteKit tutorial teaches only the current syntax, verified against Svelte's own docs.

How do you create your first SvelteKit project?

You create a SvelteKit project with the sv CLI — one command, a few prompts, and you have a running app. Open a terminal and run:

npx sv create my-app
cd my-app
npm install
npm run dev

The first command scaffolds the project in a my-app directory and asks a short series of questions: which template you want (SvelteKit minimal for a blank start, a demo app, or a library), whether to add TypeScript, which extra tooling to include, and which package manager to install dependencies with. For your first project, choose the minimal template, say yes to TypeScript if you are comfortable with types (saying no is fine too — the guide below shows the plain-JavaScript form), skip the extras, and accept npm.

npm run dev starts the development server on localhost:5173. Open that URL and you see the welcome page. Edit src/routes/+page.svelte, save, and the browser updates instantly — that feedback loop is where you will spend the whole tutorial.

Your new project has a small, predictable shape worth learning by heart:

my-app/
  src/
    routes/
      +page.svelte        ← the / route
    app.html              ← the HTML shell
    lib/                  ← shared components and helpers
  static/                 ← files served as-is (favicon, robots.txt)
  package.json
  svelte.config.js
  vite.config.js          ← where the adapter is registered

Almost everything you write lives under src/routes. The + prefix marks special files SvelteKit understands, and the directory tree is your URL tree — which brings us to routing.

How does SvelteKit file-based routing work?

SvelteKit routing works by mapping directories to URLs: every +page.svelte file inside src/routes becomes a page, and the folders around it define the path. There is no routes array, no config object, no <Router> component — a trap several stale guides still teach, but SvelteKit never had one.

Three files, three pages:

src/routes/+page.svelte          →  /
src/routes/about/+page.svelte    →  /about
src/routes/blog/+page.svelte     →  /blog

A minimal page is just markup:

<!-- src/routes/about/+page.svelte -->
<h1>About this site</h1>
<p>Built with SvelteKit.</p>
<a href="/">Home</a>

Navigate between routes with plain <a> elements — SvelteKit intercepts the clicks and does client-side navigation for you. A framework-specific <Link> component does not exist here, and importing one is a sign you are reading a React guide by mistake.

Dynamic segments use square brackets. src/routes/blog/[slug]/+page.svelte matches /blog/hello-world, /blog/my-post, and any other slug — the value arrives in your load function as params.slug, covered in the data-loading section below. That one pattern (a folder named [slug] containing a +page.svelte) is how blog posts, product pages, and user profiles are built in SvelteKit.

How do SvelteKit layouts work?

SvelteKit layouts keep the parts of your app that appear on every page — the navigation bar, the footer, the sidebar — in one file instead of repeating them. Create src/routes/+layout.svelte and it wraps every page in your app:

<!-- src/routes/+layout.svelte -->
<script>
  let { children } = $props();
</script>

<nav>
  <a href="/">Home</a>
  <a href="/about">About</a>
  <a href="/blog">Blog</a>
</nav>

{@render children()}

The only requirement is the {@render children()} tag — that is where the current page's content is rendered. Note the syntax: Svelte 5 layouts receive children as a prop through $props() and render it with {@render children()}. The old <slot /> element belongs to Svelte 4 and does not work in runes mode.

Layouts nest. A file at src/routes/settings/+layout.svelte wraps only the pages under /settings (inheriting the root layout above it), so /settings/profile and /settings/notifications can share a submenu while the rest of the site keeps the top nav. When you navigate between pages that share a layout, SvelteKit keeps the common components alive and only swaps the page — which is why the nav never flashes or re-renders on navigation.

How do you write a Svelte 5 component with runes?

Before data loading makes sense, you need Svelte 5's reactivity model — the three runes that replace everything older tutorials taught. A rune looks like a function with a $ prefix, and each one has exactly one job:

<script>
  // $state — reactive state. Reassign it and the UI updates.
  let count = $state(0);

  // $derived — a value computed from state. Updates automatically.
  let doubled = $derived(count * 2);

  // $props — values passed in from a parent component.
  let { name } = $props();
</script>

<h1>Hello {name}!</h1>
<button onclick={() => count++}>
  Clicked {count} times (doubled: {doubled})
</button>

Three things to notice. First, count is just a number — you write count++, not setCount(count + 1) and not count.set(...). Second, events are plain attributes now: onclick, not on:click. Third, props come from $props() destructuring, not export let. If a guide shows you $: labels, on:click, or export let data, it is teaching Svelte 4 against a Svelte 5 project — close the tab.

What are SvelteKit load functions?

A SvelteKit load function fetches the data a page needs before it renders, and its return value arrives in the page as the data prop. The file it lives in decides where it runs — and that choice is the single most important concept in SvelteKit data loading.

A universal load function lives in +page.js next to the page. It runs on the server during the first visit (server-side rendering) and in the browser during client-side navigation. Use it for public API calls that need no secrets:

// src/routes/blog/[slug]/+page.js
export function load({ params }) {
  return {
    slug: params.slug
    // fetch from a public API here — no API keys
  };
}

A server load function lives in +page.server.js. It always runs on the server, so it can touch a database, read files, or use private environment variables that must never reach the browser:

// src/routes/blog/[slug]/+page.server.js
import * as db from '$lib/server/database.js';

export async function load({ params }) {
  const post = await db.getPost(params.slug);
  return { post };
}

The page reads whatever load returned through the data prop:

<!-- src/routes/blog/[slug]/+page.svelte -->
<script>
  let { data } = $props();
</script>

<h1>{data.post.title}</h1>
<div>{@html data.post.content}</div>

Two rules keep beginners out of trouble. First, a server load can only return data that survives a trip over the network (JSON plus Date, Map, Set and friends — SvelteKit serializes with the devalue library), so never return a database connection or a class instance from it. Second, put secrets only in +page.server.js: anything returned from a universal +page.js load is visible in the browser by design. Layouts get the same treatment — +layout.js and +layout.server.js load data for every page beneath them, which is how a sidebar list or a logged-in user object reaches all pages at once.

How do SvelteKit form actions work?

SvelteKit form actions let a plain HTML form write data to your server with no JavaScript at all. You export an actions object from +page.server.js, point a <form method="POST"> at the page, and SvelteKit routes the submission to your code. This is the feature that makes SvelteKit feel different from a React SPA: mutations are a server concern with a built-in pattern, not a fetch call you wire up yourself.

The simplest case is a default action. Here is a newsletter signup — the form, then the server code that receives it:

<!-- src/routes/newsletter/+page.svelte -->
<form method="POST">
  <label>
    Email
    <input name="email" type="email" required />
  </label>
  <button>Subscribe</button>
</form>
// src/routes/newsletter/+page.server.js
export const actions = {
  default: async ({ request }) => {
    const data = await request.formData();
    const email = data.get('email');
    // TODO: save the email to your database
    return { success: true };
  }
};

After the action runs, the page re-renders and the action's return value is available as the form prop — so let { form } = $props() followed by {#if form?.success}<p>Subscribed!</p>{/if} shows a confirmation. A page can also declare named actions (login, register) and target them with <form method="POST" action="?/register"> or a <button formaction="?/register"> inside a shared form.

Validation uses the fail helper from @sveltejs/kit: return fail(400, { email, missing: true }) sends the submitted values back with an HTTP 400 so the form can show "the email field is required" without losing what the user typed. Successful mutations usually end with redirect(303, '/welcome') instead of returning data. And when you want the slick no-reload feel, add use:enhance from $app/forms to the form — SvelteKit progressively enhances the submission with JavaScript while the plain-POST version keeps working for everyone else.

How do you add an API route in SvelteKit?

Sometimes a page is not what you need — you need a raw endpoint. A +server.js file creates one: export functions named after HTTP verbs and return a Response. This is how you build the JSON APIs your load functions, your forms, or third-party webhooks talk to.

// src/routes/api/random-number/+server.js
import { json } from '@sveltejs/kit';

export function GET() {
  return json({ number: Math.floor(Math.random() * 100) });
}

export async function POST({ request }) {
  const body = await request.json();
  // TODO: do something with body
  return json({ received: true });
}

That file serves /api/random-number for GET and POST requests — PATCH, PUT, DELETE and the rest work the same way. One practical note from the docs: +server.js files never run in the browser, so they are a safe home for secret keys, exactly like +page.server.js.

SvelteKit vs Next.js: which should you learn?

SvelteKit vs Next.js is really a question about which UI library you want to live in. Next.js is the full-stack framework for React; SvelteKit is the full-stack framework for Svelte. The frameworks mirror each other on purpose — file-based routing, server components versus load functions, server actions versus form actions — because they solve the same problems for different ecosystems.

The honest differences come down to three things. First, the component model: Svelte compiles away the framework, so you write count++ instead of setCount and there is no virtual DOM reconciling your updates at runtime. Second, the learning surface: Svelte's runes are three concepts ($state, $props, $derived); React's hooks number in the dozens with rules about where they can be called. Third, the ecosystem: React and Next.js have the larger job market, the deeper library catalog, and the longer track record — a real factor if you are learning for employment in 2026.

A practical rule: if you already know React, Next.js gets you productive fastest. If you are starting fresh and want the gentlest path to a real full-stack app — or you simply prefer code that reads like the HTML, CSS, and JavaScript you already know — SvelteKit is the easier first framework, and everything in this guide is the complete beginner path for it.

How do you deploy a SvelteKit app?

You deploy a SvelteKit app by choosing an adapter — a small plugin that converts the built app into the format your host expects. This SvelteKit deploy walkthrough covers the adapter choice and both deployment paths beginners actually use. SvelteKit projects start with adapter-auto, which detects Vercel, Netlify, or Cloudflare Pages and does the right thing with zero configuration. For anything else, install the adapter for your target:

npx sv add sveltekit-adapter

That command installs the adapter package and registers it in vite.config.js for you. The official adapters cover every common target:

AdapterDeploy targetBest for
@sveltejs/adapter-vercelVercelZero-config deploys straight from a Git repo
@sveltejs/adapter-netlifyNetlifySame git-push workflow on Netlify
@sveltejs/adapter-cloudflareCloudflare Workers / PagesEdge deployment with KV and Workers bindings
@sveltejs/adapter-nodeAny Node.js serverVPS or Docker self-hosting with full server features
@sveltejs/adapter-bunBun runtimeBun-based servers
@sveltejs/adapter-staticAny static hostBlogs and docs with no server features

Then build and ship:

npm run build

The build output depends on the adapter — a Node server bundle for adapter-node, a folder of static files for adapter-static. Two deployment paths cover nearly every beginner. Path one, the easy one: push your project to a Git repository and connect it to Vercel or Netlify, which builds and deploys on every push — if you have not used Git hosting yet, our GitHub beginner guide covers pushing your first repo. Path two, the self-hosted one: build with adapter-node, wrap the output in a container with our Docker beginner guide, and run it on your own machine — our what is VPS hosting guide explains the server side of that setup. Community adapters exist for other platforms beyond the official six, linked from SvelteKit's adapter docs.

What should you build next?

The fastest way to lock in SvelteKit is a second project that forces you to use the server features: a guestbook (one form action writing to a JSON file, one server load function reading it back), a tiny blog (the [slug] route pattern with markdown files on disk), or a link shortener (a +server.js endpoint plus a redirect in a load function). Each one exercises a different file in src/routes, and after three of them the mental model — files are routes, + files are behavior — stops feeling like magic.

From there, the official docs are the right next stop: the routing page for rest parameters and route groups, the hooks page for handle middleware, and the remote functions docs — the experimental successor to form actions that the Svelte team is steering new projects toward, while classic form actions keep working.

Sources

Facts in this guide were verified against these sources on 2026-10-30: the official SvelteKit docs — Creating a project (npx sv create, localhost:5173), Routing (filesystem routes, +page.svelte, [slug] params, +layout.svelte with {@render children()}, +server.js API routes), Loading data (universal vs server load functions, devalue serialization), Form actions (default and named actions, request.formData(), fail(), redirects), and Adapters (the six official adapters, npx sv add sveltekit-adapter) — plus the Svelte 5 runes and onclick event syntax confirmed in Flavio Copes' Working with events in Svelte (updated September 17, 2026) and the 2026 SvelteKit + shadcn-svelte beginner guide on zignuts.com (Node.js ^20.19.0 / ^22.13.0 / 24+ requirement).

Frequently asked questions

Is SvelteKit good for beginners?

Yes — it is one of the gentlest full-stack frameworks to start with. The routing is just files in folders, forms work without JavaScript, and Svelte 5's three runes are a smaller mental model than React's hooks. The main prerequisite is comfort with HTML, CSS, and JavaScript basics; the framework itself adds surprisingly little new vocabulary.

Do I need to learn Svelte before SvelteKit?

Not separately. SvelteKit's own docs say you can start with SvelteKit and pick up Svelte along the way, and this guide follows that path — the runes crash course above is enough Svelte for your first app. You will naturally learn more Svelte (components, snippets, effects) as your pages get more ambitious.

SvelteKit vs Next.js — which should I learn in 2026?

Learn Next.js if you are targeting React jobs, since React still has the larger hiring market and library ecosystem. Learn SvelteKit if you want the fastest path from "I know JavaScript" to a deployed full-stack app, or if you prefer Svelte's compiler model where components are just HTML, CSS, and JavaScript with runes. The frameworks solve the same problems; the difference is the UI library underneath.

Can SvelteKit build a static site?

Yes, with @sveltejs/adapter-static. It prerenders every route to plain HTML, CSS, and JavaScript at build time, which you can host on any static host. The trade-off is that server-only features — server load functions, form actions, API routes — do not work in a fully static build, so it fits blogs and documentation sites better than apps with logins or databases.

What is a SvelteKit adapter, and which one should I choose?

An adapter is a plugin that converts your built SvelteKit app into the format a host expects — a Node server, serverless functions, edge workers, or static files. Start with adapter-auto (the default): it detects Vercel, Netlify, and Cloudflare Pages automatically. Choose adapter-node for your own server or Docker, adapter-static for static hosting, and the platform adapters when you deploy to that platform's dashboard.

Featured on Twelve Tools Launch Llama Tools Launch your MCP