Svelte - Tutorial Walkthrough
Svelte
Svelte is a reactive Javascript framework that hit the scene in November of 2016. Reactive JS UI frameworks are nothing new (React and Vue are popular ones), but Svelte differs from them in a fundamental way. Those reactive frameworks perform their “magic” by utilizing a Virtual DOM within their runtime. Svelte, however, builds this reactive logic directly into the code during the build/compile stage. As a result, it doesn’t rely on a Virtual DOM. The end result is a smaller and faster runtime.
This post will begin an exploration of their fantastic tutorial. I’ll walk through the various concepts presented in the tutorial, and provide examples of Svelte code. Sometimes I’ll provide my own examples, but will just as often copy code directly from the Svelte tutorial.
I’m happy that you’re here reading, and hope to provide value through describing my thoughts and experience. However, their tutorial is really top-notch, and if what’s here appeals to you, please check it out directly.
And before you go thinking this post is a simple re-hash of the Svelte tutorial…think again! There is a creative writer here trying to impress you with his narrative chops! He will use interesting words, creativity, and perhaps a dash of humor, to entice you!
So while you’re studying Svelte, consider this - there is an imaginary, unsanctioned Svelte ninja master monitoring your progress! If he is pleased with your attention and focus, you will be rewarded! He believes in you, and your passion to learn something new!
(how’s that for creative writing? A Svelte Ninja?! What blinding creativity!!)
On to the tutorial!
Getting Started
The Svelte tutorial follows a format I’ve seen in the past, with instructions on the left and a javascript sandbox on the right. I’m always impressed at how far this “sandbox” concept has come. A web page telling you how something works, and a real-time environment with a working example you can play with. What a time to be learning to code!
One cool feature I didn’t notice at first - the “JS Output” and “CSS Output” tabs in the lower right. With these, you can see the actual javascript generated by the Svelte compiler. Very useful for gaining a deeper understanding of how the compiler turns the Svelte syntax into raw javascript/CSS.
Introduction
This section walks through some of the fundamental building blocks of Svelte, including bindings, styling, and nesting.
Binding
Out of the gate, the tutorial introduces the concept of simple binding. Using something like the following code, you can easily bind variables to HTML:
Simple Binding Example
<script>
let name = 'world';
</script>
<h1>Hello {name}!</h1>
Fairly self explanatory. Looking at the underlying JS output, it’s a little hairy, but thankfully I don’t need to understand the raw JS (yet). That’s a distant mountain peak. I may strive to climb it someday, but not today.
A11y
One highlight found here - Svelte’s compiler will warn you if you’re missing A11y (accessibility) tags. What a thoughtful inclusion to the framework! A11y is often overlooked or not prioritized, which is a shame - the people who depend on Ally gain so much from it. Kudos to the Svelte team for prioritizing this feature!
Styling
Styling in Svelte is straightforward. In its simplest form, just drop a style block within your component. These component-level style blocks are scoped to that component, and they won’t overwrite styles elsewhere. Nice encapsulation.
This does get my spidey sense tingling as an area that could cause slight confusion in bigger apps (“why doesn’t this font look like the rest?”). If you find yourself wrestling with strange styling behavior, look for scoped, isolated styling tags.
Nested Components
Nested Components allow you to build a hierarchy of components. This helps to keep your components small, with singular responsibility. This division of labor promotes re-use and avoids code sprawl. The following example is simple, but you can imagine a bigger app where a much larger hierarchy of components would exist:
Child.svelte
<script>
let coolVariable = 'cool'
</script>
Parent.svelte
<script>
let parentResponsibilities = 10000;
</script>
<Child />
Making an App
The introduction wraps up with an overview of how to turn these simple concepts into an actual app. It provides suggestions for build tools and code editors. At this point in the tutorial, you probably have enough under your belt to begin playing around with things.
But there’s alot more power to uncover…the Ninja beckons you forward…
Reactivity
With the rudimentary basics covered, the tutorial dives into reactivity. This is where the framework really shines, and it illustrates why “reactivity” is so prevalent in modern Javascript frameworks. Once you go reactive, you won’t go back (tive?)
Assignments
The assignments section provides a simple example of binding an event handler to a button. It also describes how Svelte “instruments” variable assignment. This provides a small step towards understanding how the Svelte compiler turns Svelte syntax into vanilla javascript.
This is a key feature of the Svelte framework, and one that makes it so easy to use. I can write code like this:
Svelte Assignment
count += 1;
And under the covers, the Svelte compiler produces this:
Compiled Javascript
$$invalidate(0, count += 1);
Ugly framework boilerplate is hidden from view, but it allows my app to be fluidly reactive. It feels like the best of both worlds - simple javascript, powerful runtime.
Reactive Declarations
There are often assignments in javascript that aren’t quite so simple - for example, if you have a value based on another value, like the following (copied liberally from the Svelte tutorial):
Non-Reactive Variable
let count = 0;
doubled = count * 2;
While Svelte can “automatically instrument” the first line, the second line is more challenging. Svelte overcomes this with a custom syntax, hijacking the Javascript label statement:
Reactive Variable
let count = 0;
$: doubled = count * 2;
How badass is that? Svelte is using standard Javascript, but utilizing an obscure operator, giving it new meaning and power. Looking at the generated javascript, we can see some intense boilerplate code that we’ll never need to worry about:
Intense Compiled Javascript
$$self.$$.update = () => {
if ($$self.$$.dirty & /*count*/ 1) {
$: $$invalidate(1, doubled = count * 2);
}
};
Even with simple examples, the heavy-lifting power of the Svelte compiler reveals itself.
Reactive Statements
Reactive Statements take this concept even further, allowing us to designate entire blocks of code as “reactive”.
Here’s an example from the tutorial:
Reactive Statement
$: if (count >= 10) {
alert(`count is dangerously high!`);
count = 9;
}
Anytime the value for “count” changes, this code block will trigger. This is super cool - in addition to the screen updating in response to a changed value, we can also have a value change trigger a block of code.
Updating Arrays and Objects
With more complicated scenarios involving objects and arrays, some additional thought is required around reactivity. It’s nothing horribly complicated, but it doesn’t work quite as easily as simple values.
With arrays, you can’t simply modify the contents of the array (push, splice, etc). This alone won’t give the Svelte compiler enough context to recognize a reactive update. One simple (but inelegant) fix is to assign the variable to itself after modifying:
Inelegant Array Updating
function addNumber() {
numbers.push(numbers.length + 1);
numbers = numbers;
}
However, there is a more idiomatic solution that uses the spread syntax to update an array. Here’s an example of where a “pop” can be replaced with spread syntax:
Pop Replacement
function removeNumber() {
numbers = [...numbers.slice(0, numbers.length - 1)];
}
(Special thanks to this post for all the immutable array manipulation examples)
These patterns give us immutable arrays, which are valuable for performance and debuggability. Immutability is a topic that comes up pretty often when talking about reactive frameworks - probably worth a future post or two entirely devoted to this topic!
The Svelte tutorial provides a rule of thumb for determing whether an assignment will trigger reactivity:
“The name of the updated variable must appear on the left hand side of the assignment.”
This feels like an area to pay close attention to while you’re learning the framework. If you see updates that aren’t propagated onto the screen, this would be one of the first areas to explore.
Props
While encapsulating state and functionality within components is desirable, a single component can’t do much on its own. It’s difficult to build anything meaningful without components interacting with each other. Properties, or “Props”, are how Svelte components share data from parent to child.
This “parent to child” qualification is important - data flows “downhill”. If you need a change in a child to propagate up to parent, you’ll need an advanced concept such as event bindings or stores. We will cover those in a future post.
Declaring Props
Props are declared in Svelte by prepending variables with the “export” keyword, eg:
Child.svelte
<script>
export let counter;
</script>
Parent.svelte
<Child counter={4} />
This is an unusual use of the export statement. Similar to “$”, Svelte makes use of an existing keyword to accomplish its goals with native javascript.
Default Values
Props can be assigned default value in its declaration:
Child.svelte
<script>
export let counter = 10;
</script>
Which means if “Parent” doesn’t pass the value, it will default.
Parent.svelte
<Child /> // "counter" is now defaulted to 10.
Spread Props
If your code uses an object to maintain state, you can pass this object to a nested component using “spread”:
Spread Syntax
<Child {...stateObject} />
This eliminates the need to use several property assignments to pass multiple values to a child component.
Summary
That’s enough for today. We’ve covered some of the basics, touched on reactivity, and walked through Svelte properties. Still a ways to go, but it’s a fun journey to undertake. If you like what you see, Svelte’s tutorial will give you a chance to see it for yourself.
The imaginary Svelte ninja master on your shoulder is pleased with your progress thus far! He thinks you should play in the Svelte sandbox for a bit. The slightest suggestion from this ninja master is like education gold, and worth remembering. You should probably get crackin’.
In the next post, we will dig further into the Svelte tutorial, and cover topics such as logic and events. Onward and upward!
Thoughts & Notes
- Special thanks to this guy for the code markdown styling suggestion.