Before we begin

Temporary note: This document is a work-in-progress. Please forgive any missing or misleading parts, and don't be shy about asking for help in the Discord chatroom. The tutorial is more complete; start there.

This page contains detailed API reference documentation. It's intended to be a resource for people who already have some familiarity with Svelte.

If that's not you (yet), you may prefer to visit the interactive tutorial or the examples before consulting this reference.

Component format

Components are the building blocks of Svelte applications. They are written into .svelte files, using a superset of HTML.

All three sections — script, styles and markup — are optional.

<script>
	// logic goes here
</script>

<style>
	/* styles go here */
</style>

<!-- markup (zero or more items) goes here -->

<script>

A <script> block contains JavaScript that runs when a component instance is created. Variables declared (or imported) at the top level are 'visible' from the component's markup. There are four additional rules:

1. export creates a component prop

Svelte uses the export keyword to mark a variable declaration as a property or prop, which means it becomes accessible to consumers of the component:

<script>
	// these properties can be set externally
	export let foo;
	export let bar = 'optional default value';

	// Values that are passed in as props
	// are immediately available
	console.log(foo, bar);

	// function declarations cannot be set externally,
	// but can be accessed from outside
	export function instanceMethod() {
		alert(foo);
	}
</script>

2. Assignments are 'reactive'

To change component state and trigger a re-render, just assign to a locally declared variable.

Update expressions (count += 1) and property assignments (obj.x = y) have the same effect.

<script>
	let count = 0;

	function handleClick () {
		// calling this function will trigger a re-render
		// if the markup references `count`
		count = count + 1;
	}
</script>

3. $: marks a statement as reactive

Any top-level statement (i.e. not inside a block or a function) can be made reactive by prefixing it with the $: label. Reactive statements run immediately before the component updates, whenever the values that they depend on have changed.

<script>
	export let title;

	// this will update `document.title` whenever
	// the `title` prop changes
	$: document.title = title;

	$: {
		console.log(`multiple statements can be combined`);
		console.log(`the current title is ${title}`);
	}
</script>

If a statement consists entirely of an assignment to an undeclared variable, Svelte will inject a let declaration on your behalf.

<script>
	export let num;

	// we don't need to declare `squared` and `cubed`
	// — Svelte does it for us
	$: squared = num * num;
	$: cubed = squared * num;
</script>

4. Prefix stores with $ to access their values

Any time you have a reference to a store, you can access its value inside a component by prefixing it with the $ character. This causes Svelte to declare the prefixed variable, and set up a store subscription that will be unsubscribed when appropriate.

Note that the store must be declared at the top level of the component — not inside an if block or a function, for example.

Local variables (that do not represent store values) must not have a $ prefix.

<script>
	import { writable } from 'svelte/store';

	const count = writable(0);
	console.log($count); // logs 0

	count.set(1);
	console.log($count); // logs 1
</script>

<script context="module">

A <script> tag with a context="module" attribute runs once when the module first evaluates, rather than for each component instance. Values declared in this block are accessible from a regular <script> (and the component markup) but not vice versa.

You can export bindings from this block, and they will become exports of the compiled module.

You cannot export default, since the default export is the component itself.

<script context="module">
	let totalComponents = 0;

	// this allows an importer to do e.g.
	// `import Example, { alertTotal } from './Example.svelte'`
	export function alertTotal() {
		alert(totalComponents);
	}
</script>

<script>
	totalComponents += 1;
	console.log(`total number of times this component has been created: ${totalComponents}`);
</script>

<style>

CSS inside a <style> block will be scoped to that component.

This works by adding a class to affected elements, which is based on a hash of the component styles (e.g. svelte-123xyz).

<style>
	p {
		/* this will only affect <p> elements in this component */
		color: burlywood;
	}
</style>

To apply styles to a selector globally, use the :global(...) modifier.

<style>
	:global(body) {
		/* this will apply to <body> */
		margin: 0;
	}

	div :global(strong) {
		/* this will apply to all <strong> elements, in any
			 component, that are inside <div> elements belonging
			 to this component */
		color: goldenrod;
	}
</style>

Template syntax

Tags

A lowercase tag, like <div>, denotes a regular HTML element. A capitalised tag, such as <Widget>, indicates a component.

<script>
	import Widget from './Widget.svelte';
</script>

<div>
	<Widget/>
</div>

Attributes

By default, attributes work exactly like their HTML counterparts.

<div class="foo">
	<button disabled>can't touch this</button>
</div>

As in HTML, values may be unquoted.

<input type=checkbox>

Attribute values can contain JavaScript expressions.

<a href="page/{p}">page {p}</a>

Or they can be JavaScript expressions.

<button disabled={!clickable}>...</button>

An expression might include characters that would cause syntax highlighting to fail in regular HTML, so quoting the value is permitted. The quotes do not affect how the value is parsed:

<button disabled="{number !== 42}">...</button>

When the attribute name and value match (name={name}), they can be replaced with {name}.

<!-- These are equivalent -->
<button disabled={disabled}>...</button>
<button {disabled}>...</button>

Spread attributes allow many attributes or properties to be passed to an element or component at once.

An element or component can have multiple spread attributes, interspersed with regular ones.

<Widget {...things}/>

Text expressions

  • {expression}

Text can also contain JavaScript expressions:

<h1>Hello {name}!</h1>
<p>{a} + {b} = {a + b}.</p>

HTML expressions

  • {@html expression}

In a text expression, characters like < and > are escaped. With HTML expressions, they're not.

Svelte does not sanitize expressions before injecting HTML. If the data comes from an untrusted source, you must sanitize it, or you are exposing your users to an XSS vulnerability.

<div class="blog-post">
	<h1>{post.title}</h1>
	{@html post.content}
</div>

If blocks

  • {#if expression}...{/if}
  • {#if expression}...{:else if expression}...{/if}
  • {#if expression}...{:else}...{/if}

Content that is conditionally rendered can be wrapped in an if block.

{#if answer === 42}
	<p>what was the question?</p>
{/if}

Additional conditions can be added with {:else if expression}, optionally ending in an {:else} clause.

{#if porridge.temperature > 100}
	<p>too hot!</p>
{:else if 80 > porridge.temperature}
	<p>too cold!</p>
{:else}
	<p>just right!</p>
{/if}

Each blocks

  • {#each expression as name}...{/each}
  • {#each expression as name, index}...{/each}
  • {#each expression as name, index (key)}...{/each}
  • {#each expression as name}...{:else}...{/each}

Iterating over lists of values can be done with an each block.

<h1>Shopping list</h1>
<ul>
	{#each items as item}
		<li>{item.name} x {item.qty}</li>
	{/each}
</ul>

An each block can also specify an index, equivalent to the second argument in an array.map(...) callback:

{#each items as item, i}
	<li>{i + 1}: {item.name} x {item.qty}</li>
{/each}

If a key expression is provided — which must uniquely identify each list item — Svelte will use it to diff the list when data changes, rather than adding or removing items at the end.

{#each items as item, i (item.id)}
	<li>{i + 1}: {item.name} x {item.qty}</li>
{/each}

You can freely use destructuring patterns in each blocks.

{#each items as { id, name, qty }, i (id)}
	<li>{i + 1}: {name} x {qty}</li>
{/each}

An each block can also have an {:else} clause, which is rendered if the list is empty.

{#each todos as todo}
	<p>{todo.text}</p>
{:else}
	<p>No tasks today!</p>
{/each}

Await blocks

  • {#await expression}...{:then name}...{:catch name}...{/await}
  • {#await expression}...{:then name}...{/await}
  • {#await expression then name}...{/await}

Await blocks allow you to branch on the three possible states of a Promise — pending, fulfilled or rejected.

{#await promise}
	<!-- promise is pending -->
	<p>waiting for the promise to resolve...</p>
{:then value}
	<!-- promise was fulfilled -->
	<p>The value is {value}</p>
{:catch error}
	<!-- promise was rejected -->
	<p>Something went wrong: {error.message}</p>
{/await}

The catch block can be omitted if you don't need to render anything when the promise rejects (or no error is possible).

{#await promise}
	<!-- promise is pending -->
	<p>waiting for the promise to resolve...</p>
{:then value}
	<!-- promise was fulfilled -->
	<p>The value is {value}</p>
{/await}

If you don't care about the pending state, you can also omit the initial block.

{#await promise then value}
	<p>The value is {value}</p>
{/await}

DOM events

  • on:eventname={handler}
  • on:eventname|modifiers={handler}

Use the on: directive to listen to DOM events.

<script>
	let count = 0;

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

<button on:click={handleClick}>
	count: {count}
</button>

Handlers can be declared inline with no performance penalty. As with attributes, directive values may be quoted for the sake of syntax highlighters.

<button on:click="{() => count += 1}">
	count: {count}
</button>

Add modifiers to DOM events with the | character.

The following modifiers are available:

  • preventDefault — calls event.preventDefault() before running the handler
  • stopPropagation — calls event.stopPropagation(), preventing the event reaching the next element
  • passive — improves scrolling performance on touch/wheel events (Svelte will add it automatically where it's safe to do so)
  • capture — fires the handler during the capture phase instead of the bubbling phase
  • once — remove the handler after the first time it runs

Modifiers can be chained together, e.g. on:click|once|capture={...}.

<form on:submit|preventDefault={handleSubmit}>
	<!-- the `submit` event's default is prevented,
		 so the page won't reload -->
</form>

If the on: directive is used without a value, the component will forward the event, meaning that a consumer of the component can listen for it.

<button on:click>
	The component itself will emit the click event
</button>

Component events

  • on:eventname={handler}

Components can emit events using createEventDispatcher, or by forwarding DOM events. Listening for component events looks the same as listening for DOM events:

<SomeComponent on:whatever={handler}/>

Element bindings

  • bind:property={value}

Data ordinarily flows down, from parent to child. The bind: directive allows data to flow the other way, from child to parent. Most bindings are specific to particular elements.

The simplest bindings reflect the value of a property, such as input.value.

<input bind:value={name}>
<textarea bind:value={text}></textarea>

<input type="checkbox" bind:checked={yes}>

If the name matches the value, you can use a shorthand.

<!-- These are equivalent -->
<input bind:value={value}>
<input bind:value>

Numeric input values are coerced; even though input.value is a string as far as the DOM is concerned, Svelte will treat it as a number. If the input is empty or invalid (in the case of type="number"), the value is undefined.

<input type="number" bind:value={num}>
<input type="range" bind:value={num}>

Inputs that work together can use bind:group.

<script>
	let tortilla = 'Plain';
	let fillings = [];
</script>

<!-- grouped radio inputs are mutually exclusive -->
<input type="radio" bind:group={tortilla} value="Plain">
<input type="radio" bind:group={tortilla} value="Whole wheat">
<input type="radio" bind:group={tortilla} value="Spinach">

<!-- grouped checkbox inputs populate an array -->
<input type="checkbox" bind:group={fillings} value="Rice">
<input type="checkbox" bind:group={fillings} value="Beans">
<input type="checkbox" bind:group={fillings} value="Cheese">
<input type="checkbox" bind:group={fillings} value="Guac (extra)">

A <select> value binding corresponds to the value property on the selected <option>, which can be any value (not just strings, as is normally the case in the DOM).

<select bind:value={selected}>
	<option value={a}>a</option>
	<option value={b}>b</option>
	<option value={c}>c</option>
</select>

A <select multiple> element behaves similarly to a checkbox group.

<select multiple bind:value={fillings}>
	<option value="Rice">Rice</option>
	<option value="Beans">Beans</option>
	<option value="Cheese">Cheese</option>
	<option value="Guac (extra)">Guac (extra)</option>
</select>

When the value of an <option> matches its text content, the attribute can be omitted.

<select multiple bind:value={fillings}>
	<option>Rice</option>
	<option>Beans</option>
	<option>Cheese</option>
	<option>Guac (extra)</option>
</select>

Media elements (<audio> and <video>) have their own set of bindings — four readonly ones...

  • duration (readonly) — the total duration of the video, in seconds
  • buffered (readonly) — an array of {start, end} objects
  • seekable (readonly) — ditto
  • played (readonly) — ditto

...and three two-way bindings:

  • currentTime — the current point in the video, in seconds
  • paused — this one should be self-explanatory
  • volume — a value between 0 and 1
<video
	src={clip}
	bind:duration
	bind:buffered
	bind:seekable
	bind:played
	bind:currentTime
	bind:paused
	bind:volume
></video>

Block-level elements have readonly clientWidth, clientHeight, offsetWidth and offsetHeight bindings, measured using a technique similar to this one.

<div bind:offsetWidth={width} bind:offsetHeight={height}>
	<Chart {width} {height}/>
</div>

To get a reference to a DOM node, use bind:this.

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

	let canvasElement;

	onMount(() => {
		const ctx = canvasElement.getContext('2d');
		drawStuff(ctx);
	});
</script>

<canvas bind:this={canvasElement}></canvas>

Component bindings

  • bind:property={value}

You can bind to component props using the same mechanism.

<Keypad bind:value={pin}/>

Components also support bind:this, allowing you to interact with component instances programmatically.

Note that we can do {cart.empty} rather than {() => cart.empty()}, since component methods are closures. You don't need to worry about the value of this when calling them.

<ShoppingCart bind:this={cart}/>

<button on:click={cart.empty}>
	Empty shopping cart
</button>

Classes

  • class:name={value}
  • class:name

A class: directive provides a shorter way of toggling a class on an element.

<!-- These are equivalent -->
<div class="{active ? 'active' : ''}">...</div>
<div class:active={active}>...</div>

<!-- Shorthand, for when name and value match -->
<div class:active>...</div>

Actions

  • use:action
  • use:action={parameters}
action = (node: HTMLElement, parameters: any) => {
	update?: (parameters: any) => void,
	destroy?: () => void
}

Actions are functions that are called when an element is created. They can return an object with a destroy method that is called after the element is unmounted:

<script>
	function foo(node) {
		// the node has been mounted in the DOM

		return {
			destroy() {
				// the node has been removed from the DOM
			}
		};
	}
</script>

<div use:foo></div>

An action can have parameters. If the returned value has an update method, it will be called whenever those parameters change, immediately after Svelte has applied updates to the markup.

Don't worry about the fact that we're redeclaring the foo function for every component instance — Svelte will hoist any functions that don't depend on local state out of the component definition.

<script>
	export let bar;

	function foo(node, bar) {
		// the node has been mounted in the DOM

		return {
			update(bar) {
				// the value of `bar` has changed
			},

			destroy() {
				// the node has been removed from the DOM
			}
		};
	}
</script>

<div use:foo={bar}></div>

Transitions

  • transition:name
  • transition:name={params}
  • transition:name|local
  • transition:name|local={params}
  • in:name
  • in:name={params}
  • in:name|local
  • in:name|local={params}
  • out:name
  • out:name={params}
  • out:name|local
  • out:name|local={params}
transition = (node: HTMLElement, params: any) => {
	delay?: number,
	duration?: number,
	easing?: (t: number) => number,
	css?: (t: number, u: number) => string,
	tick?: (t: number, u: number) => void
}

A transition is triggered by an element entering or leaving the DOM as a result of a state change. Transitions do not run when a component is first mounted, but only on subsequent updates.

Elements inside an outroing block are kept in the DOM until all current transitions have completed.

The transition: directive indicates a bidirectional transition, which means it can be smoothly reversed while the transition is in progress.

{#if visible}
	<div transition:fade>
		fades in and out
	</div>
{/if}

The in: and out: directives are not bidirectional. An in transition will continue to 'play' alongside the out transition, if the block is outroed while the transition is in progress. If an out transition is aborted, transitions will restart from scratch.

{#if visible}
	<div in:fly out:fade>
		flies in, fades out
	</div>
{/if}

Like actions, transitions can have parameters.

(The double {{curlies}} aren't a special syntax; this is an object literal inside an expression tag.)

{#if visible}
	<div transition:fade="{{ duration: 2000 }}">
		flies in, fades out over two seconds
	</div>
{/if}

Transitions can use custom functions. If the returned object has a css function, Svelte will create a CSS animation that plays on the element.

The t argument passed to css is a value between 0 and 1 after the easing function has been applied. In transitions run from 0 to 1, out transitions run from 1 to 0 — in other words 1 is the element's natural state, as though no transition had been applied. The u argument is equal to 1 - t.

The function is called repeatedly before the transition begins, with different t and u arguments.

<script>
	import { elasticOut } from 'svelte/easing';

	export let visible;

	function whoosh(node, params) {
		const existingTransform = getComputedStyle(node).transform.replace('none', '');

		return {
			delay: params.delay || 0,
			duration: params.duration || 400,
			easing: params.easing || elasticOut,
			css: (t, u) => `transform: ${existingTransform} scale(${t})`
		};
	}
</script>

{#if visible}
	<div in:whoosh>
		whooshes in
	</div>
{/if}

A custom transition function can also return a tick function, which is called during the transition with the same t and u arguments.

If it's possible to use css instead of tick, do so — CSS animations can run off the main thread, preventing jank on slower devices.

<script>
	export let visible = false;

	function typewriter(node, { speed = 50 }) {
		const valid = (
			node.childNodes.length === 1 &&
			node.childNodes[0].nodeType === 3
		);

		if (!valid) return {};

		const text = node.textContent;
		const duration = text.length * speed;

		return {
			duration,
			tick: (t, u) => {
				const i = ~~(text.length * t);
				node.textContent = text.slice(0, i);
			}
		};
	}
</script>

{#if visible}
	<p in:typewriter="{{ speed: 20 }}">
		The quick brown fox jumps over the lazy dog
	</p>
{/if}

If a transition returns a function instead of a transition object, the function will be called in the next microtask. This allows multiple transitions to coordinate, making crossfade effects possible.

An element with transitions will dispatch the following events in addition to any standard DOM events:

  • introstart
  • introend
  • outrostart
  • outroend
{#if visible}
	<p
		transition:fly="{{ y: 200, duration: 2000 }}"
		on:introstart="{() => status = 'intro started'}"
		on:outrostart="{() => status = 'outro started'}"
		on:introend="{() => status = 'intro ended'}"
		on:outroend="{() => status = 'outro ended'}"
	>
		Flies in and out
	</p>
{/if}

Local transitions only play when the block they belong to is created or destroyed, not when parent blocks are created or destroyed.

{#if x}
	{#if y}
		<p transition:fade>
			fades in and out when x or y change
		</p>

		<p transition:fade|local>
			fades in and out only when y changes
		</p>
	{/if}
{/if}

Animations

TODO i can't remember how any of this works

Slots

  • <slot><!-- optional fallback --></slot>
  • <slot name="x"><!-- optional fallback --></slot>
  • <slot prop={value}></slot>

Components can have child content, in the same way that elements can.

The content is exposed in the child component using the <slot> element, which can contain fallback content that is rendered if no children are provided.

<!-- App.svelte -->
<Widget>
	<p>this is some child content</p>
</Widget>

<!-- Widget.svelte -->
<div>
	<slot>
		this will be rendered if someone does <Widget/>
	</slot>
</div>

Named slots allow consumers to target specific areas. They can also have fallback content.

<!-- App.svelte -->
<Widget>
	<h1 slot="header">Hello</h1>
	<p slot="footer">Copyright (c) 2019 Svelte Industries</p>
</Widget>

<!-- Widget.svelte -->
<div>
	<slot name"header">No header was provided</slot>
	<p>Some content between header and footer</p>
	</slot name="footer"></slot>
</div>

Slots can be rendered zero or more times, and can pass values back to the parent using props. The parent exposes the values to the slot template using the let: directive.

The usual shorthand rules apply — let:item is equivalent to let:item={item}, and <slot {item}> is equivalent to <slot item={item}>.

<!-- App.svelte -->
<FancyList {items} let:item={item}>
	<div>{item.text}</div>
</FancyList>

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

Named slots can also expose values. The let: directive goes on the element with the slot attribute.

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

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

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

<svelte:self>

The <svelte:self> element allows a component to include itself, recursively.

It cannot appear at the top level of your markup; it must be inside an if or each block to prevent an infinite loop.

<script>
	export let count;
</script>

{#if count > 0}
	<p>counting down... {count}</p>
	<svelte:self count="{count - 1}"/>
{:else}
	<p>lift-off!</p>
{/if}

<svelte:component>

  • <svelte:component this={expression}>

The <svelte:component> element renders a component dynamically, using the component constructor specified as the this property. When the property changes, the component is destroyed and recreated.

If this is falsy, no component is rendered.

<svelte:component this={currentSelection.component} foo={bar}/>

<svelte:window>

  • <svelte:window on:event={handler}/>
  • <svelte:window bind:prop={value}/>

The <svelte:window> element allows you to add event listeners to the window object without worrying about removing them when the component is destroyed, or checking for the existence of window when server-side rendering.

<script>
	function handleKeydown(event) {
		alert(`pressed the ${event.key} key`);
	}
</script>

<svelte:window on:keydown={handleKeydown}/>

You can also bind to the following properties:

  • innerWidth
  • innerHeight
  • outerWidth
  • outerHeight
  • scrollX
  • scrollY
  • online — an alias for window.navigator.onLine

All except scrollX and scrollY are readonly.

<svelte:window bind:scrollY={y}/>

<svelte:body>

  • <svelte:body on:event={handler}/>

As with <svelte:window>, this element allows you to add listeners to events on document.body, such as mouseenter and mouseleave which don't fire on window.

<svelte:body
	on:mouseenter={handleMouseenter}
	on:mouseleave={handleMouseleave}
/>

<svelte:head>

  • <svelte:head>

This element makes it possible to insert elements into document.head. During server-side rendering, head content exposed separately to the main html content.

<svelte:head>
	<link rel="stylesheet" href="tutorial/dark-theme.css">
</svelte:head>

<svelte:options>

  • <svelte:options option={value}>

The <svelte:options> element provides a place to specify per-component compiler options, which are detailed in the next section. The possible options are:

  • immutable={true} — you never use mutable data, so the compiler can do simple referential equality checks to determine if values have changed
  • immutable={false} — the default. Svelte will be more conservative about whether or not mutable objects have changed
  • namespace="..." — the namespace where this component will be used, most commonly "svg"
  • tag="..." — the name to use when compiling this component as a custom element
<svelte:options tag="my-custom-element"/>

Run time

svelte

The svelte package exposes lifecycle functions and the context API.

  • onMount(callback: () => void)
  • onMount(callback: () => () => void)

The onMount function schedules a callback to run as soon as the component has been mounted to the DOM. It must be called during the component's initialisation (but doesn't need to live inside the component; it can be called from an external module).

onMount does not run inside a server-side component.

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

	onMount(() => {
		console.log('the component has mounted');
	});
</script>

If a function is returned from onMount, it will be called when the component is unmounted.

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

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

		return () => clearInterval(interval);
	});
</script>
  • beforeUpdate(callback: () => void)

Schedules a callback to run immediately before the component is updated after any state change.

The first time the callback runs will be before the initial onMount

<script>
	import { beforeUpdate } from 'svelte';

	beforeUpdate(() => {
		console.log('the component is about to update');
	});
</script>
  • afterUpdate(callback: () => void)

Schedules a callback to run immediately after the component has been updated.

<script>
	import { afterUpdate } from 'svelte';

	afterUpdate(() => {
		console.log('the component just updated');
	});
</script>
  • onDestroy(callback: () => void)

Schedules a callback to run once the component is unmounted.

Out of onMount, beforeUpdate, afterUpdate and onDestroy, this is the only one that runs inside a server-side component.

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

	onDestroy(() => {
		console.log('the component is being destroyed');
	});
</script>
  • promise: Promise = tick()

Returns a promise that resolves once any pending state changes have been applied, or in the next microtask if there are none.

<script>
	import { beforeUpdate, tick } from 'svelte';

	beforeUpdate(async () => {
		console.log('the component is about to update');
		await tick();
		console.log('the component just updated');
	});
</script>
  • setContext(key: any, context: any)

Associates an arbitrary context object with the current component and the specified key. The context is then available to children of the component (including slotted content) with getContext.

Like lifecycle functions, this must be called during component initialisation.

<script>
	import { setContext } from 'svelte';

	setContext('answer', 42);
</script>
  • context: any = getContext(key: any)

Retrieves the context that belongs to the closest parent component with the specified key. Must be called during component initialisation.

<script>
	import { getContext } from 'svelte';

	const answer = getContext('answer');
</script>

svelte/store

The svelte/store module exports functions for creating stores.

To be considered a store, an object must have a subscribe method that returns an unsubscribe function.

const unsubscribe = store.subscribe(value => {
	console.log(value);
}); // logs `value`

// later...
unsubscribe();

Stores have special significance inside Svelte components. Their values can be read by prefixing the store's name with the $ character, which causes Svelte to set up subscriptions and unsubscriptions automatically during the component's lifecycle.

<script>
	import { count } from './stores.js';

	function handleClick() {
		// this is equivalent to count.update(n => n + 1)
		$count += 1;
	}
</script>

<button on:click={handleClick}>
	Clicks: {$count}
</button>
  • store = writable(value: any)
  • store = writable(value: any, () => () => void)

Creates a store with additional set and update methods.

import { writable } from 'svelte/store';

const count = writable(0);

count.subscribe(value => {
	console.log(value);
}); // logs '0'

count.set(1); // logs '1'

count.update(n => n + 1); // logs '2'

If a function is passed as the second argument, it will be called when the number of subscribers goes from zero to one (but not from one to two, etc). That function can return another function that is called when the number of subscribers goes from one to zero.

import { writable } from 'svelte/store';

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

count.set(1); // does nothing

const unsubscribe = count.subscribe(value => {
	console.log(value);
}); // logs 'got a subscriber', then '1'

unsubscribe(); // logs 'no more subscribers'
  • store = readable((set: (value: any) => void) => () => void)
  • store = readable((set: (value: any) => void) => () => void, value: any)

Creates a store whose value cannot be set from 'outside'. Instead, the function passed to readable, which is called when the subscriber count goes from zero to one, must call the provided set value. It must return a function that is called when the subscriber count goes from one to zero.

If a second argument is provided, it becomes the store's initial value.

import { readable } from 'svelte/store';

const time = readable(set => {
	const interval = setInterval(() => {
		set(new Date());
	}, 1000);

	return () => clearInterval(interval);
}, new Date());
  • store = derive(a, callback: (a: any) => any)
  • store = derive(a, callback: (a: any, set: (value: any) => void) => void)
  • store = derive([a, ...b], callback: ([a: any, ...b: any[]]) => any)
  • store = derive([a, ...b], callback: ([a: any, ...b: any[]], set: (value: any) => void) => void)

Derives a store from one or more other stores. Whenever those dependencies change, the callback runs.

In the simplest version, derive takes a single store, and the callback returns a derived value.

import { derive } from 'svelte/store';

const doubled = derive(a, $a => $a * 2);

The callback can set a value asynchronously by accepting a second argument, set, and calling it when appropriate.

import { derive } from 'svelte/store';

const delayed = derive(a, ($a, set) => {
	setTimeout(() => set($a), 1000);
});

In both cases, an array of arguments can be passed as the first argument instead of a single store.

import { derive } from 'svelte/store';

const summed = derive([a, b], ([$a, $b]) => $a + $b);

const delayed = derive([a, b], ([$a, $b], set) => {
	setTimeout(() => set($a + $b), 1000);
});
  • value: any = get(store)

Generally, you should read the value of a store by subscribing to it and using the value as it changes over time. Occasionally, you may need to retrieve the value of a store to which you're not subscribed. get allows you to do so.

This works by creating a subscription, reading the value, then unsubscribing. It's therefore not recommended in hot code paths.

import { get } from 'svelte/store';

const value = get(store);

svelte/motion

The svelte/motion module exports two functions, tweened and spring, for creating writable stores whose values change over time after set and update, rather than immediately.

  • store = tweened(value: any, options)

Tweened stores update their values over a fixed duration. The following options are available:

  • delay (number, default 0) — milliseconds before starting
  • duration (number, default 400) — milliseconds the tween lasts
  • easing (function, default t => t) — an easing function
  • interpolator (function) — see below

TODO passing these options into store.set and store.update, to override defaults

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

	const size = tweened(1, {
		duration: 300,
		easing: cubicOut
	});

	function handleClick() {
		$size += 1;
	}
</script>

<button
	on:click={handleClick}
	style="transform: scale({$size}); transform-origin: 0 0"
>embiggen</button>

TODO custom interpolators

  • store = spring(value: any, options)

A spring store gradually changes to its target value based on its stiffness and damping parameters. Whereas tweened stores change their values over a fixed duration, spring stores change over a duration that is determined by their existing velocity, allowing for more natural-seeming motion in many situations.

TODO

svelte/transition

TODO

  • fade, fly, slide, draw
  • crossfade...

svelte/animation

TODO

  • TODO this doesn't even exist yet

TODO

svelte/easing

  • TODO could have nice little interactive widgets showing the different functions, maybe

svelte/register

TODO

Client-side component API

  • const component = new Component(options)

A client-side component — that is, a component compiled with generate: 'dom' (or the generate option left unspecified) is a JavaScript class.

import App from './App.svelte';

const app = new App({
	target: document.body,
	props: {
		// assuming App.svelte contains something like
		// `export let answer`:
		answer: 42
	}
});

The following initialisation options can be provided:

option default description
target none An HTMLElement to render to. This option is required
anchor null A child of target to render the component immediately before
props {} An object of proeprties to supply to the component
hydrate false See below
intro false If true, will play transitions on initial render, rather than waiting for subsequent state changes

Existing children of target are left where they are.

The hydrate option instructs Svelte to upgrade existing DOM (usually from server-side rendering) rather than creating new elements. It will only work if the component was compiled with the hydratable: true option.

Whereas children of target are normally left alone, hydrate: true will cause any children to be removed. For that reason, the anchor option cannot be used alongside hydrate: true.

The existing DOM doesn't need to match the component — Svelte will 'repair' the DOM as it goes.

import App from './App.svelte';

const app = new App({
	target: document.querySelector('#server-rendered-html'),
	hydrate: true
});
  • component.$set(props)

Programmatically sets props on an instance. component.$set({ x: 1 }) is equivalent to x = 1 inside the component's <script> block.

Calling this method schedules an update for the next microtask — the DOM is not updated synchronously.

app.$set({ answer: 42 });
  • component.$on(event, callback)

Causes the callback function to be called whenever the component dispatches an event.

app.$on('selected', event => {
	console.log(event.detail.selection);
});
  • component.$destroy()

Removes a component from the DOM and triggers any onDestroy handlers.

  • component.prop
  • component.prop = value

If a component is compiled with accessors: true, each instance will have getters and setters corresponding to each of the component's props. Setting a value will cause a synchronous update, rather than the default async update caused by component.$set(...).

By default, accessors is false, unless you're compiling as a custom element.

console.log(app.count);
app.count += 1;

Custom element API

  • TODO

Server-side component API

  • const result = Component.render(...)

Unlike client-side components, server-side components don't have a lifespan after you render them — their whole job is to create some HTML and CSS. For that reason, the API is somewhat different.

A server-side component exposes a render method that can be called with optional props. It returns an object with head, html, and css properties, where head contains the contents of any <svelte:head> elements encountered.

const App = require('./App.svelte');

const { head, html, css } = App.render({
	answer: 42
});

Compile time

Typically, you won't interact with the Svelte compiler directly, but will instead integrate it into your build system using a bundler plugin:

Nonetheless, it's useful to understand how to use the compiler, since bundler plugins generally expose compiler options to you.

svelte.compile

result: {
	js,
	css,
	ast,
	warnings,
	vars,
	stats
} = svelte.compile(source: string, options?: {...})

This is where the magic happens. svelte.compile takes your component source code, and turns it into a JavaScript module that exports a class.

const svelte = require('svelte/compiler');

const result = svelte.compile(source, {
	// options
});

The following options can be passed to the compiler. None are required:

option default description
filename null string used for debugging hints and sourcemaps. Your bundler plugin will set it automatically.
name "Component" string that sets the name of the resulting JavaScript class (though the compiler will rename it if it would otherwise conflict with other variables in scope). It will normally be inferred from filename.
format "esm" If "esm", creates a JavaScript module (with import and export). If "cjs", creates a CommonJS module (with require and module.exports), which is useful in some server-side rendering situations or for testing.
generate "dom" If "dom", Svelte emits a JavaScript class for mounting to the DOM. If "ssr", Svelte emits an object with a render method suitable for server-side rendering. If false, no JavaScript or CSS is returned; just metadata.
dev false If true, causes extra code to be added to components that will perform runtime checks and provide debugging information during development.
immutable false If true, tells the compiler that you promise not to mutate any objects. This allows it to be less conservative about checking whether values have changed.
hydratable false If true, enables the hydrate: true runtime option, which allows a component to upgrade existing DOM rather than creating new DOM from scratch.
legacy false If true, generates code that will work in IE9 and IE10, which don't support things like element.dataset.
accessors false If true, getters and setters will be created for the component's props. If false, they will only be created for readonly exported values (i.e. those declared with const, class and function). If compiling with customElement: true this option defaults to true.
customElement false If true, tells the compiler to generate a custom element constructor instead of a regular Svelte component.
tag null A string that tells Svelte what tag name to register the custom element with. It must be a lowercase alphanumeric string with at least one hyphen, e.g. "my-element".
css true If true, styles will be included in the JavaScript class and injected at runtime. It's recommended that you set this to false and use the CSS that is statically generated, as it will result in smaller JavaScript bundles and better performance.
preserveComments false If true, your HTML comments will be recreated inside your component. By default, they are stripped out.
preserveWhitespace false If true, whitespace inside and between elements is kept as you typed it, rather than optimised by Svelte.
outputFilename null A string used for your JavaScript sourcemap.
cssOutputFilename null A string used for your CSS sourcemap.
sveltePath "svelte" The location of the svelte package. Any imports from svelte or svelte/[module] will be modified accordingly.

The returned result object contains the code for your component, along with useful bits of metadata.

const {
	js,
	css,
	ast,
	warnings,
	vars,
	stats
} = svelte.compile(source);
  • js and css are obejcts with the following properties:
    • code is a JavaScript string
    • map is a sourcemap with additional toString() and toUrl() convenience methods
  • ast is an abstract syntax tree representing the structure of your component.
  • warnings is an array of warning objects that were generated during compilation. Each warning has several properties:
    • code is a string identifying the category of warning
    • message describes the issue in human-readable terms
    • start and end, if the warning relates to a specific location, are objects with line, column and character properties
    • frame, if applicable, is a string highlighting the offending code with line numbers
  • vars is an array of the component's declarations, used by eslint-plugin-svelte3 for example. Each variable has several properties:
    • name is self-explanatory
    • export_name is the name the value is exported as, if it is exported (will match name unless you do export...as)
    • injected is true if the declaration is injected by Svelte, rather than in the code you wrote
    • module is true if the value is declared in a context="module" script
    • mutated is true if the value's properties are assigned to inside the component
    • reassigned is true if the value is reassigned inside the component
    • referenced is true if the value is used outside the declaration
    • writable is true if the value was declared with let or var (but not const, class or function)
  • stats is an object used by the Svelte developer team for diagnosing the compiler. Avoid relying on it to stay the same!

svelte.preprocess

result: {
	code: string,
	dependencies: Array<string>
} = svelte.preprocess(
	source: string,
	preprocessors: Array<{
		markup?: (input: { source: string, filename: string }) => Promise<{
			code: string,
			dependencies?: Array<string>
		}>,
		script?: (input: { source: string, attributes: Record<string, string>, filename: string }) => Promise<{
			code: string,
			dependencies?: Array<string>
		}>,
		style?: (input: { source: string, attributes: Record<string, string>, filename: string }) => Promise<{
			code: string,
			dependencies?: Array<string>
		}>
	}>,
	options?: {
		filename?: string
	}
)

The preprocess function provides convenient hooks for arbitrarily transforming component source code. For example, it can be used to convert a <style lang="sass"> block into vanilla CSS.

The first argument is the component source code. The second is an array of preprocessors (or a single preprocessor, if you only have one), where a preprocessor is an object with markup, script and style functions, each of which is optional.

Each markup, script or style function must return an object (or a Promise that resolves to an object) with a code property, representing the transformed source code, and an optional array of dependencies.

The markup function receives the entire component source text, along with the component's filename if it was specified in the third argument.

Preprocessor functions may additionally return a map object alongside code and dependencies, where map is a sourcemap representing the transformation. In current versions of Svelte it will be ignored, but future versions of Svelte may take account of preprocessor sourcemaps.

const svelte = require('svelte/compiler');

const { code } = svelte.preprocess(source, {
	markup: ({ content, filename }) => {
		return {
			code: content.replace(/foo/g, 'bar')
		};
	}
}, {
	filename: 'App.svelte'
});

The script and style functions receive the contents of <script> and <style> elements respectively. In addition to filename, they get an object of the element's attributes.

If a dependencies array is returned, it will be included in the result object. This is used by packages like rollup-plugin-svelte to watch additional files for changes, in the case where your <style> tag has an @import (for example).

const svelte = require('svelte/compiler');
const sass = require('node-sass');

const { code, dependencies } = svelte.preprocess(source, {
	style: ({ content, attributes, filename }) => {
		// only process <style lang="sass">
		if (attributes.lang !== 'sass') return;

		const { css, stats } = await new Promise((resolve, reject) => sass.render({
			file: filename,
			data: content,
			includePaths: [
				dirname(filename),
			],
		}), (err, result) => {
			if (err) reject(err);
			else resolve(result);
		}));

		return {
			code: css.toString(),
			dependencies: stats.includedFiles
		};
	}
}, {
	filename: 'App.svelte'
});

Multiple preprocessors can be used together. The output of the first becomes the input to the second. markup functions run first, then script and style.

const svelte = require('svelte/compiler');

const { code } = svelte.preprocess(source, [
	{
		markup: () => {
			console.log('this runs first');
		},
		script: () => {
			console.log('this runs third');
		},
		style: () => {
			console.log('this runs fifth');
		}
	},
	{
		markup: () => {
			console.log('this runs second');
		},
		script: () => {
			console.log('this runs fourth');
		},
		style: () => {
			console.log('this runs sixth');
		}
	}
], {
	filename: 'App.svelte'
});

svelte.VERSION

The current version, as set in package.json.

const svelte = require('svelte/compiler');
console.log(`running svelte version ${svelte.VERSION}`);