Did anyone else just find out that svelte is a real word? It's pretty much a synonym for lithe or slender.
If you're watching the front-end JavaScript framework ecosystem closely these days, you've probably noticed that JavaScript has started to stabilize. We no longer see a dozen frameworks competing for market share in the JavaScript space. Now, we've got a handful of front-running frameworks and a few niche ones.
Why would someone introduce a new component framework for building user interfaces with JavaScript?
Good question, I'm glad you asked.
Traditional JavaScript frameworks (React is like six years old, we can call that traditional, right?) put a heavy load on the browser even though they take advantage of a virtual DOM. A virtual DOM helps frameworks like React re-render your web interface upon state change performantly. It's an excellent idea.
But it might not be necessary.
So what is wrong with the virtual DOM?
There is nothing wrong with the VDOM, usually. Relying on a virtual DOM is totally fine for most use cases; however, it is still overhead.
There is a top-notch article by Rich Harris that covers how the Svelte project feels about the virtual DOM. To boil it down, a virtual DOM is fine in practice for many applications, but it is not faster than the DOM itself.
An analogous example described in the above article is the C compiler. You could write faster code lower in the stack, but why would you when C is friendly (and therefore productive) and fast enough?
But what if you didn't have to pick between productivity and speed?
With Svelte, you can have the same powerful model you see in React and Vue, without the overhead of the virtual DOM.
What makes Svelte special?
It removes overhead.
The hypothesis behind Svelte is straightforward: Browser-based UI frameworks result in a lot of overhead; it is possible to remove this overhead by handling the framework in a build step outside of the browser. Svelte doesn't have a virtual DOM.
It's a compiler, not a dependency.
Frameworks like Vue and React are dependencies; they interact with your code while it executes. Svelte is a compiler; it interacts with your code before you ever put that code in production — Svelte outputs vanilla JavaScript.
How does it work?
There is some really awesome documentation on svelte.dev, and I plan to write a series of tutorials on Svelte shortly. There is a wonderful REPL available on the Svelte site too.
But, I'll share some code in this article to give you a taste of working in Svelte. You should use the REPL to follow along. 😉
<!-- App.svelte -->
<script>
let name = 'world';
</script>
<style>
h1 {
font-family: Helvetica;
color: #333;
}
</style>
<h1>Hello {name}!</h1>
That's weird. It looks like a generic HTML file with one exception:
<h1>Hello {name}!</h1>
What's up with the curly brackets? Svelte makes it easy to drop JavaScript into your markup, just like JSX. For example, we could just as easily do this:
<h1>Hello {name || 'world'}!</h1>
And just like that, we are handling falsey values for the name
variable.
If you're following along, you might be confused because I called this a component framework (I'll probably use the words framework and compiler interchangeably, sorry). You'd be forgiven for asking where the component is, but you're looking at the component:
<!-- App.svelte -->
<script>
let name = 'Jacob';
</script>
<style>
h1 {
font-family: Helvetica;
color: #333;
}
</style>
<h1>Hello {name || 'world'}!</h1>
What if we want to add another component, we can just make a new file:
<!-- Image.svelte -->
<script>
export let src;
export let alt;
</script>
<style>
h1 {
font-family: "Comic Sans MS";
color: #ff0;
}
</style>
<h1>Check this out!</h1>
<img {src} {alt}>
Now let's import our new component and render it in App.svelte
.
<!-- App.svelte -->
<script>
import Image from './Image.svelte';
let name = 'Jacob';
</script>
<style>
h1 {
font-family: Helvetica;
color: #333;
}
</style>
<h1>Hello {name || 'world'}!</h1>
<Image
src="https://ksassets.timeincuk.net/wp/uploads/sites/55/2016/04/2014RickAstley_Getty109255193201014-1.jpg"
alt="The world's most talented musician"
/>
You might notice something really cool about the <h1>
tags. The styles from App.svelte
don't override the styles from Image.svelte
and vice-versa. Styles are scoped to components 🤯.
That's cool and all, but keep in mind that this is a compiler. The code that I'm writing is code for humans (and Svelte allows for some human-friendly code), but we've got to run it through the compiler to get code for the browser.
This is what the browser sees:
CSS:
h1.svelte-iq7gzg{font-family:Helvetica;color:#333}
and javascript:
/* App.svelte generated by Svelte v3.9.2 */
import {
SvelteComponent,
append,
attr,
destroy_component,
detach,
element,
init,
insert,
mount_component,
noop,
safe_not_equal,
space,
text,
transition_in,
transition_out
} from "svelte/internal";
import Image from "./Image.svelte";
function create_fragment(ctx) {
var h1, t0, t1_value = name || 'world' + "", t1, t2, t3, current;
var image = new Image({
props: {
src: "https://ksassets.timeincuk.net/wp/uploads/sites/55/2016/04/2014RickAstley_Getty109255193201014-1.jpg",
alt: "The world's most talented musician"
}
});
return {
c() {
h1 = element("h1");
t0 = text("Hello ");
t1 = text(t1_value);
t2 = text("!");
t3 = space();
image.$$.fragment.c();
attr(h1, "class", "svelte-iq7gzg");
},
m(target, anchor) {
insert(target, h1, anchor);
append(h1, t0);
append(h1, t1);
append(h1, t2);
insert(target, t3, anchor);
mount_component(image, target, anchor);
current = true;
},
p: noop,
i(local) {
if (current) return;
transition_in(image.$$.fragment, local);
current = true;
},
o(local) {
transition_out(image.$$.fragment, local);
current = false;
},
d(detaching) {
if (detaching) {
detach(h1);
detach(t3);
}
destroy_component(image, detaching);
}
};
}
let name = 'Jacob';
class App extends SvelteComponent {
constructor(options) {
super();
init(this, options, null, create_fragment, safe_not_equal, []);
}
}
export default App;
👆This is not code for humans. This is code for the browser; it is optimized for the browser. Separating the code for humans and the code for the machine means we don't have to choose between readability and speed.
Think of this like any compiler. The code that comes out of a compiler isn't intended for humans, it's intended for machines. The code that goes into the compiler is intended for humans. As a lover of readable code, this excites me.
At a glance, Svelte is a tool for writing component-based UIs with incredibly simple (read: maintainable) JavaScript. I'm not sure I'd put it in production yet, but I'm more excited to follow the development of Svelte than almost any other web technology right now.
🚀🎸🏎
There's more...
I'm writing a lot of articles these days, I run a podcast, and I've started sending out a newsletter digest about all of the awesome stories I'm hearing.
You can also follow me on Twitter, where I make silly memes and talk about being a developer.
Top comments (20)
Nice post Jacob!
I don't know if you already know this, but if you want cool syntax highlighting on your code in DEV posts, then instead of just:
You can do:
Or:
:)
It is a certain number of weeks I'm looking at svelte. My only issue is: when a bundle like bootstrap-vue or a set of material design/bulma widgets will be out?
Then I will use it! It is the most sane thing I've seen on frontend after backbone.
Why anyone would put vue inside a svelte project? It gives nothing extra from my point of view.
By the other part, don't mind on bootstrap as valid responsive/ui framework as it loads a considerable bunch of js and css (moreover it needs jQuery). It breaks the modularity on svelte or every SPA you could make.
In my opinion, Mustard UI could be a better approach: css only, lightweight and bootstrap 3.x like syntax. If you need some js plugin for giving some functionality that it's not on sapper/svelte neither on mustard, you can import it only wherever you need it, instead on load it across all entire project.
Regards
Describing it as sane is very accurate
Probably as soon as someone who wants it writes it an open sources it ;)
Great writeup! Really like Svelte's approach but saying Svelte outputs vanilla JavaScript is not accurate I think. It still has a runtime, that's the
svelte/internal
etc in the compiled output code. That's a dependency. The same is true for Stencil. It's a tiny runtime for sure but it exists :)Interesting! Definitely something to keep an eye on.
Amazing artcle! I loved how this workz, thks by the good news ;)
I'm sorry you don't like Svelte, but attacking people who use modern JS frameworks reveals that your opinion is probably just ignorance manifested.
Innovation tends to frustrate some people. 🤷♀️
Nice post, I like Svelte, never had a chance to use it production but why would you say "I'm not sure I'd put it in production" ? Is there any particular reason ?
Mostly just because it's young. I tend to fall in the camp of stable stuff over novel stuff.
Do you think Svelte would find as much popularity and acceptance as a front-end framework as React? Or would it be more of a niche framework like Vue?
I'm not sure. React will be around for a very long time due to the sheer volume of React code that has been written. Svelte seems like it might be a bit more niche, but I see as an evolution of the VDOM approach.
Really nice
quite
I have a little doubt... the way of how Svelte compile and export vanilla JS is not the same way than Angular do?