Skip to main content
Svelte & SvelteKit·Lesson 1 of 5

Svelte Basics

Svelte is a JavaScript framework with a twist: it runs at build time, not in the browser. Instead of shipping a virtual DOM runtime, Svelte compiles your components into tiny, direct DOM manipulation code. The result is smaller bundles, faster runtime performance, and less boilerplate.

No Virtual DOM

React and Vue ship a runtime that reconciles a virtual DOM against the real DOM. Svelte skips that entirely:

React/Vue:  Component  Virtual DOM  Reconciler  Real DOM
Svelte:     Component  Compiled JS  Real DOM

The compiled output directly updates element.textContent, classList.add(), etc. — exactly what you'd write by hand.

Your First Component

A Svelte component is a .svelte file with three optional sections:

<script>
  let count = 0;

  function increment() {
    count += 1;
  }
</script>

<style>
  button { padding: 0.5rem 1rem; background: #ff3e00; color: white; border: none; cursor: pointer; }
  p      { font-size: 1.25rem; }
</style>

<p>Count: {count}</p>
<button on:click={increment}>+1</button>

That's it. No imports, no useState, no JSX. count is a reactive variable — whenever it changes, Svelte updates the DOM automatically.

Reactivity

Svelte tracks assignments. Any = to a declared variable triggers a UI update:

<script>
  let name  = 'World';
  let items = [];

  function addItem() {
    items = [...items, `Item ${items.length + 1}`];  // assignment triggers update
  }
</script>

<input bind:value={name} placeholder="Your name">
<p>Hello, {name}!</p>

<button on:click={addItem}>Add</button>
<ul>
  {#each items as item}
    <li>{item}</li>
  {/each}
</ul>

Note the items = [...items, ...] pattern — you must reassign to trigger reactivity. items.push(...) alone won't update the UI.

Reactive Declarations

$: marks a reactive statement that re-runs whenever its dependencies change:

<script>
  let width  = 4;
  let height = 3;

  $: area      = width * height;          // reactive variable
  $: doubled   = area * 2;
  $: if (area > 20) console.log('Big!');  // reactive side effect
</script>

<input type="number" bind:value={width}>
<input type="number" bind:value={height}>
<p>Area: {area}</p>
<p>Doubled: {doubled}</p>

Try It in the Playground

The output of a Svelte component is plain HTML, CSS, and JS — here's the equivalent browser code:

Ctrl+Enter
HTML
CSS
JS
Preview

Props

Pass data into a component with export let:

<!-- Greeting.svelte -->
<script>
  export let name = 'stranger';  // default value
</script>

<p>Hello, {name}!</p>

Use it:

<Greeting name="Sabaoon" />
<Greeting />  <!-- uses default: "stranger" -->

Lifecycle

<script>
  import { onMount, onDestroy } from 'svelte';

  let interval;

  onMount(() => {
    interval = setInterval(() => console.log('tick'), 1000);
  });

  onDestroy(() => {
    clearInterval(interval);
  });
</script>

onMount runs after the component is first rendered to the DOM (client-side only — important for SSR). onDestroy cleans up when the component is removed.