Svelte or Svelte JS is a frontend framework that can be used in a similar fashion as React and Vue. Svelte does a lot of things differently and
prides itself to be fast and simple. In parts that is, because Svelte doesn’t use a virtual DOM, like React, and relies a lot on the classic way of building websites
and applications with HTML CSS and JS and sprinkling it with some useful additions.
Just like other frameworks, Svelte relies on one or more components, usually stored as *.svelte
files and we usually want an entry file called main.js
and our
initially loaded component, App.svelte
. Let’s kickstart an example application, by installing Svelte via npx:
npx degit sveltejs/template svelte-app
npm install
npm run dev
This will get us started with the following folder structure, with src
being the folder that we’ll focus on for now, because holds our entry point and components.
├── …
├── public
├── scripts
├── src
│ ├── main.js
│ ├── App.svelte
│ └── …
├── package.json
The entry file can be very simple when starting a new project. All we do here is declare a target to append our application and define the initial
component that holds the rest of our application. We can also pass different props to our app from here.
import App from './App.svelte';
const app = new App({
target: document.body,
props: {
name: 'my first app',
version: '1.0.0'
}
});
export default app;
And because we’re using App.svelte
as our parent component, let’s dive in and look at how components in Svelte are generally structured.
This is where Svelte really differs from React and Vue and simply lets us write HTML with optional script
and style
blocks. That means the simplest component
can be just HTML, but we’re free to use JS and CSS. Every CSS we write inside a component is scoped to that specific component, so styling a <p>
tag in one
component will not set the styles of every paragraph.
<script>
// ...
</script>
<main>
<h1>Hello World!</h1>
</main>
<style>
/* ... */
</style>
A simple Svelte component example
Now to start structuring our application and getting our hands dirty a little more, let’s look at importing another component and
actually adding some functionality, pulling data from an external API. For this example, we’ll fetch a random dad joke and display it on our page.
When we press a button, the fetch function will be called again and another dad joke is displayed.
<script>
async function fetchData() {
const res = await fetch("https://icanhazdadjoke.com", {
headers: {
Accept: "application/json",
},
});
const data = await res.json();
return data.joke;
}
let joke = fetchData();
function handleClick() {
joke = fetchData();
}
</script>
<button on:click={handleClick}>Get a random dad joke </button>
<h2>Here's a random dad joke:</h2>
{#await joke}
<p>...waiting</p>
{:then joke}
<p>{joke}</p>
{:catch error}
<p style="color: red">Couldn't fetch a joke...</p>
{/await}
In the example above we can see that our JavaScript is not any different than it would be without a framework. In the HTML section, however, we see the first
Svelte blocks, one handler, used to reload a joke and a special logic block, used to await
a response from our async function fetchData()
. Handlers in Svelte look a lot like
they do in Vue.js and the different logic blocks are fairly easy to remember. Here’s a quick look at two common blocks: a simple if condition and each loop.
<!-- If condition --->
{#if user.loggedIn}
<button on:click={toggle}>
Log out
</button>
{/if}
<!-- Each block-->
{#each things as thing}
<Thing name={thing.name}/>
{/each}
Data binding
Just like we can pass data from parent to child components in Svelte, we can also rely on reactive variables/data binding. The bind:
directive allows
us to automatically set name
to the input field’s current value. In the same manner, we can make other form elements reactive, such as the select
element below.
<script>
let name = 'world';
let selected;
</script>
<input bind:value={name}>
<h1>Hello {name}!</h1>
<select bind:value={selected} on:change="{() => answer = ''}">
<!-- ... -->
</select>
Lifecycle hooks and stores
Like other frameworks, Svelte gives us a few useful lifecycle hooks that allow us to run code at certain stages of a component’s lifecycle.
We can make use of the methods onMount
, onDestroy
, beforeUpdate
and afterUpdate
after we imported them in our component:
import { onMount, onDestroy, beforeUpdate, afterUpdate } from 'svelte'
A common use case for the onMount
function is fetching data from external endpoints. Doing that, we can rewrite the example above to fetch a dad joke without using an await block in our HTML. Instead, we start fetching the data right after the component is mounted and only return the final joke.
<script>
import { onMount } from 'svelte'
let joke = "loading joke..."
onMount(async () => {
const res = await fetch("https://icanhazdadjoke.com", {
headers: {
Accept: "application/json",
},
});
let json = await res.json();
joke = json.joke
})
</script>
<h2>Here's a random dad joke:</h2>
<p>{joke}</p>
Svelte also brings its own storing mechanism, which helps a lot with keeping state in sync across components. Under the hood, a store is a simple object that we
can subscribe
to, to be notified of any changes. In order to store one of the jokes from the example above, we need a writable
store. Writable stores generally have
two more functions, update
and set
that let us manipulate the stored values. In our application, we can achieve this by creating a new file, called stores.js
<script>
// stores.js
import { writable } from 'svelte/store';
export const globalJoke = writable("no joke stored yet...");
</script>
We can then import our store or specific values inside it in any other component and we’re able to read and mutate the stored values as needed:
<script>
// any other component
import { globalJoke } from './stores.js';
globalJoke.update("Did you hear about the bread factory burning down? They say the business is toast.")
</script>
Further reading
That’s only the basics that should help you get started with Svelte.
If you want to dig deeper from here, the official tutorial is a great place to start, as well
as the documentation. The Svelte site also offers an interactive playground that you can use to start getting a feel for the library.
More Stories like this
GitHub – droppyjs/droppy: Self-hosted file storage
Jest VSCode Extension | How to code Tutorial.
Import SVGs as React Components | How to code Tutorial