tldr — Svelte is a JavaScript framework for building user interfaces. Its compiler architecture enables amazing tradeoffs for UX and DX. Svelte might be worth your attention, especially if you pine for the web of yore and future.
It’s March 2020 and a friend and I are spinning up a big long-term web project. We’re choosing technologies and I’m recommending a UI framework. I love writing frontends and my friend is a backend developer with a little frontend experience. Here’s what our project looks like:
- competes with community platforms like forums and chat apps
- heavy on content and extra heavy on interactivity and app-like behavior
- embraces the web platform and optimizes for both desktop and mobile
- it’s big and we plan to work on it for many years
So — which frontend JavaScript UI framework should we choose? For context, I’ve used React full-time since 2014 and Svelte for a year. I’ve also made small things with Vue, Angular, and Ember, and before that, I worked with Backbone and jQuery for three years. I pledge no allegiance — all are good tools.
Our top priority is the end user experience. Whatever tools we use should optimize for the quality of the experience while balancing other concerns. This is no simple formula. Many factors affect UX — performance, development speed, even developer happiness. Each of these is complex and interrelated. This is a subjective choice, not a solvable equation, and any recommendation is going to be context-dependent and biased. My goal is to communicate why I believe Svelte is the better choice for our project, lay out the pros and cons, and persuade you to consider learning more.
Here’s the current opening pitch at svelte.dev:
Svelte is a radical new approach to building user interfaces. Whereas traditional frameworks like React and Vue do the bulk of their work in the browser, Svelte shifts that work into a compile step that happens when you build your app.
Instead of using techniques like virtual DOM diffing, Svelte writes code that surgically updates the DOM when the state of your app changes.
If you’re new to Svelte, now would be a good time to read its introductory blog post. From here I’ll assume some familiarity.
After using Svelte for a year and participating in the community, I can say I love its design and I’m having a lot of fun. Svelte provides an enjoyable DX that doesn’t compromise on UX. I think it’ll soon become common knowledge among UI developers that compilers have an advantage over runtime-only frameworks for hitting this sweet spot. Both Angular (Ivy) and Ember (Octane) have evolved towards compilation as Svelte helps popularize the idea.
Rich Harris created Svelte in 2016 for his work on interactives at the New York Times. The work demanded web UIs that are fast, tiny in bundle size, and quick to produce, with good support for SVG and animations. His colleague Mike Bostock (of d3) had been promoting compilation as a powerful pattern that was underutilized on the web. Svelte grew out of these needs and inspiration. In early 2019 version 3 was released, bringing major innovations like reactive assignments, reactive declarations, and composable lifecycle functions, attracting significant attention in the web community. (1, 2, 3, 4) I was loosely following Svelte because it kept smoking benchmarks, and version 3 convinced me of its potential — I began using it for risk-tolerant projects. In the State of JS 2019 survey (caveat: it has many flaws), 75% of respondents have heard of Svelte, 45% are interested in learning it, and 7% have used it. It’s no exaggeration when author Rich Harris calls the community small but mighty. Compared to modern mainstream frameworks like React and Vue and their communities, Svelte is smaller and less mature, but its community is active and established. Svelte is now commonly mentioned in the same breath as React, Vue, Angular, Preact, and Ember, and for good reason.
Like all technologies, Svelte comes with tradeoffs. We’ll explore both the pros and cons ahead. The costs and benefits to your projects are situational. Some downsides are unavoidable, but many are temporary if growth and development continue. First let’s talk about the good stuff.
Our goal is to create amazing user interfaces that exceed expectations, and Svelte is a tool that delivers. By default, Svelte websites are fast and lightweight. As a tool, it’s powerful, flexible, friendly, and beautifully designed. Making things with Svelte feels fun and streamlined. Let’s walk through the details.
Svelte is easy to learn.
Its design philosophy shares much with
The Zen of Python.
The team values beginner friendliness and
the official tutorial
is excellent and approachable.
The official blog post
“Svelte for new developers”
helps those new to Node and the command line.
Its .svelte
files pack together all three of the web’s languages
with holistically-designed extensions.
Like Vue, Svelte templates are a superset of HTML.
If you know HTML and CSS, you can write Svelte immediately
and learn more as you go, layering useful concepts on top of the web platform.
People who already know JavaScript and a modern frontend framework
regularly mention how easy it is to learn Svelte.
(1,
2,
3)
Like most frameworks that abstract the DOM, Svelte has incompatibilities
like the inability to name a prop class
because it’s a reserved keyword in JS,
and you’ll use on:click
not onclick
,
but these quirks are few in number and reflect carefully chosen tradeoffs.
Svelte does its best to harmonize with the web platform,
welcoming both experienced developers and newcomers
with whatever web knowledge they have.
The Svelte language’s extensions to HTML, CSS, and JS are designed to improve the development experience, and they set the framework clearly apart from its peers. Svelte initially received a lot of attention for its performance and small bundles, but since v3 the dev team has emphasized Svelte’s DX advantages. Here are some of the official examples, which hopefully speak for themselves:
- reactive assignments
- reactive declarations
- reactive statements
- declaring props
- store auto subscriptions
- transitions
- event forwarding
- optional two-way binding
Svelte code is terse, and not in a cryptic way — component definitions feel distilled to their essence, with hardly any wasted characters. See the official blog post “Write less code” for the full picture. Rich Harris also gave a related talk, “The Return of ‘Write Less, Do More’”.
As a compiler, Svelte can tailor its output code for context-specific needs. For example, it can write to targets like custom elements a.k.a. web components — and component libraries can export both Svelte components and vanilla JS scripts. This makes it a good candidate for incremental adoption, like using Svelte components with React and Vue. Svelte outputs small bundles that include only the framework code used by your components. An experiment with WebGL and the NativeScript integration svelte-native demonstrate compile targets beyond the DOM. Its server-side rendering mode compiles components to simple string concatenation for big performance gains. Compilers have access to flexibility and power that runtime frameworks do not — this point is deep and there’s a wide frontier to explore.
Making UIs with Svelte is a pleasure. I like its taste and aesthetics so much. Svelte’s design feels like a warm cozy blanket on the stormy web. This impacts everything — features, documentation, syntax, semantics, performance, framework internals, npm install size, the welcoming and helpful community attitude, and its collegial open development and RFCs — it all oozes goodness. Its API is tight, powerful, and beautiful — I’d point to actions and stores to support this praise, but really, the whole is what feels so good.
The aesthetics of underlying technologies have a way of leaking into the end user experience, and Svelte is a lovely companion. Our team is building open source community tools and Svelte fits our identity as an independent labor of love with an organic community. With some frameworks, you may find your needs at odds with the enterprise-level goals of a megacorp owner, and you may both benefit and sometimes suffer from their web-scale engineering. Svelte’s future does not depend on the continued delivery of business value to one company and its direction is shaped in public by volunteers. Regardless of measurable impact, Svelte resonates with our emotions and it makes for a good story.
Svelte has excellent performance characteristics. It deserves its reputation for speed but that’s not its top priority — instead Svelte wants to provide an awesome development experience and output code that performs well by default. Svelte can optimize user code at compile-time, like resolving the dependency graph of computed properties to propagate changes with minimal runtime overhead, and there’s low-hanging performance fruit to be picked.
Runtime frameworks like React and Vue pay some costs that compilers can minimize or avoid. Virtual DOM implementations have downsides — see the official Svelte blog post “Virtual DOM is pure overhead”. While Vue is implementing strategies to optimize its runtime templating, React is betting long-term on concurrent mode and functional purity to improve performance, leveraging its virtual DOM architecture to unlock benefits unavailable to other frameworks. Concurrent mode applies additional restrictions that developers are learning to work with, which the React team confidently trades for the benefits. The tradeoffs are complex, context-dependent, and nuanced. React may provide amazing UX in some circumstances once concurrent mode is ready, but I’m skeptical that their solution is the best one for our problems. My instincts lead me to prefer less abstraction, lean on automated tools like compilers, and avoid runtime costs without clear benefit. See this comparison Rich Harris made between Svelte and a popular React concurrent mode demo. Svelte can write code that performs similarly to hand-written JS and sometimes do everything in a single animation frame, where React sometimes spreads equivalent work over multiple frames. Sometimes is the key word here. There is no objectively right answer for every situation. With Svelte we may end up jealous of React’s sweet non-blocking rendering one day as this tweet portends, but today Svelte is fast for typical usage and it should continue improving.
Svelte components are a thin layer over the DOM and naturally expose the web platform. Coding in Svelte feels like I’m moving with the grain of the web. React abstracts the DOM with functionally pure declarative rendering and provides escape hatches back to mutable imperative DOM land. This is a profound philosophical difference that Rich Harris gave a talk about. (unfortunately not recorded — slides here)
The difference is salient with animation — Svelte ships with builtin support for high performance transitions and animations, using optimal CSS when possible and JS when not. In comparison, React’s functional declarative model has developers declare what the UI looks like at individual snapshots in time. Both the code we write and performance are impacted — it can be difficult or verbose to accomplish some things like animations in React, especially without libraries, and high-performance React animation libraries often bail out of its rendering model to manipulate the DOM directly.
Concurrent mode is a further departure from the DOM and points toward the endgame of React’s functional purity. It’ll be interesting to follow how this philosophical difference plays out as each side of the spectrum moves closer to the theoretical endpoints. Future web standards may or may not follow React’s lead. For our project, we’re comfortable aligning with the web platform for the long run.
Svelte’s upsides are compelling to our team, but we also need to understand its downsides. First we’ll discuss the negatives that are unlikely to change.
The compiler architecture moves complexity
from the runtime and source code to buildtime and tools.
Behind Svelte’s simple APIs sits a beefy compiler.
Frontend web development has become very tool heavy in the webapp era,
so in practice this adds little cost beyond what developers like myself
already pay, but increased build complexity is important to acknowledge.
For example Vue’s Evan You has stated
that Vue should always be droppable into any webpage for immediate development.
Many people like and rely on this ability.
It keeps things simple.
Svelte can do this but only by including its compiler in the browser,
which currently weighs 870k. This is super useful in some circumstances,
like Svelte’s REPL,
but it’s not a viable option for normal application code.
Svelte requires a build step that’s heavier
than React’s JSX and Vue’s .vue
files.
Svelte is its own language
not plain HTML+CSS+JS, increasing the risks of adoption,
but happily it adheres closely to the web platform
outside of its own targeted enhancements.
Svelte changes some of JavaScript’s semantics to support useful features
by extending/reusing/reinterpreting valid syntax.
(e.g. reactivity,
auto-subscriptions,
and declaring props)
Rich Harris is proposing to standardize its templating language as
HTMLx,
which may or may not gain adoption.
Svelte CSS is scoped to components, which is a nice default,
and it provides the :global
escape hatch
to opt out.
Svelte isn’t alone in its approach
of extending languages, but it goes further than Angular and Vue,
which extend HTML but not JS,
though their JS is subject to framework-specific rules and behaviors
not unlike Svelte.
React introduced both JSX and hooks,
the latter of which change some semantic expectations of JS function calls,
and it’s arguable whether React or Svelte
is the more radical departure from the norm.
(sounds like a boring argument tbh)
After using Svelte for a year, I can comfortably claim
it extends the web’s languages with taste and restraint,
and for our team it’s worth the costs and risk.
Svelte’s reactive language extensions are limited to components. In Vue and libraries like the React-friendly MobX, you use the same syntax for reactive primitives in every module, because they are plain JavaScript. Although this is a restriction in Svelte, it comes with benefits as well — its reactive syntax is part of why people like it so much, and its simple store contract interoperates with things like RxJS, so you can choose among many libraries or stick with Svelte’s simple builtin stores, depending on the needs of a project.
Svelte may never be able to implement the equivalent of React’s concurrent mode. This could be a big deal and it’s probably the weakest part of my recommendation to my team. See the discussion above for more about concurrent mode. Rich Harris intends to implement an equivalent to React’s suspense, so it appears React’s advantage there is temporary. Svelte has a history of surprising innovations but we shouldn’t count on this one.
React and other mainstream frameworks work great. Is Svelte worth the time and risk? We think so for our project.
Many of Svelte’s negative tradeoffs reflect its relative youth and not-yet-mainstream popularity. Today these are issues, but I expect them to be resolved as Svelte’s development and adoption continue.
Peripheral tooling is a work in progress. With React and TypeScript we can write fairly well-typed frontends with good buildtime error detection, featureful editor plugins, and mature devtool browser extensions. Svelte is its own language, not plain JS, so it needs specialized tooling. Svelte has decent editor support today but the plugins I’ve used have rough edges and missing features. Svelte’s TypeScript support is a work in progress being helped by a TypeScript team member. The community has been actively improving tools for the year I’ve been using Svelte (shoutout to @UnwrittenFun) but there’s much to do before the DX feels polished.
Svelte’s userland resources and cultural knowledge like patterns, anti-patterns, best practices, and consensus libraries are sparse and under-developed. People who adopt it today will have to think through problems where other communities have common knowledge solutions, making the learning curve temporarily steeper. Svelte’s beginner documentation is great but people are still figuring out what mastery looks like. Thoughtful feedback from experienced Svelte users is readily offered on Discord, and the community is active on Twitter, Reddit, and Stack Overflow, but not to the degree of React and Vue, which have vast communities and educational resources. Our development will be slowed as our team develops ideas about the best ways to build a big Svelte app. I have a lot of experience working on JS frontends and I enjoy the pattern frontier, so I’m personally excited about working in a fresh and chaotic ecosystem with my teammates. For us the slowdown is an acceptable cost and we see a meaningful opportunity to grow as developers.
Libraries are fewer in number and generally less mature. Depending on your project and team, this could be irrelevant, inconvenient, or a blocker. Even though Svelte has many quality choices for the basics like component sets, its library ecosystem is a fraction of the size of the major frameworks.
For our project this is not impactful — we’ll be writing most components from scratch for UX and DX reasons. We’re developing our own design language and we care a lot about customizability, consistency, and performance, and off-the-shelf components add significant friction here, especially in a less mature ecosystem. For short-term results, Svelte today may not have the libraries to meet one’s needs. We’re investing for the long-term. Implementing components oneself is one of the best ways to gain valuable experience as a developer, and we’re able and willing to spend the time to own our UI and level up along the way.
Svelte is known for its tantalizingly small JavaScript bundles, and compiler improvements sometimes shrink the output even more for free, but there’s a problem here. With its current compiler, as more components are added to a single bundle, Svelte’s JS size advantage shrinks and eventually reverses, because Svelte templates are compiled to a form that is more verbose than the source.
Rich Harris addresses this in the issue “Yes, but does it scale?”, saying that code splitting should usually make Svelte websites much smaller, and notes that in the future, Svelte could optionally send a template bytecode instead of compiled JS to clients, substantially lowering bundle sizes after paying the cost of the interpreter. However today there is no such Svelte template interpreter. A large majority of websites will not have this problem, but our project is going to have a heavy UI metasystem similar to an IDE, with components that are more difficult to code split and lazy load. Our base JS cost may be larger than the equivalent in other frameworks if we don’t pull off some wizardry.
Our project is an open source community platform that seeks to build a community around its source code, and Svelte is going to be a barrier to some would-be contributors — not because it’s difficult to learn (as mentioned earlier, I think quite the opposite) — but because many people develop an understanding of a single framework, structure their thinking around its patterns, and remain in its garden, often for employment reasons. Some people who would jump into a React or Vue project won’t look twice at a Svelte codebase — this can be mitigated but not ignored. On the bright side, Svelte may attract some people who have the time and motivation to learn a new framework, and it’s approachable for web developers of any experience level.
There are few jobs for Svelte right now. Our team members are developing skills that might not directly translate to future employment. In my experience, learning multiple frameworks was tremendously helpful for rounding out my frontend skills.
There’s no full-time team supporting Svelte — its developers are part-time volunteers. Bugs get fixed, features get added, and many professionals rely on it in production, but unlike other major frameworks, nobody is being paid to work on it full-time. Rich likes his dayjob, but it seems likely that funding will be available to the dev team in the future, if they want it.
Is using bleeding edge tech risky and foolish? How much blood are we talking about? My experience tells me Svelte is a safe choice, more leading edge than bleeding. However I’m more risk tolerant than most people, I have a lot of experience with JS frameworks, and our team is motivated, so we can deal with rough edges. We’re happy to pay the costs of early adoption when a technology provides significant advantages, and that’s our bet for Svelte.
Evidence of growth, buyin, mindshare, etc:
- there’s a lot of logos and faces at svelte.dev
- Svelte is one of the 6 JS frameworks in the (flawed) State of JS 2019 survey — 75% have heard of it, 7% have used it, and 45% are interested in learning more
- GitHub stars in March 2020 (the best metric obv) — React has 145k, Vue 159k, Angular 59k, Svelte 31k, Preact 26k, and Ember 21k
- lots of local meetup groups have formed in the last year
- IBM recently implemented their Carbon design system in Svelte and Apple is hiring for Svelte
- npm trends shows consistent growth since v3 was released in early 2019
- active community — tweet @sveltejs — chat on Discord — unofficial subreddit /r/sveltejs
With the caveat that hero worship can be gross, distorting, and unhelpful to everyone involved, Svelte author Rich Harris (@rich_harris on Twitter) is one of my favorite open source developers. In the JS community he’s well-known among tool authors for spreading interesting ideas. He’s the creator of many open source projects including Rollup, the bundler of choice for many libraries including React and Vue. Here are some of his inspiring talks about Svelte:
Alright! Was that a fairly thorough and persuasive overview? I hope you’ll consider Svelte next time you want to play around with some new technologies and see it as a worthwhile option for making awesome software for people.
Want to learn more? The interactive Svelte tutorial is a good place to start. The examples are a good followup, and the API docs and Discord community can help you from there. The basic template is a good way to begin making stuff, or jump in with Sapper, the officially supported app framework equivalent of React’s Next.js and Vue’s Nuxt.js. And finally, the Svelte community repo is a nice door into the ecosystem.
Discuss this post on the web:
- /r/javascript — /r/webdev — /r/sveltejs
- lobste.rs
- Hacker News
- Tildes
- tweet me @ryanatkn and see the tweet for this post
- please feel free to open an issue here on GitHub with questions/comments/improvements/etc
It’s worth mentioning that Svelte limits its scope to being only a UI component framework. Like React, it provides just the view layer. Others like Angular and Vue provide a more all-in-one solution with official routers, state management, and more. Sapper is Svelte’s official app framework that adds routing, server-side rendering, and some other essential app features, but it has no opinions about state management and beyond. Some devs prefer Svelte’s minimal approach that defers problems to userland, encouraging more innovation, choice, and fragmentation, and other devs prefer a more fully integrated toolkit with a well-supported happy path.
The project that prompted this post is Felt, a super customizable community platform. We’re in the planning phase right now — felt.dev has an early mockup, felt.social has a mailing list signup, and we’re @feltcoop on GitHub and Twitter. Felt is open source, easily self-hosted, and owned by a worker co-op with the future goal of becoming a platform co-op. The name was inspired by Svelte so our bias goes deep. :]
Written by Ryan Atkinson (@ryanatkn)
with special thanks to
Hamilton Reed (@greatbacon),
Robert Hall (@arxpoetica),
and @pngwn (),
and extra special thanks to the Svelte team and community
for the wonderful experience. 💚