Svelte tutorial: An elegant framework for learning new things

In this tutorial, we'll build a basic Svelte app that will give you a good understanding of the core concepts in Svelte-like components, props, and more.
September 6, 2023


Hello! Today, we're going to learn about Svelte. Svelte is a frontend framework, just like React and Vue. The term “svelte” means lean and elegant, and the framework aims to be exactly that.

In this tutorial, we'll build a basic Svelte app that will give you a good understanding of the core concepts in Svelte-like components, props, state management, conditional rendering, and styling.

Let's go. You can see the final code in this repository.

Setting up

As you’ll see throughout this tutorial, working with Svelte generally involves fewer steps and less code than with other frameworks. 

You'll need to have the latest version of Node.js installed on your system. If you don't have it already, you can download it from the official Node.js website.

To create a Svelte project, open your terminal or command prompt and run the following command:

npm create vite@latest svelte-intro -- --template svelte

This command will create a new folder called svelte-intro, and initialize a vanilla Svelte project (no TypeScript) inside it. 

Now, navigate into your new svelte-intro folder by running:

cd svelte-intro

Next, install the required dependencies by executing:

npm install

Once the installation is complete, you can run:

npm run dev

And you’re ready to start building your first Svelte app.

Side-note: Svelte vs. [insert framework]

I’m guessing that if you’re reading a Svelte tutorial, you’re already curious about the framework, and how it compares to the other ones. We have a pretty detailed comparison of Svelte vs. React already, but what about the rest?

The main feature that distinguishes Svelte to the other JavaScript frameworks is that it’s compiler-based.

What does that mean? Well, Angular, Vue, Next.js all add a runtime to your bundle on top of your JavaScript to take care of the virtual DOM and other things. Svelte doesn’t. The Svelte compiler does the work at build-time to turn your Svelte code into regular DOM manipulations. That’s why it’s so small!

Your first Svelte component

All the “modern” frontend frameworks are created around the concept of components, and Svelte is no different.

Just like with the other frameworks, a Svelte component is a reusable, self-contained piece of UI (mostly). HTML, CSS, JavaScript, are in a single file with a .svelte extension. 

It can manage its own state, and it can receive data from parent components via properties (or "props").

Svelte component structure

Let's start by creating our first Svelte component. Let's use the classic example of a counter component, named Counter.svelte.

This is what a Svelte counter looks like:

Let's see how components in Svelte work:

  1. JavaScript is defined in the <script> tags. In our case, the state is represented by the count variable, and the logic includes an increment function for updating this state.

  2. The beauty of Svelte is that most of the code in that <script> tag is just JavaScript, there’s no JSX or other framework-specific language to deal with. (There is some specific syntax when you get into reactivity, but you can mostly copy-paste regular JavaScript, and that’s great.)

  3. The HTML is defined in the second section. Here, a button is set up, with the on:click attribute calling the increment function in the script tag. The curly braces {} let you do a binding to the count variable, which means that the value of the variable will be reflected there and automatically updated.

  4. The CSS comes last, within the <style> tags. In Svelte, the styles are locally scoped to the individual component, meaning they do not affect the other parts of your app.

Using the component

Like with the other JavaScript frameworks, you can import this Counter.svelte component into another component and use it like an HTML tag. In our demo app, we need to import it into our App.svelte file, which is our entry point.

Then, you'd add the Counter component to the markup section.

Now, the Counter component is part of the App component, and when your app auto-reloads, you'll see a button that increments a counter.

That's it, that’s your first Svelte component. Next, we'll dive into how props work.

Props in Svelte

Props allow us to pass data from a parent component down to a child component. Props in Svelte work like HTML attributes. 

Let's create a new Svelte component, Card, that we'll use to display product information. 

First, we need to make a new file named Card.svelte in the src/lib directory.

In Card.svelte, add the following:

In Svelte, we need to add the export keyword to make internal variables available as props.

Here we declared the title, description, and price as props.

Passing Props

To pass props to the Card component, you would do the following:

First, import the Card component at the top of your App.svelte file.

Then, in the HTML, remove the Counter component, add the Card component and pass in some values like regular attributes.

That's it! Now you know how to use props in Svelte.

Iterating / Loops

Svelte uses an {#each}{/each} block to loop through/iterate over arrays of items. It’s the exact same syntax as handlebars, just with one less curly bracket.

Going back to our example, if we want to display multiple products, we can create an array for all of them, and render a Card component for each. Here's how we can do it.

Declare an array of products in the app.svelte component, then, use the {#each} block to render a card component for each product in the html section.

Be mindful of the {/each} closing tag (it’s not the same as the opening #{each} tag.) And let’s not forget to pass in the product's title, description, and price as props.

In the next section, we'll explore how to add styles to Svelte components.

Adding global styles and open-props

I’m very much a typical developer in that I’m either not good, or very slow at designing. A quick way to make a project look good is open-props. It’s a project from Adam Argyle, which gives us a set of ready-to-use CSS variables that support your system’s light/dark mode.

To use open-props, you'll need to import the CSS files and make the styles within available to all your other Svelte components. 

Remember that styles are scoped to the component by default, so you’ll need to add the global attribute to your style tag to make the styles global.

Now open-props is imported and available in every component. Let’s use some of its variables to style our Card component.

In this example, we're using the --font-weight-8 and --font-weight-4 variables to make our h2 bolder.

Next, we'll look at state management in Svelte. We'll learn how to use the concept of “stores” in Svelte to manage shared state across different components.

State management

State management is a complicated topic. There’s a whole parallel ecosystem in the world of React with Redux, Immer, React Query, etc. Now there are whole books written about these specific libraries, so this is just a brief overview of how Svelte does it.

In Svelte, there’s a built-in way to manage state through the concept of “stores.” Svelte stores help you manage state through observing arbitrary values and subscribing to changes to these values in components. 

There are two kinds of Svelte stores:

1. Writable stores

A writable store is like a file with write access, you can read from it and write to it. 

In a component, you can subscribe to the store and update its value:

2. Readable store

A readable store only allows you to read it. It’s all there is to it.

In a component, you still subscribe to the store to read its value:

Using stores to manage VAT 

In our project, we can use a store to manage whether VAT should be applied to the price of the products.

Create a new file named ./store.js  and within it, create a writable store using the writable function from the svelte/store module:

This code creates a writable store named hasVat and initializes it with a value of true.

Here's how we can subscribe to the hasVat store in the Card component:

We import the hasVat store and subscribe to it. Inside the subscription callback, we update the hasVatValue variable whenever the store's value changes. In the HTML, we use this value to conditionally apply the VAT to the price.

Rather than having state all over the place, I like that we can keep a record of all our stores neat and tidy in a single file. 

Wrapping up: Svelte tutorial

Here’s a quick recap of what you’ve learned

  • Svelte’s component syntax: props, loops, styles, templating

  • Adding global styles and using open-props

  • Built-in state management with Svelte stores

If you need to find out more about Svelte, the official website is The REPL is also incredibly helpful. Thanks for reading.

Start building

Use your favorite tech stack, language, and framework of your choice.

About the author

Don't miss the latest

Get updates in your inbox
Discover new insights from the Contentful developer community each month.
add-circle arrow-right remove style-two-pin-marker subtract-circle remove