FIELD GUIDE 39Web and app platforms

sveltejs / svelte

Svelte 5 makes reactivity explicit while keeping components close to the web

Svelte compiles declarative components made from HTML, CSS, and JavaScript into targeted browser code. Version 5's runes make state, derivation, effects, and props explicit and reusable beyond component top level, while a compatibility path lets established Svelte 4 syntax coexist during migration.

WHAT TO KNOW FIRST

  1. Svelte is the component compiler; SvelteKit is the companion application framework for routing, data loading, server code, and deployment.
  2. Svelte 5 runes make reactive state and derivation explicit and usable in .svelte.js or .svelte.ts modules, not only component top level.
  3. Legacy Svelte 4 syntax remains supported during migration, but mixing models indefinitely can make shared code and review harder to reason about.

01A compiler at the center of the component model

The official documentation defines Svelte as a framework for building web interfaces that uses a compiler to turn declarative components into lean JavaScript. A .svelte file brings script, markup, and style into one component boundary. The compiler can understand which values affect which output and generate targeted updates. Developers still use ordinary browser elements, events, CSS, and JavaScript expressions rather than constructing a separate virtual interface tree by hand.

Compilation does not mean there is no runtime or that every Svelte application is automatically small. Client code, dependencies, hydration, data, and third-party scripts still reach the browser according to what the product uses. The useful distinction is that the compiler has more information before runtime and can transform Svelte-specific syntax ahead of time. Teams should measure the production bundle and interaction cost of their own components instead of using framework architecture as a performance result.

02Svelte and SvelteKit own different layers

The sveltejs/svelte repository contains the component compiler and runtime. SvelteKit is the companion application framework for routes, layouts, server data loading, form actions, endpoints, navigation, rendering choices, and deployment adapters. A standalone Svelte component can power a widget or fit into another build system. A new full web product normally needs the application layer as well. Evaluating only the Svelte repository leaves routing and server behavior unanswered.

This separation is healthy when teams state it clearly. Component decisions belong to Svelte: props, state, template structure, transitions, and styles. Request authorization, route data, cache policy, secrets, redirects, and deployment belong to SvelteKit or the surrounding host. A component may render protected data, but hiding a button is never authorization. Keep server-only modules out of client import paths and test the framework boundary on the actual adapter the application will run.

03Runes make reactive intent explicit

Svelte 5 introduced runes, compiler instructions whose names begin with a dollar sign. $state creates reactive state, $derived expresses a value computed from reactive inputs, $effect synchronizes with an external system, and $props receives component inputs. Unlike the implicit top-level reactivity of earlier Svelte, runes can also work in .svelte.js and .svelte.ts modules. That makes reusable reactive logic possible without switching to a separate store model solely because code moved outside a component.

The explicit vocabulary helps review. A derived value is visibly different from a side effect, and props are destructured through an ordinary-looking boundary. State values are read and assigned directly rather than through a universal wrapper property. The compiler tracks dependencies used during execution. This power still needs restraint. Use $derived for calculations and reserve $effect for external synchronization. Copying one rune value into another through an effect recreates the same duplicate-state problems found in other frameworks.

04Components communicate through props and callbacks

With modern syntax, a component receives values through $props and can type the destructured shape in TypeScript. Callback props provide a direct way for a child to report events upward. Bindable props exist for intentional two-way bindings, but they should be rare enough that ownership remains obvious. DOM event handlers are properties such as onclick in runes mode, aligning component syntax more closely with JavaScript objects.

Snippets and render tags replace many uses of slots with reusable template fragments that can receive parameters. They are useful for list rows, table cells, and component regions whose markup belongs to the caller. A component API can still become too clever. Prefer a small prop and callback surface before exposing many bindable values or nested snippets. The question is the same as for any module: which part owns the state, and which variation is a supported contract rather than an accidental opening.

  • Type public props and callback signatures where components cross package or team boundaries.
  • Use stable keys for lists whose items can be inserted, removed, or reordered.
  • Reserve two-way binding for values with clear shared ownership rather than convenience alone.

05Templates and scoped styles keep the web visible

Svelte templates provide if, each, await, key, and snippet blocks around recognizable HTML. Attributes, classes, styles, actions, transitions, and event properties remain attached to the elements they affect. Component styles are scoped by default, reducing accidental leakage while preserving ordinary CSS. Global selectors are available when a reset or third-party surface truly needs them. This local arrangement makes a component's rendered states easier to review in one file.

Svelte's compiler reports accessibility warnings for several markup patterns, but semantic design remains a human responsibility. A clickable div is still weaker than a button, heading order still matters, and animated transitions need reduced-motion consideration. Scoped CSS can also hide specificity and inheritance decisions if every fix reaches for a global escape. Start with native elements and resilient layout, test long and translated content, and use the browser's accessibility tree rather than assuming the compiler has certified the result.

06Effects, stores, and shared state need boundaries

An effect reruns when the reactive values it reads change and can return cleanup for subscriptions or resources. It is appropriate for a browser API, an imperative chart, or another system that Svelte does not own. It is not the first choice for deriving data or handling a click whose event is already available. Effects do not run during server rendering, which matters when a page relies on their output for initial content.

Svelte stores remain supported and useful for observable values, interoperability, or established libraries. Runes allow much shared reactive logic to live in ordinary modules, so new code should choose based on ownership rather than habit. Server applications must also avoid global mutable state that can leak across requests or users. Put request-specific data in the framework's request and load flow, and keep long-lived client state limited to information that genuinely survives navigation.

07Testing should cover compiled behavior and real routes

The official testing guidance points to unit and component tools for Svelte code and browser testing for complete applications. Pure functions and server logic can be tested without rendering. Component tests should query accessible output, perform user actions, and assert visible results. Browser tests cover routing, hydration, focus, cookies, forms, and network integration that an isolated component cannot reproduce.

Avoid asserting compiler-generated class names or internal state because those details can change while behavior remains correct. Test pending and rejected await blocks, component boundaries, keyboard paths, and cleanup after unmount. Server-rendered applications also need hydration tests because HTML may look correct before the client attaches. A production build is part of validation: development compilation, warnings, source maps, and timing differ from the artifact deployed to users.

08The Svelte 5 migration is intentionally gradual

The migration guide says Svelte 5 continues to support Svelte 4 syntax and allows old and new components to coexist. It documents changes from reactive let declarations to $state, $: statements to $derived or $effect, export let to $props, event directives to event properties, slots to snippets, and class-based component APIs to functions. An official migration script can automate many mechanical steps, but not every design decision.

Upgrade the runtime and framework on a branch, run the migration against a focused area, and review reactive intent rather than accepting transformed text blindly. Third-party components may remain in legacy mode without blocking modern application code. The MIT-licensed repository is a strong choice when its concise component model fits the team, but documentation examples now span two eras. Name the syntax expected in new files and give migration a finish condition so the codebase does not preserve two teaching models forever.

A SENSIBLE FIRST HOUR

Start small enough to learn the repo

  1. Use the official Svelte CLI and choose SvelteKit for a new application, or open the official playground for a contained component experiment.
  2. Build one component with typed props, $state, $derived, an event callback, an each block with stable keys, and scoped styles.
  3. Add one test for user-visible behavior, then verify focus, keyboard operation, loading, empty, and error states in the real application route.
  4. Run the production build, inspect client output and hydration, and read the Svelte 5 migration guide before bringing in legacy components or tutorials.

SOURCE LEDGER

What this review is built on

We use the project repository and first-party documentation. Access, licenses and project direction can change, so recheck the linked source before making a production decision.

  1. Svelte repositoryrepository
  2. Svelte overviewdocumentation
  3. Svelte runes guidedocumentation
  4. Svelte 5 migration guidedocumentation
  5. Svelte releasesrelease
  6. Svelte licenselicense