Obinna Ekwuno Writer of all things technical and inspirational. Developer and Community Advocate. In a love-love relationship with JavaScript🔥

Building a simple Svelte JS app

Example included

7 min read 2025

building svelte bookstore app example

Editor’s Note: This post was updated on 12 May 2021 to reflect updated code, images, and information on SvelteKit and Svelte Native

In the world of JavaScript, a new framework comes out every day and the ideas behind them are generally similar and offer few significant improvements. Modern UI component-based frameworks include React, Vue, ember, Angular, and many more.

In this article, we’ll look at Svelte, which takes a different approach to building user interfaces.

What is Svelte?

According to its creators:

“Svelte is a radical new approach to building user interfaces. Whereas traditional frameworks like React and Vue do the bulk of their work in the browser, Svelte shifts that work into a compile step that happens when you build your app. Instead of using techniques like virtual DOM diffing, Svelte writes code that surgically updates the DOM when the state of your app changes.”

An advantage of learning Svelte over another framework is that it has a gentler learning curve. Svelte sticks closely to the standard models for HTML, CSS, and JS. It just adds a few extensions to HTML and JavaScript, which means that developers with basic HTML, CSS, and JavaScript knowledge should be able to grasp Svelte specifics in a short time and begin building web applications quite quickly.

Prerequisites

Before we go any further, this article assumes the following:

  • Node.js ≥v6 is installed on your machine
  • npm is installed on your machine
  • Familiarity with HTML, CSS, and JavaScript
  • A basic understanding of component-based frameworks like React is helpful but not required

The difference between Svelte and component-based frameworks

Frameworks like React do the bulk of their work in the user’s browser while the app is running, but Svelte shifts that work into a compile step that happens only when you build your app. The React dev environment uses hot module replacement to exchange modified modules while an application is running, rather than performing a full reload.

This can be confusing if updates to code are not reflected in the browser, usually because of caching! You may run into issues like this if you don’t understand a bit about what the framework does behind the scenes for you.

Svelte compiles components down to a single JavaScript file (bundle.js), a CSS file (bundle.css), and a HTML file (index.html). It produces a highly-optimized vanilla JavaScript bundle, which means the browser can reload the app without it being a slow or expensive thing to do. It also excludes unused styles from the bundled CSS file to keep the stylesheets lean.

This is a reason why Svelte is becoming a popular choice for low-powered devices. Applications with smaller bundle sizes are ideal for devices with slow network connections and limited processing power.

We made a custom demo for .
No really. Click here to check it out.

React uses JSX, which puts HTML inside of JavaScript code. Svelte is similar to Vue in that it has a single file component with a section for JavaScript, a section for CSS, and a section for HTML.

<script>
  // JavaScript here - app logic
</script>
<style>
  /* CSS here - style */
</style>
<!-- HTML here -->

React and Vue use a virtual DOM. Svelte manipulates the DOM directly — it writes code that makes specific updates when the state of your app changes.

Because Svelte is a compiler, it offers features that other frameworks can’t offer such as compile-time accessibility checking.

Svelte is not as popular as React and Vue. Its ecosystem is more limited in terms of tooling, support, plugins, coding conventions, and job opportunities. However, it is growing and improving all the time.

SvelteKit was released in March 2021. It is a framework based on Svelte, think of it as the Svelte equivalent to Next.js (for React). It enables you to develop applications with advanced features like server-side rendering, code splitting, file-based routing, and offline support. Svelte Native is a mobile application framework powered by Svelte (similar to React Native).

This should be enough to make you interested in exploring Svelte and consider using it going forward.

Building a bookstore app with Svelte

Getting started

There are several ways to get Svelte up and running for a project. You can read more about the many ways to get started here. For the purpose of this article, we will be working with degit which is a software scaffolding tool. To start, run the following commands:

npx degit sveltejs/template {project name }

In this case, I am calling it svelte-bookstore.

npx degit sveltejs/template svelte-bookstore

Next, CD into the project directory, run the npm install, and finally, run the application by running npm run dev.

svelte bookstore app example

This creates a boilerplate “Hello World” app for you. The main.js file is the entry point of the app. Inside it, we see it initializes the App component and passes it a prop called name.

import App from './App.svelte';
const app = new App({
    target: document.body,
    props: {
        name: 'world'
    }
});
export default app;

The App component is written in app.svelte – this would be a good time to note that components in Svelte are saved with .svelte extension. In app.svelte, we can see the three sections we mentioned earlier.

The prop name is declared in the script section as a regular variable, but it is prepended with an export statement that marks it as a prop. It is used inside the HTML by surrounding it with curly braces.

<script>
    export let name;
</script>
<style>
    h1 {
        color: purple;
    }
</style>
<h1>Hello {name}!</h1>

Creating a dynamic book component in Svelte

When creating our components, there are a few things that are noteworthy about Svelte:

  • Styles are scoped within components, so a div styled in one component will not affect another in a different component
  • We can define functions that are connected dynamically

In this section, we’ll create a dynamic event with Svelte and linking the book.svelte component with app.svelte and passing props.

The first step is setting up the book component and exporting variables which can be set from the parent tag in app.svelte:

<script>
    export let bookTitle;
    export let bookPrice;
    export let bookDescription;
</script>
<style>
    div{
        margin: 1rem;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26)
    }
    h1{
        font-size: 1.25rem;
        margin: 0.25rem 0;
    }
    h2{
        font-size: 1rem;
        margin: 0.25rem 0;
        color: aqua;
    }
    p{
        margin: 0.25rem 0;
    }
    button{
        font : larger;
        padding: 0.15rem 0.5rem;
        background-color: #1b1a1a;
        border: 1px solid  aliceblue ;
        cursor: pointer;
        color: white;
    }
</style>

<div>
    <h2> {bookTitle} </h2>
    <p> {bookPrice}</p>
    <p> {bookDescription}</p>
    <button> Add </button>
</div>

From the code block above, we can see that we have variables that are being used in the tags in the div. They have their values coming from the app.svelte, which we will see next and where most of the dynamic manipulations happen.

In the app.svelte, we have imported the book component and this is where we will do a lot of the dynamic manipulation.

<script>
    import Book from './book.svelte'
    let title = '';
    let price = 0;
    let description = '';
    function setTitle(event){
        title = event.target.value;
    }
</script>
<style>
    h1 {
        color: purple;
        
    }
    section{
        margin: auto;
        width :30rem;
        
    }
    label,input,textarea{width: 100%}
</style>
<section>
    <div> 
        <label for="title">Title</label>
        <input type="text" id="title" value={title} on:input={setTitle}/>
    </div>
    <div>
        <label for="price">Price</label>
        <input type="number" id="price" value={price} bind:value={price}/>
    </div>
    <div>
        <label for="description">Description</label>
        <textarea rows="3" id="description" bind:value ={description}/>
    </div>
</section>
<Book bookTitle={title} bookPrice={price} bookDescription={description}/>

From the code example above, we can see that inside our script tag, we have also set variables to empty " ". These are the values that are automatically updated. Also notice a function setTitle, which is used to set a title to target the object that calls it within the on:.

Note that we call the function without parentheses because we don’t want it immediately executed. Instead, we are trying to set up a refers so that Svelte can call the function on every keystroke.

We use the on: to add event listeners in Svelte. We can use this to listen to the input event, and the curly braces are used to show dynamic input. Because the function we have uses two-way binding, we can use it on other tags using the bind:. This binds the value property to the variable. We also do this for the description.

Finally, we pass the variables to the Book component as props. We do this by passing the variables title, price, and description using curly braces {}.

Displaying book information in Svelte

Now that we have the card updating when we input value, the next step is to make sure that we are able to add books to our bookstore. The first thing we have to do is make our button a stand-alone component in order to be able to use it in the other two components. We do this by creating a button.svelte and importing it to the book and app component, respectively.

<style>
  button{
        font : larger;
        padding: 0.15rem 0.5rem;
        background-color: #1b1a1a;
        border: 1px solid  aliceblue ;
        cursor: pointer;
        color: white;
    }

</style>


<button on:click >
    <slot/>
</button>

You might notice an on:click attribute in the button tag. This is used to trigger the forward event to the component that uses the button and will handle the event.

Let’s look at an example.

app.svelte

<Button on:click={addBook}>ADD Book</Button>

This engages with an addBook function that allows the button to add a new book to the array:

let books =[]

function addBook(){
        const newBook = {
            title : title,
            price : price,
            description: description
        };
        books = books.concat(newBook)
    }

The above code exists inside the script tag and what it does is call all the properties of the book from the form and concatenates them. We make use of a concat because push does not change the book variable. It only changes the array, but assigning concat to a new value will trigger a change.

We now have an array of books which is displayed conditionally using a special markup that Svelte gives us:

{#if books.length === 0}
    <p>
       No books in stock. 
    </p>
{:else}
    {#each books as book}
        <Book bookTitle={book.title} bookPages={book.price} bookDescription={book.description}/>
    {/each}
{/if}

If the array is empty, it will show “No books in stock”.

 

Building a Svelte app bookstore example

 

And displays the information on the card once the user updates:

building svelte app example bookstore add new book

Adding a cart in Svelte

To achieve this, we will have to make another component called purchase.svelte. In the script tag, we would want to export the books variable so that it can be updated by the book tag, by passing the information as props in the app.svelte.

building svelte app example adding cart to bookstore

In the app.svelte, we add an empty array in the script to hold the purchased books. Now, how do we add books to these purchases? We will use the buy button in the book component and then, add the purchaseBook function to script and bind to the button using on:{purchaseBook}.

We then use the create a dispatch function from the Svelte’s custom library. Finally, we can link the function to the Book tag by adding the on:buy = {purchaseBook}. This event dispatches from our purchaseBook function.

Conclusion

In this article, we learned the basics of Svelte by creating a book store app. I hope it helped you understand the power of Svelte and shows you the ways you can go about creating awesome applications. Here is a link to the source code. I recommend the interactive tutorial on the official Svelte website to get a more thorough understanding of Svelte. Happy coding! 😄

: Full visibility into your web apps

LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.

.
Obinna Ekwuno Writer of all things technical and inspirational. Developer and Community Advocate. In a love-love relationship with JavaScript🔥

Testing accessibility with Storybook

One big challenge when building a component library is prioritizing accessibility. Accessibility is usually seen as one of those “nice-to-have” features, and unfortunately, we’re...
Laura Carballo
4 min read

Leave a Reply