Getting Started with Svelte: A Beginner's Guide

Welcome to this beginner's guide to getting started with Svelte! In this tutorial, we will explore the basics of Svelte, including its core concepts, setting up Svelte, working with components, and understanding state management. We will also touch on some advanced topics such as animations, routing, and server-side rendering. By the end of this guide, you will have a solid understanding of how to build applications using Svelte, a powerful JavaScript framework.

getting started sveltejs beginners guide

Introduction

What is Svelte?

Svelte is a modern JavaScript framework for building user interfaces. Unlike traditional frameworks such as React or Vue, Svelte compiles your code at build time, rather than running it in the browser. This approach allows Svelte to generate highly efficient and performant code, resulting in faster loading times and a smoother user experience.

Why use Svelte?

There are several reasons why you might choose to use Svelte for your next project.

Firstly, Svelte's compiler generates optimized JavaScript code, which means that your application will be smaller and faster compared to other frameworks. This is especially beneficial for mobile users or those with slower internet connections.

Secondly, Svelte's reactivity system allows for seamless data binding and automatic updates. This means that any changes to your data will automatically update the corresponding parts of your user interface, without the need for manual intervention.

Lastly, Svelte's simplicity and ease of use make it a great choice for beginners or developers who prefer a lightweight framework. With its intuitive syntax and clear documentation, getting started with Svelte is a breeze.

Setting up Svelte

Before we dive into the core concepts of Svelte, let's first set up our development environment to work with Svelte.

To use Svelte, we need to install it globally on our machine. Open your terminal and run the following command:

npm install -g degit

Next, we can create a new Svelte project by running the following command:

npx degit sveltejs/template svelte-app

This will create a new folder named svelte-app with the basic structure of a Svelte project.

Basic Concepts

Components

In Svelte, components are the building blocks of your application. A component is a self-contained unit that encapsulates its own HTML, CSS, and JavaScript code. This allows you to create reusable and modular pieces of your user interface.

To define a component in Svelte, create a new file with a .svelte extension. Let's create a simple Button.svelte component:

<script>
  export let label = 'Button';
</script>

<style>
  button {
    padding: 8px 16px;
    background-color: #007bff;
    color: #fff;
    border: none;
    border-radius: 4px;
  }
</style>

<button>{label}</button>

In this code snippet, we define a component called Button that accepts a label prop. The component's HTML code consists of a single button element, with the label prop rendered inside.

Reactivity

Svelte's reactivity system is one of its most powerful features. It allows you to declaratively define dependencies between your data and your user interface, ensuring that any changes to your data are automatically reflected in your UI.

To demonstrate this, let's modify our Button.svelte component to include a counter that increments every time the button is clicked:

<script>
  export let label = 'Button';
  let count = 0;

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

<style>
  /* ... */
</style>

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

In this updated code, we introduce a new variable called count and a function called handleClick that increments the count. We then bind the handleClick function to the button's click event using the on:click directive.

Props

Props are a way to pass data from a parent component to a child component. In Svelte, props are defined in the component's JavaScript section using the export keyword.

Let's create a new component called App.svelte that uses our Button component:

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

<Button label="Click me!" />

In this code, we import the Button component and use it within our App component. We pass a label prop with the value "Click me!" to the Button component.

To access the prop within the Button component, we need to modify its JavaScript code like this:

<script>
  export let label = 'Button';
</script>

<style>
  /* ... */
</style>

<button>{label}</button>

Now, the Button component will render the value of the label prop that is passed to it.

Events

In addition to accepting props, components can also emit events to notify their parent components about certain actions or changes.

Let's modify our Button.svelte component to emit a custom event when it is clicked:

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

  export let label = 'Button';
  let count = 0;

  const dispatch = createEventDispatcher();

  function handleClick() {
    count += 1;
    dispatch('click', { count });
  }
</script>

<style>
  /* ... */
</style>

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

In this code, we import the createEventDispatcher function from the svelte module. We then create a dispatch function using createEventDispatcher(), which allows us to emit custom events.

Inside the handleClick function, we increment the count and then call dispatch('click', { count }) to emit a custom event named "click" with the current count as the payload.

To listen for the event in the parent component, we can modify our App.svelte code like this:

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

  function handleButtonClick(event) {
    console.log('Button clicked:', event.detail);
  }
</script>

<Button label="Click me!" on:click={handleButtonClick} />

In this code, we define a handleButtonClick function that logs a message to the console when the button is clicked. We bind this function to the click event of the Button component using the on:click directive.

Getting Started

Installing Svelte

To get started with Svelte, we first need to install it in our project. Open your terminal and navigate to the root folder of your Svelte project. Then, run the following command:

npm install svelte

This will install Svelte as a dependency in your project.

Creating your first Svelte app

Now that we have Svelte installed, let's create our first Svelte app. In the root folder of your project, create a new file called App.svelte and add the following code:

<script>
  let name = 'Svelte';
</script>

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

<style>
  h1 {
    color: #007bff;
  }
</style>

In this code, we define a variable called name and set it to 'Svelte'. We then use this variable within the <h1> element to display a greeting.

To render the App component, create a new file called main.js in the root folder of your project and add the following code:

import App from './App.svelte';

const app = new App({
  target: document.body,
});

In this code, we import the App component from App.svelte and create a new instance of it. We then specify document.body as the target element where our app will be rendered.

To run your Svelte app, open your terminal and navigate to the root folder of your project. Then, run the following command:

npm run dev

This will start a development server and open your app in your default browser. You should see the greeting "Hello, Svelte!" displayed on the page.

Understanding the file structure

By default, a Svelte project has the following file structure:

svelte-app/
  ├── public/
  │   └── index.html
  ├── src/
  │   ├── App.svelte
  │   └── main.js
  ├── .gitignore
  ├── package.json
  └── rollup.config.js

The public folder contains static assets that will be served as-is, such as your index.html file.

The src folder is where you'll put your Svelte components and JavaScript files. The App.svelte file is the entry point of your app, and the main.js file is responsible for rendering the App component.

The .gitignore file specifies which files and folders should be ignored by Git.

The package.json file contains information about your project and lists its dependencies.

The rollup.config.js file is the configuration file for Rollup, the bundler used by Svelte.

Working with Components

Creating reusable components

One of the key benefits of using Svelte is the ability to create reusable components. These components can be used across your application, allowing you to build complex UIs with ease.

To create a reusable component, simply define a new .svelte file and add your component code. Let's create a Button.svelte component:

<script>
  export let label = 'Button';
</script>

<style>
  button {
    padding: 8px 16px;
    background-color: #007bff;
    color: #fff;
    border: none;
    border-radius: 4px;
  }
</style>

<button>{label}</button>

In this code, we define a Button component that accepts a label prop. The component's HTML code consists of a single button element, with the label prop rendered inside.

To use the Button component in another component, simply import it and include it in your markup. For example, let's create an App.svelte component that uses the Button component:

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

<main>
  <Button label="Click me!" />
</main>

In this code, we import the Button component and use it within our App component. We pass a label prop with the value "Click me!" to the Button component.

Passing data between components

In addition to accepting props, components can also communicate with each other by sharing data. This can be achieved using Svelte's reactive statements and stores.

To demonstrate this, let's modify our Button.svelte component to emit a custom event when it is clicked, and have the parent component update its state accordingly:

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

  export let label = 'Button';

  const dispatch = createEventDispatcher();

  function handleClick() {
    dispatch('click');
  }
</script>

<style>
  /* ... */
</style>

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

In this code, we import the createEventDispatcher function from the svelte module. We then create a dispatch function using createEventDispatcher(), which allows us to emit custom events.

Inside the handleClick function, we call dispatch('click') to emit a custom event named "click".

In the parent component, we can listen for this event and update the state accordingly:

<script>
  let count = 0;

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

<main>
  <Button label="Click me!" on:click={handleButtonClick} />
  <p>Button clicked {count} times.</p>
</main>

<style>
  /* ... */
</style>

In this code, we define a count variable and a handleButtonClick function that increments the count. We bind the handleButtonClick function to the click event of the Button component using the on:click directive.

We then render the Button component and display the current count below it.

Now, every time the button is clicked, the count will be updated and displayed in the parent component.

Styling components

Styling components in Svelte is straightforward and follows a similar approach to regular CSS.

To style a component, you can use the <style> tag within the component's .svelte file. Let's modify our Button.svelte component to include some custom styles:

<script>
  export let label = 'Button';
</script>

<style>
  button {
    padding: 8px 16px;
    background-color: #007bff;
    color: #fff;
    border: none;
    border-radius: 4px;
  }
</style>

<button>{label}</button>

In this code, we define a new style block that targets the button element within our component. We set some custom styles for the button, such as padding, background color, and text color.

You can also use Svelte's reactive statements and CSS classes to conditionally apply styles. For example, let's modify our Button.svelte component to add a disabled prop that disables the button when set to true:

<script>
  export let label = 'Button';
  export let disabled = false;
</script>

<style>
  button {
    /* ... */
  }

  .disabled {
    opacity: 0.5;
    pointer-events: none;
  }
</style>

<button class:disabled={disabled}>{label}</button>

In this code, we introduce a new disabled prop and modify the button element's class to conditionally apply the disabled class based on the value of the prop.

When the disabled prop is set to true, the button will have reduced opacity and will not respond to user interactions.

State Management

Understanding stores

Svelte provides a built-in state management solution called stores. Stores are a way to store and share reactive data across your application.

There are two types of stores in Svelte: writable stores and readable stores.

Writable stores allow you to write and update values, while readable stores allow you to read values.

To create a writable store, use the writable function from the svelte/store module. Let's create a simple counter store:

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

  export const count = writable(0);
</script>

In this code, we import the writable function from the svelte/store module and use it to create a new writable store called count. We initialize the store with a default value of 0.

To update the value of the store, we can use the set method:

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

  function increment() {
    count.update(n => n + 1);
  }
</script>

<button on:click={increment}>Increment</button>

In this code, we import the count store and define an increment function that uses the update method to increment the value of the store.

To use a readable store, simply import it and use it in your component's JavaScript code. For example, let's create a Counter.svelte component that displays the value of the count store:

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

<p>{ $count }</p>

In this code, we import the count store and use it within our component. We use the $ prefix to access the value of the store.

Using stores in your app

To use stores in your app, you can import them in your components and use them like regular variables.

Let's modify our Button.svelte component to use the count store and update its value when clicked:

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

  export let label = 'Button';

  function handleClick() {
    count.update(n => n + 1);
  }
</script>

<style>
  /* ... */
</style>

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

In this code, we import the count store and use the update method to increment its value when the button is clicked.

Now, when the button is clicked, the value of the count store will be updated, and any components that use the count store will automatically reflect the new value.

Advanced Topics

Animations

Svelte provides a powerful animation system that allows you to create smooth and visually appealing transitions in your application.

To animate an element, you can use the animate directive and define the animation properties. Let's create a simple fade-in animation for our Button.svelte component:

<script>
  import { fade } from 'svelte/transition';

  export let label = 'Button';
</script>

<button in:fade>{label}</button>

<style>
  /* ... */
</style>

In this code, we import the fade transition from the svelte/transition module. We then use the in:fade directive to apply the fade-in animation to the button element.

Routing

Svelte does not have built-in routing capabilities, but you can easily integrate a routing library of your choice into your Svelte app.

One popular routing library for Svelte is svelte-routing. To install it, open your terminal and run the following command:

npm install svelte-routing

To set up routing in your app, you can create a Router.svelte component that handles the routing logic. Let's create a basic example:

<script>
  import { Router, Route } from 'svelte-routing';

  import Home from './Home.svelte';
  import About from './About.svelte';

  const routes = {
    '/': Home,
    '/about': About,
  };
</script>

<Router {routes} />

In this code, we import the Router and Route components from svelte-routing. We then define a routes object that maps URL paths to component imports.

The Router component handles the routing logic and renders the appropriate component based on the current URL. The Route component specifies the URL path and the component to render.

Server-side rendering

Svelte supports server-side rendering (SSR) out of the box, allowing you to render your app on the server and send the HTML to the client.

To enable SSR in your Svelte app, you can use the svelte-kit framework. It provides a powerful development and build system for Svelte apps with built-in support for SSR.

To get started with svelte-kit, open your terminal and run the following command:

npx create-svelte@next my-app

This will create a new my-app folder with a basic svelte-kit project structure.

For more information on how to build and deploy your Svelte app with svelte-kit, refer to the official documentation.

Conclusion

In this tutorial, we covered the basics of getting started with Svelte. We explored the core concepts of components, reactivity, props, and events. We learned how to set up a Svelte project, create reusable components, and work with state management using stores. We also touched on some advanced topics such as animations, routing, and server-side rendering.

Svelte is a powerful and efficient JavaScript framework that offers a unique approach to building user interfaces. Its simplicity, performance, and ease of use make it a great choice for developers of all levels of experience.

We hope this beginner's guide has provided you with a solid foundation to start building your own applications using Svelte. Happy coding!