Getting Started with Svelte 3

It has happened again! I have fallen in love once more! Or is it just infatuation? It’s too early to tell perhaps, but I’ve developed strong feelings for Svelte indeed and time will tell if it turns into a full blown relationship.

What is Svelte?

Svelte is a UI framework of sorts that barrows a lot or the great ideas from some of its peers like React and Vue.js, but brings about its own interesting ideas to the table. Plus, it’s not entirely a framework in the sense that we’re used to and is perhaps better seen as a compiler.

When you build a Svelte app for production, your code is compiled into pure and optimized JavaScript, without other framework dependencies included in the mix, which makes for really tiny bundles. So it feels like a framework when developing with all the syntax niceties, but then the framework disappears when the code is launched in production. The best of both worlds!

Svelte has been around for a few years now, but with the arrival of Svelte 3, even more powerful features are available for developers. I personally feel like it’s starting to look like a serious contender for when it comes to choosing a tool to build UIs for the web.


Enough with my chit-chat already, and let’s get down to brass tacks. If you’re interested in more of a big picture overview and inception story, I recommend you watch this talk by Rich Harris, the creator of Svelte:

Initiating a Svelte 3 Project

Get started with Svelte by using the degit project scaffolding package. You can do so in the command line by simply calling degit using npx. Let’s create a simple say-something app:

$ npx degit sveltejs/template say-something

# cd into the created directory
$ cd say-something

# install the dependencies
$ npm install # or yarn install if that's more your jam

And with this, you can now run a development server using this command:

$ npm run dev

And now you can head over to http://localhost:5000 to access your app. We’re ready to start playing with Svelte!

Guts of a Svelte App

It can help to know how all the files fit together in a Svelte project to grasp the big picture. Let’s break things down:

package.json

Open up the project into your favorite code editor and access the package.json file. Notice how there are only dev dependencies and no traditional dependencies! This is where it starts to sink in that you’re working with something totally different. There are no normal dependencies because the framework compiles your code to pure vanilla JavaScript when building for production.

JavaScript entry point: main.js

If you look into the src folder, you’ll see a root component, App.svelte, and a JavaScript entry point, main.js. Like with React or Vue, Svelte apps are built using components, and most of the time you’ll have an App component that acts as the root component to the rest of the component tree that forms your app. main.js simply takes that App component and instantiates it using a target element in your index.html file and optional props that the App component can receive.

Again, just like components in React or Vue, Svelte components can receive props.

Public folder

When developing, the public folder will contain an unminified version of your app bundle and an index.html file in which the bundle is executed.

Svelte files

Components in Svelte are written using .svelte files, which contain all the logic, styling and markup for a component. You’ll be used to something like that if you’re coming from the Vue world.

A typical Svelte file will look like this:

SomeComponent.svelte

<script>
  // logic for your component
</script>

<style>
  /* the styling for your component */
</style>

<!-- The HTML markup for your component -->

It’s refreshing to think that you can just write plain old JavaScript, CSS and HTML! The only difference is a few Svelte-specific syntax additions to the HTML and a few special rules for how some of the JavaScript is treated.

Oh, and the styles will be scoped to the component described in the Svelte file, so no need to use fancy classes or worry about specificity outside the component.

Building a Counter Component

Let’s build a simple Counter component and learn about some of the Svelte-specific syntax at the same time. We’ll forgo styles here for simplicity, as style and scripts blocks in a .svelte file are optional anyway.

Here’s our starting point:

<script>
  let count = 0;
</script>

<div>Current count: {count}</div>

Curly brackets in your markup is for value interpolation. Any valid JavaScript one-liner will work, but most often it’s kept simple to interpolate values that come from our JavaScript code.

Binding to events

Let’s add some buttons so that we can increment or decrement the counter:

<script>
  let count = 0;

  function increment() {
    count += 1;
  }

  function decrement() {
    count -= 1;
  }
</script>

<div>Current count: {count}</div>

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

As you can see, you can bind to events using the on:eventname syntax. You can then pass-in a reference to a function that’s defined in your JavaScript logic.

Conditionals

You can make use of conditionals using a special if syntax. Let’s display some paragraphs only when our counter value is higher than 5 or lower than -5:

<script>
  let count = 0;

  function increment() {
    count += 1;
  }

  function decrement() {
    count -= 1;
  }
</script>

<div>Current count: {count}</div>

{#if count > 5}
  <p>⚠️ That's a little much, don't you think!</p>
{:else if count < -5}
  <p>👻 How low can you go!</p>
{/if}
  

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

The :else if clause is optional, and you can also make use of an :else clause.

Two-way value binding

Sometimes you’ll want a value to be bound both ways, like when a form input should take its value from a variable in your component, but changing its value should also change that variable’s value. That’s easy to do with Svelte! Let’s have our count displayed in a form input instead and allow the user to set the current count manually:

<script>
  let count = 0;

  function increment() {
    count += 1;
  }

  function decrement() {
    count -= 1;
  }
</script>

<div>Current count: <input bind:value={count} type="number" /></div>

{#if count > 10}
  <p>⚠️ That's a little much, don't you think!</p>
{:else if count < -10}
  <p>👻 How low can you go!</p>
{/if}
  

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

The two-way binding is accomplished with the help of the bind:value={myVal} syntax. Notice here that we used an input of type number and Svelte automatically coerces the input value into a Number type instead of the usual string that form inputs provide. A nice little shortcut!

Building for Production

When you’re ready to take your app to production, just run the build command:

$ npm run build

And now the public folder will contain a minified and optimized version of your compiled bundle, ready to be pushed to a CDN near you! 👍

Learning More

This post barely scratched the surface and I plan on starting a whole series to explore the ins and outs of Svelte.

In the mean time, have a look at the official tutorial and examples, which are two great resources to learn all about Svelte. My bet is that you’ll find yourself being productive with Svelte in no time!

  Tweet It

🕵 Search Results

🔎 Searching...

Sponsored by #native_company# — Learn More
#native_title# #native_desc#
#native_cta#