SvelteJS cheatsheet for developers || All about SvelteJS

Svelte cheatsheet for developers

Doc examples

Table of Contents

  1. Structure
  2. Imports
  3. Variables
  4. Reactivity

    1. Variables
    2. Statements
    3. Updating objects
  5. Props
  6. Logic

    1. Conditions
    2. Loops
    3. Promises
  7. Events

    1. Event dispatcher
    2. Event forwarding
  8. Bindings
  9. Lifecycle
  10. Store

    1. Usage
    2. Readable store
    3. Writable store
    4. Derived store
    5. Custom store
  11. Motion

    1. Tweened
    2. Spring
  12. Transitions
  13. Dynamic classes
  14. Slots
  15. Contexts
  16. Debugging
  17. Integrations

    1. GraphQL integration

Your components are inside .svelte files.


Your component use few tags to be operating:

  • <script>
  • <style>

<script> will describe how to animate the component. <style> how to render it


You can include a component inside another one by importing it:

  import Nested from './Nested.svelte'



You can define variables in your <script> tag and then use it with brackets:

  let foo = "bar"

<p class={bar}>Some text</p>

Tip: It also works inside double-quotes: <p class="primary-{bar}">Some text</p>

Moreover, when var = attribute, (src={src}) you can use it this way: {src}.


Reactivity is triggered by assignments What does it mean? Every change will be triggered after an assignment has been done.

More on that later.


Sometimes a variable is result from a computation, you'll have to use a reactive declaration:

let count = 0;
$: doubled = count * 2;

We're not limited to variable declaration, we can also use reactive statements:

$: console.log(`the count is ${count}`);

Here console.log is called whenever count value changes. Notice the usage of ` (backquotes).

Tip: You can group more statements by using $: { ... }.

Updating objects

Because Svelte's reactivity is triggered by assignments following code won't do anything when called:

function addNumber() {
  numbers.push(numbers.length + 1);

Unless you add it this assignment:

function addNumber() {
  numbers.push(numbers.length + 1);
  numbers = numbers;


There's an easy way to pass props to a child component. Just export it !

// Nested.svelte
  export let answer = 42
<p>The answer is {answer}</p>

// App.svelte
  import Nested from './Nested.svelte'

<Nested/> // Will display: The answer is 42

Tip: You can also use <Nested answer={42}/> to set a default value to a prop that hasn't been initialized into it's own component.

When passing multiple props typically as an object of properties, you can spread them to a component instead of specifying each one with ...:

  import Info from './Info.svelte';

  const pkg = {
    name: 'svelte',
    version: 3,
    speed: 'blazing',
    website: ''

<Info name={} version={pkg.version} speed={pkg.speed} website={}/>
<Info {...pkg}/>

Assuming we have exported name, version, and so on in the Info component.



To conditionally render some markup, we wrap it in an if block:

{#if user.loggedIn}
  <button on:click={toggle}>
    Log out

{#if !user.loggedIn}
  <button on:click={toggle}>
    Log in

You can also make use of :

  • {:else}
  • {:else if .. }


Expressed this way:

{#each cats as cat, i}
  <li><a target="_blank" href="{}">
    {i}: {}

Tip: You can also de-structure as: {#each cats as { id, name }} and then use {name} instead of {}

When a value isn't exported but is computed by a prop, you can go into problems when updating values since it's a copy and not a reference. Thus, be sure to identify the right object when updating its value(s):

{#each cats as cat, i (cat)} // Notice the (cat)
  <li><a target="_blank" href="{}">
    {i}: {}


You can deal with promises and display at each of the promise lifecycle:

{#await promise}
{:then result}
  <p>It returns {result}</p>
{:catch error}
  <p>An error occurred: {error.message}</p>

Tip: You can also skip loading step by using: {#await promise then result}


You can bind functions / events to your tags:

  let count = 0;

  function handleClick() {
    count += 1;

<button on:click={handleClick}>
  Clicked {count} {count === 1 ? 'time' : 'times'}

You can use all javascript event (click, mousemove, ...). You can also modify event by piping modifiers to it: <button on:click|once={handleClick}> You can chain them by adding pipes.

Event dispatcher

You can create an event dispatcher inside a component. It must be called when component is first instantiated.

  import { createEventDispatcher } from 'svelte';

  const dispatch = createEventDispatcher();

  function sayHello() {
    dispatch('message', {
      text: 'Hello!'

On the other side:

  import Inner from './Inner.svelte';

  function handleMessage(event) {

<Inner on:message={handleMessage}/> // on:eventname

Event forwarding

You can handle events from any other component by calling them with their own event:

// Outer.svelte
  import Inner from './Inner.svelte';

<Inner on:message/>

Here we can intercept event message from Inner. Then, when called, we can define how the component reacts:

<Outer on:message={handleMessage}/>


Data flow is top down, that means a parent component can set props on a child component but not the other way around.

Bindings can break that rule:

  let name = 'world';

<input bind:value={name}>  // name and value are tied together, they are bind

<h1>Hello {name}!</h1>

You can also use a group of bindings:

  let flavourList = [
    'Cookies and cream',
    'Mint choc chip',
    'Raspberry ripple'


{#each flavourList as flavour}
    <input type=checkbox bind:group={flavourList} value={flavour}>


Is ruled by a bunch of functions:

  • onMount
  import { onMount } from 'svelte';

  let photos = [];

  onMount(async () => {
    const res = await fetch(``);
    photos = await res.json();
  • onDestroy
  • beforeUpdate
  • afterUpdate


A store is simply an object with a subscribe method that allows interested parties to be notified whenever the store value changes:

  let countValue;
  const unsubscribe = count.subscribe(value => {
    count_value = value;

<h1>The count is {count_value}</h1>

Then, you can update the stored value:

  function increment() {
    count.update(n => n + 1)

Or set a value:

  function reset() {

Best practice: Auto-subscription


You can use auto-subscription to get rid of subscribe and onDestroy methods:

  import { storeValue } from './AnotherComponent'
  // ...other imports come after

<h1>The count is {$storeValue}</h1>

Warning: The store value must be imported or declared at the top-level scope of a component !

Readable store

It's a read-only store.

  export const time = readable(new Date(), function start(set) {
    // Implementation

    return function stop() {
      // Implementation

The first argument can be null, it represents an initial value. You then have to define a set callback which is called when the store gets its first subscriber and a stop callback when the last subscriber unsubscribes.

Writable store

  import { writable } from 'svelte/store';

  const count = writable(0, () => {
    console.log('got a subscriber');
    return () => console.log('no more subscribers');

It can be altered with set and update. It can also be bind to a tag.

Derived store

...from another store.

  import { derived } from 'svelte/store';

  const delayed = derived(time, ($a, set) => {
    setTimeout(() => set($a), 1000);
  }, 'one moment...');

  // or (read-only derived):

  const elapsed = derived(time, $time =>
    Math.round(($time - start) / 1000)


First argument is the original store. Second one is facultative and added if you want to write on the store.

Custom store

// store.js

import { writable } from 'svelte/store';
function createCount() {
  const { subscribe, set, update } = writable(0);

  return {
    increment: () => update((n) => n + 1),
    decrement: () => update((n) => n - 1),
    reset: () => set(0),
export const count = createCount();

In the component:

  import { count } from './store.js';

<h1>The count is {$count}</h1>

<button on:click={count.increment}>+</button>
<button on:click={count.decrement}>-</button>
<button on:click={count.reset}>reset</button>


Stores are cool but you can make them even smoother by adding animation when transposed to UI.


It's usable like an ordinary store:

  import { tweened } from 'svelte/motion';
  import { cubicOut } from 'svelte/easing';

  const progress = tweened(0, {
      duration: 400,
      easing: cubicOut

<progress value={$progress}></progress>

<button on:click="{() => progress.set(0)}">0%</button>

Spring better with frequently changing value.

  import { spring } from 'svelte/motion';

  let coords = spring({ x: 50, y: 50 }, {
      stiffness: 0.1,
      damping: 0.25
  let size = spring(10);


There're a lot:

  • Fade in/out: transition:fade (ie: <p transition:fade>Some text</p>)
  • Fly (disappear in a given direction): transition:fly
  • ...

Dynamic classes

To affect a class to a tag dynamically when condition are met:

  class:active="{current === 'foo'}"

.active {
  background-color: #ff3e00;
  color: white;

Here we affect the class .active when condition is true.


Slots give you the opportunity to shape a component inside another one.

  import Box from './Box.svelte';

  <p>This is a box. It can contain anything.</p>

// Box.svelte
<div class="box">
  <slot>A default value here</slot>

Slots can be named:

  import ContactCard from './ContactCard.svelte';

  <span slot="name">T. Pellegatta</span>

// ContactCard.svelte
<article class="contact-card">
    <slot name="name">
      <span class="missing">Unknown name</span>    // Will display T. Pellegatta because it has been defined

  <div class="address">
    <slot name="address">
      <span class="missing">Unknown address</span>

You can pass props to slots:

<!-- App.svelte -->
<FancyList {items}>
  <div slot="item" let:item={item}>{item.text}</div>
  <p slot="footer">Copyright (c) 2019 Svelte Industries</p>

<!-- FancyList.svelte -->
  {#each items as item}
    <li class="fancy">
        <slot name="item" item={item}></slot>

<slot name="footer"></slot>

The let: directive goes on the element with the slot attribute.


Almost the same as stores but less reactive. Documentation


Instead of using debugger; use {@debug variable}


GraphQL integration

...with Apollo

You'll have to import some plugins:

  • apollo-boost
  • graphql
  • svelte-apollo

Then, in the main component instantiate a client:

  import ApolloClient from 'apollo-boost'
  import { setClient } from 'svelte-apollo'
  const client = new ApolloClient({
      uri: 'http://site/graphqlApi/endpoint'

In another one (or the same) use it to fetch/push data:

  import { getClient, query } from 'svelte-apollo'
  import { gql } from 'apollo-boost'

  const GET_TODOS = gql`
      getTodos {

  const client = getClient()
  const todos = query(client, { query: GET_TODOS })

{#await $todos}
{:then result}
  <p>Total todos: {}</p>
    {each as todo}
{:catch error}