Learn Svelte in less than five minutes

Svelte is so easy, you already know it. Just open your terminal and type npm create vite then choose svelte. After installing dependencies start local development server, that’s all.

Or just visit https://svelte.dev/playground and start writing svelte code without installing anything. Let’s get started.

Writing HTML and CSS

As I said, you already know svelte. Create a .svelte file and write your html and it will be rendered.

<h1>Hello World!</h1>

Once you want to style it, just create a style element and write your styles. By default all styles are scoped to that file, and if you want to write global styles you have to use :global selector.

<h1>Hello World!</h1>

<style>
  h1 {
    font-family: 'Roboto';
    color: orangered;
  }

  :global(main) {
    background-color: white;
  }
</style>

Reactivity

This is one of the best things in svelte, In Svelte 5, the framework introduced runes. In this simple tutorial we will focus on $state, $derived, and $effect runes.

To add interactivity to svelte, you have to use script tag and write your normal JS or TS.

<script>
  let count = $state(0);
  const double = $derived(count * 2);
</script>

<h1>Counter: {count}</h1>
<h2>Double: {double}</h2>

<button onclick={() => count++}>Increment</button>

The $effect rune

In the previous example I didn’t use $effect rune because I don’t need it, and from svelte documentation: they said that we should try to avoid using it. Here is an example that shows where we would need it.

<script>
  let color = $state('white');

  $effect(() => {
    document.body.style.background = color;
  })
</script>

<input type="color" bind:value={color}>

We should have used $derived rune but when you try to use it, you will get an error: $derived(...) can only be used as a variable declaration initializer, a class field declaration, or the first assignment to a class field at the top level of the constructor.

Reactivity outside of .svelte files

If you want to use state or reactive variable across different components you can create a .svelte.js or .svelte.ts file and you can use runes inside that file.

// counter.svelte.js

class Counter {
	#initialValue;
	
  constructor(initialValue) {
    this.#initialValue = initialValue;

    this.value = $state(initialValue);
    this.double = $derived(this.value * 2);
  }

  increment() {
    this.value++;
  }

  reset() {
    this.value = this.#initialValue;
  }
}

export const counter = new Counter(7);
<script>
  import {counter} from './counter.svelte.js';
</script>

<h1>Counter: {counter.value}</h1>
<h2>Double: {counter.double}</h2>
<script>
  import {counter} from './counter.svelte.js';
</script>

<button onclick={() => counter.increment()}>Increment</button>
<button onclick={() => counter.reset()}>Reset</button>

Snippets

In svelte you can have only one component per file, but sometimes we need to create components without creating more files, by using snippets this problem is solved.

<nav>
  {@render link('/', 'Home')}
  {@render link('/about', 'About us')}
  {@render link('/contact', 'Contact us')}
</nav>

{#snippet link(href, text)}
  <a {href} class="some-classes">{text}</a>
{/snippet}

Control flow

Svelte has it’s own syntax to render content conditionally or to loop over arrays.

Conditional rendering

<script>
  const num = 10;
</script>

{#if !(num % 2)}
  <p>{num} is even number</p>
{/if}

{#if new Date().getHours() < 12}
  <p>Good morning</p>
{:else}
  <p>Good evening</p>
{/if}

Looping

<script>
  const numbers = [15, 90, 35];
</script>

{#each numbers as number, index}
  <p>numbers[{index}] = {number}</p>
{:else}
  <p>You have no numbers</p>
{/each}

Props

If you have a reusable component, it may need props to render or do different actions according to those props.

<!-- Car.svelte -->

<script>
  const {color} = $props();
</script>

<h1>I am a {color} car!</h1>
<script>
  import Car from './Car.svelte';
</script>

<Car color="black" />

children prop

In Svelte children prop is a special prop which is used to pass slot to a child component, but you can pass more named slots using snippets.

<!-- Link.svelte -->

<script>
  const {children, href, text} = $props()
</script>

<a {href}>
  {@render children?.()} {text}
</a>
<script>
  import Link from './Link.svelte';

  const links = [
    {href: '/', text: 'Home', icon: '🛖'},
    {href: '/contact', text: 'Contact us', icon: '☎️'},
    {href: '/search', text: 'Search'},
  ];
</script>

{#each links as {href, text, icon}}
  <Link {href} {text}>
    {icon}
  </Link>
{/each}

Context

When your project grows, you might find your self passing props to components which are not even using them or modifying them. That’s when you will use context, by using context you set a value to a parent component and child component will be able to access it.

// context.js

import {createContext} from 'svelte';
export const [getName, setName] = createContext();
<!-- FavoriteFramework.svelte -->

<script>
  import {getName} from './context.js';
  const name = getName();
</script>

<p>My favorite framework is {name}</p>
<script>
  import {setName} from './context.js';
  import FavoriteFramework from './FavoriteFramework.svelte';

  setName('Svelte');
</script>

<FavoriteFramework />

I hope you fall in love with svelte, if you want to read more and learn svelte/svelte-kit you can use the following links they are more helpful: