Skip to main content

What is Svelte?

Svelte occupies a unique position among JavaScript frameworks. While React and Vue work as runtime libraries, Svelte works as a compiler. It converts components to pure JavaScript at build time, so no extra framework code needs to be shipped to the browser. Svelte’s biggest characteristic is that it doesn’t use a Virtual DOM. When state changes, code Svelte generated at compile time directly updates the DOM. This yields extremely lightweight and fast UIs.
This page describes the combination of Svelte 5 and Inertia v3. The Laravel 13 starter kit uses this stack by default.

Svelte 5 runes

Svelte 5 (released 2024) introduced a new reactivity system called Runes. You declare reactive state using special functions (runes) like $state, $derived, and $effect. Unlike the implicit reactivity of Svelte 4 and earlier, the design is explicit and predictable.
Laravel’s Svelte starter kit uses Svelte 5 + TypeScript as the standard. All examples on this page are written in TypeScript (lang="ts").

Svelte’s position in Laravel

History

Svelte’s relationship with Laravel is much newer than Vue’s or React’s; the first official support is starter kit adoption. With Laravel 13 in 2026, Svelte was officially added to the starter kits, making Svelte an official frontend option in the Laravel ecosystem. It’s treated as equal to Vue and React and is selectable in the laravel new interactive prompt. Svelte is still relatively unknown to many Laravel users, but its compiler-driven small bundles and simple syntax stand out—users switching from Vue or React are often surprised by how little they need to write.

The current mainstream style: Inertia × Svelte

The center of gravity for Svelte in Laravel today is Inertia × Svelte. Inertia enables a “modern monolith” architecture where data flows from Laravel controllers directly to Svelte components without designing an API.

Setup

For new projects, using a starter kit is the easiest way.
Choosing Svelte in the interactive prompt sets up all of the following automatically:
  • inertiajs/inertia-laravel (server-side adapter)
  • @inertiajs/svelte (client adapter)
  • svelte + @sveltejs/vite-plugin-svelte (Svelte 5 itself and the Vite plugin)
  • TypeScript + svelte-check
  • Tailwind CSS + the shadcn-svelte component library
  • The HandleInertiaRequests middleware
  • Auth screens like login and registration (already implemented in Inertia + Svelte + TypeScript)

Manual installation

To add it to an existing project, install the server-side and client-side pieces separately.
Next, add the Svelte plugin and the Inertia Vite plugin to vite.config.ts.
Start the Inertia app from resources/js/app.ts. The @inertiajs/vite plugin handles page auto-resolution and mounting, so only a minimal entry point is needed.
For manual installation details (root template configuration, middleware registration, etc.), see the Inertia official docs.

Directory structure

In the starter kits, Svelte page components live in the resources/js/pages/ directory.
Writing Inertia::render('posts/Index', [...]) maps to the component at resources/js/pages/posts/Index.svelte.

Basic structure of a Svelte file

A .svelte file consists of three blocks: <script>, template, and <style>.
The structure resembles Vue’s Single File Components (SFCs), but there’s less markup and script to write. Because <style> is scoped by default, you don’t need to worry about class name collisions.

Template syntax

Variable interpolation and expressions

Inside the template, use {} to embed JavaScript values and expressions.

{#if} — conditionals

Equivalent to Vue’s v-if / v-else or React’s ternary operator.

{#each} — list rendering

(post.id) specifies the key, used for efficient diffing. Equivalent to Vue’s v-for or React’s Array.map().

bind: — two-way binding

Use bind:value to two-way sync a form element’s value with a reactive variable.
Equivalent to Vue’s v-model. React requires you to hand-wire onChange handlers, but Svelte lets you write this declaratively with bind:.

Page component basics

Inertia page components are ordinary Svelte components. Data passed from a Laravel controller arrives as props.

Controller

Svelte page component

In Svelte 5, use the $props() rune to receive props.
Just receive props with $props() and use them in the template. No REST API definition needed.
The <Link> component from @inertiajs/svelte routes page transitions via XHR, avoiding a full browser reload.
You write it like a normal <a> tag, but Inertia swaps only the page component behind the scenes, giving you an SPA-like feel.

The Form component

The <Form> component from @inertiajs/svelte is the recommended form submission style used in the starter kit auth screens. Specify action and method as props and write the interior with a {#snippet}.

Basic usage

{#snippet children({ errors, processing })} is Svelte’s snippet syntax—a content block passed to a component (equivalent to Vue slots or React render props). errors and processing are computed and provided automatically by the Form component. Form fields use HTML-native name attributes rather than bind:value, and the browser’s standard form data collection does the work.

Starter kit pattern

The starter kit uses Wayfinder to manage routes as objects. store.form() returns an object containing the route object’s action and method, which is spread onto <Form>.
Fields listed in resetOnSuccess are automatically reset on successful submission. Use it for fields like password fields that should be cleared after submit.
Without Wayfinder, pass the URL directly like action="/login" and it behaves the same.

The useForm hook

For form handling, use @inertiajs/svelte’s useForm hook. It cleanly implements form state management, submission, and validation error display.

Controller side

Svelte form component

Here are the main properties on the object returned by useForm. When validation errors are returned, useForm displays them while preserving the input values. Combined with bind:value, it delivers a seamless form experience.

Shared data

Data needed on every page (the logged-in user, flash messages, etc.) is defined in the share() method of the HandleInertiaRequests middleware.
Use usePage() to access shared data from a Svelte component.
Because shared data is included on every request, keep it to the minimum needed. Wrapping in fn() for lazy evaluation ensures it’s only evaluated when actually accessed.

Svelte 5 reactivity (runes)

Here are the Svelte 5 runes to know when developing with Inertia × Svelte.

$state — reactive state

Variables declared with $state become automatically reactive. When the value changes, the DOM updates automatically. It corresponds to Vue’s ref or React’s useState, but you don’t need .value—just assign to update state.

$derived — derived values

$derived automatically recomputes when its dependencies change. Corresponds to Vue’s computed or React’s useMemo.

$effect — side effects

$effect runs each time a $state dependency changes. It corresponds to React’s useEffect, but you don’t need to specify a dependency array—the $state variables used are tracked automatically.

shadcn-svelte components

The starter kit includes shadcn-svelte. shadcn-svelte is a component library with the same design philosophy as shadcn/ui for React—copy the code into your project and freely customize.

Adding a component

Running the command places the component source into resources/js/components/ui/.

Usage

The starter kit already includes commonly used components like Button, Input, Card, Dialog, and Dropdown. Add more as needed with npx shadcn-svelte@latest add.

Summary

Svelte shines when paired with Laravel, especially in a “modern monolith” configuration through Inertia. The compiler-based design keeps bundle sizes small, and the runes syntax makes reactivity explicit and easy to understand. Inertia × Svelte combines the simplicity of a Laravel backend with Svelte’s compact style, offering a great development experience. Creating a project from the starter kit gets you started immediately, auth screens included.

Inertia.js official docs

See the official documentation for all Inertia v3 features.
Last modified on July 13, 2026