Yesterday I tried Svelte to see what all the fuss is about. Version 3.0.0 came out recently and it smells like Svelte is ready for the big time.

You can watch the livestream here 👇

Created by @rich_harris, Svelte's unique idea is that there's no runtime. The framework compiles itself away to become vanilla JavaScript and create the smallest bundles you ever did see.

Plus a few features to make development absolutely painless:

plain JavaScript in every file

plain CSS automatically scoped to components

plain HTML ... with some additions

no state management

You can use plain HTML. You need the extensions to interact with Svelte and your code. Such is life.

Building with Svelte feels like magic. Lemme show you 👇

We built a Marvel Movie timeline; 22 movies sorted by their timeline inside the Marvel Cinematic Universe. The AMC website helped out with a list coz I had no idea there were so many Marvel movies 😅

Click 👆 to try it in action. Total JavaScript size just 17.2KB, or 7.2KB when compressed for transfer.

That still sounds like a lot for this app, but it's less than React where you some 40KB goes just to React itself. The CSS compiled into a 1KB file with random classes for scoping. There's nothing else.

App loads fast and works fast 👌

You can see the full code on GitHub. Importing the repo into CodeSandbox didn't quite work and I'm not sure why.

Best way to start a new Svelte project is with the CLI

$ npx degit sveltejs/template my-svelte-project $ cd my-svelte-project $ yarn install $ yarn dev

That creates a new Hello World project in my-svelte-project and runs the dev server. Go to localhost:5000 and start hacking. Every change triggers a page reload so you can see what you're doing.

I didn't have to install anything new to make the above commands work 🤷‍♂️

Svelte components live in .svelte files, split into 3 sections:

JavaScript inside <script> tags CSS inside <style> tags HTML at the bottom

Our App.svelte component looks like this.

<code class="javascript">// src/App.svelte <script> // import other components import MarvelMovies from "./MarvelMovies.js"; import Movie from "./Movie.svelte"; import Header from "./Header.svelte"; import Footer from "./Footer.svelte"; // this is automatically reactive let index = 0; // assigning new values in functions triggers re-renders function nextMovie() { index = (index + 1) % MarvelMovies.length; } function prevMovie() { index = index - 1; if (index < 0) { index = MarvelMovies.length - 1; } } </script> <style> // all of this gets scoped to your component .grid-container { display: grid; grid-template-columns: 0.1fr 2.9fr 0.1fr; grid-template-rows: 0.1fr 2.8fr 0.1fr; grid-template-areas: "h1 h2 h3" "b1 b2 b3" "f1 f2 f3"; } button { cursor: pointer; } </style> // free floating HTML is kinda neat <div class="grid-container"> <Header /> <button on:click={prevMovie} style="grid-area:b1">👈</button> <Movie {...MarvelMovies[index]} /> <button on:click={nextMovie} style="grid-area:b3">👉</button> <Footer /> </div>

You might wanna install the Svelte plugin for VSCode to have proper syntax highlighting, Prettier support, and all the rest. The plugin did cause some weird issues while I was streaming, but who knows what that was.

A few interesting things to note about App.svelte :

You can import .svelte components just like normal JavaScript

components just like normal JavaScript Every let variable becomes reactive by default

variable becomes reactive by default Assigning new values in functions triggers re-renders. No need to think about any of that

Your CSS is scoped to your component so there's no bleed-over

Your HTML free-floats at the bottom

Just like in JSX, Svelte components become HTML-like elements

Dynamic values go in curly braces, {} , same as JSX

My favorite way to use custom components and add dynamic values to HTML. Vue's approach never quite made sense to me 😇

Where I think Svelte really shines is building components for re-use. Like the <Movie /> component we used above to render the Movie view.

<code class="javascript">// src/Movie.svelte <script> export let title; export let description; export let image; export let yearOut; </script> <style> .main { grid-area: b2; display: grid; grid-template-columns: 1fr; grid-template-rows: 0.1fr 400px 1.1fr; grid-template-areas: "title" "thumbnail" "description"; } h2 { text-align: center; grid-area: title; } img { max-height: 100%; max-width: 640px; display: block; } .thumbnail { grid-area: thumbnail; display: flex; justify-content: center; align-items: center; } p { grid-area: description; padding: 0 1em; } </style> <div class="main"> <h2>{title}</h2> <div class="thumbnail"> <img src={image} alt={`${title} movie thumbnail`} /> </div> <p>{description}</p> </div>

Yep it's mostly CSS.

You declare props by exporting let variables. Use them just like you would props in React 👉 <Movie title="Iron Man" description="..." /> .

Because our Movie props come from a variable, we used a spread and that worked too. <Movie {...MarvelMovies[index]} /> .

Notice that my CSS is very sloppy.

I'm redefining h2 , img , and p tags and yet it's totally fine. Svelte scopes it all to the <Movie> component.

Whatever CSS you write here affects this file/component only and that's neat.

Plus there was no boilerplate at all to get props working, reactive, and passed into the template. To be fair, the same React component looks like this:

<code class="javascript">// <Movie> as React const Style = styled.div` grid-area: b2; display: grid; grid-template-columns: 1fr; grid-template-rows: 0.1fr 400px 1.1fr; grid-template-areas: "title" "thumbnail" "description"; h2 { text-align: center; grid-area: title; } img { max-height: 100%; max-width: 640px; display: block; } .thumbnail { grid-area: thumbnail; display: flex; justify-content: center; align-items: center; } p { grid-area: description; padding: 0 1em; } ` const Movie = ({ title, description, image, yearOut }) => ( <Style> <h2>{title}</h2> <div class="thumbnail"> <img src={image} alt={`${title} movie thumbnail`} /> </div> <p>{description}</p> </Style> )

Which isn't so bad either 🤔

Where Svelte shines is its reactivity. Look at all the state management for our app

<code class="javascript"> // this is automatically reactive let index = 0; // assigning new values in functions triggers re-renders function nextMovie() { index = (index + 1) % MarvelMovies.length; } function prevMovie() { index = index - 1; if (index < 0) { index = MarvelMovies.length - 1; } }

Define a variable, index , change it inside methods. When its value changes, the component re-renders.

😍

As far as I understand, Svelte is smart enough to re-render only the HTML nodes that rely on the index variable. Sort of like what you can achieve with MobX and React if you're super careful.

This does seem easier than React's setState . Less to think about.

However, reactivity can come to bite you in the butt with more complex apps. Sometimes it leads to an effect like screen tearing where parts of the UI update before everything is ready.

Imagine if instead of changing index , each button click changed title , image , and description separately. You might get each part of the UI updating on its own without waiting for all 3 to finish changing.

For that, Svelte comes with a built-in dispatcher. I haven't used it, but looks like it gives you functionality similar to Redux.

Another neat Svelte feature is the event handling.

Svelte uses what I believe are called directives. thing:something syntax added to the HTML. Remember when I said there's no such thing as plain HTML in modern JS? 😛

We used the on: directive to make buttons work

<code class="html"><button on:click={prevMovie} style="grid-area:b1">👈</button>

Call the prevMovie function when the button is clicked.

That's it. No binding. No passing params. No nothing. Svelte figures it all out on its own.

This is where I think Svelte fumbles. Svelte's template logic is easy to use, but reminiscent of old Mustache or Handlebars syntax.

<code class="javascript">{#if user.loggedIn} <button on:click={toggle}> Log out </button> {:else} <button on:click={toggle}> Log in </button> {/if}

Not sure how I feel about that 🤔

Easy to read, yes, easier to write than React's nested ternary expressions, definitely, but means you have to learn another syntax beyond JavaScript, CSS, and HTML. Which can be good or bad.

Depends what you're doing I guess. For simple stuff this is great.

Svelte is great. Quick to get started, easy to use, good ergonomics, not too complex. Like other frameworks, I'd have to build some bigger projects to see how it feels in the real world.

That's where I've found in the past that React shines. With bigger more complex projects. Whereas Vue, in my experience, is quick to get started but breaks down with complexity.

Svelte? I don't know yet.

But it feels like Svelte takes the best of React and the best of Vue to make something awesome.

I recommend you dig through the examples. They're great and show off Svelte's best features.

Like the built-in transition support. Love it 👌

Did you enjoy this article? 👎 👍

Published on May 20th, 2019 in Front End, Technical

Learned something new?

Want to become a high value JavaScript expert? Here's how it works 👇 Leave your email and I'll send you an Interactive Modern JavaScript Cheatsheet 📖right away. After that you'll get thoughtfully written emails every week about React, JavaScript, and your career. Lessons learned over my 20 years in the industry working with companies ranging from tiny startups to Fortune5 behemoths. Start with an interactive cheatsheet 📖 Then get thoughtful letters 💌 on mindsets, tactics, and technical skills for your career. "Man, love your simple writing! Yours is the only email I open from marketers and only blog that I give a fuck to read & scroll till the end. And wow always take away lessons with me. Inspiring! And very relatable. 👌" ~ Ashish Kumar Your Name Your Email Your Address Subscribe & Become an expert 💌 Join over 10,000 engineers just like you already improving their JS careers with my letters, workshops, courses, and talks. ✌️

Have a burning question that you think I can answer? I don't have all of the answers, but I have some! Hit me up on twitter or book a 30min ama for in-depth help.

Ready to Stop copy pasting D3 examples and create data visualizations of your own? Learn how to build scalable dataviz components your whole team can understand with React for Data Visualization

Curious about Serverless and the modern backend? Check out Serverless Handbook, modern backend for the frontend engineer.

Ready to learn how it all fits together and build a modern webapp from scratch? Learn how to launch a webapp and make your first 💰 on the side with ServerlessReact.Dev

Want to brush up on your modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com

By the way, just in case no one has told you it yet today: I love and appreciate you for who you are ❤️