Svelte is a popular component-based frontend framework. Let’s discuss what Svelte is, outline why you might choose it for your next project, cover its key features, and elaborate on what sets Svelte apart from other frameworks.
Svelte is a component-based frontend framework. It’s similar to frameworks such as React, Vue, and Angular, which all share the goal of making it easier to build modular, interactive user interfaces.
Svelte is the fourth most popular frontend framework after Angular (third), Vue (second), and React (first). It was voted the most admired JavaScript web framework in the 2023 Stack Overflow Developer Survey. In other words, it’s evident that developers love using Svelte.
Svelte was created by Rich Harris when he was working as a graphics editor at The Guardian newspaper. Rich created the framework out of his own frustration with the frontend framework landscape circa 2015. In 2019, after the release of Svelte 3, it started to gain more traction with frontend developers.
Rich created Svelte as a response to the web’s JavaScript bloat crisis. The bundle size of JavaScript frameworks was growing year over year.
The status quo was for everything to be done at runtime in the browser. Frameworks such as React had to be run in the browser alongside the application code, leading to slower loading times and other performance constraints. Svelte took a very different approach, earning its tagline of “the magical disappearing UI framework.”
Fundamentally, Svelte is a compiler. It converts your components into a tiny, framework-less vanilla JavaScript bundle at build time. This approach ensures that you don’t incur a heavy penalty when your app first loads, which would happen with other frameworks.
Svelte takes a holistic view of what a developer requires to make a frontend application. The objective is to save you the time it would take to trawl npm for the bare necessities. It has built-in support for scoped styling, form bindings, state management, animations, motion, and more.
Additionally, Svelte has built-in code quality tool called svelte-check
that can detect unused CSS and provide accessibility hints.
You can use Svelte to build an app from scratch or add it incrementally to an existing codebase. Although you need to add a preprocessor, you can also use TypeScript within Svelte components.
Since Svelte is a compiler, it’s easy to change output targets without having to change your component’s code. For example, Svelte supports server-side rendering (SSR) out of the box by providing a compiler mode for it.
Svelte also has an official application framework called SvelteKit that is a one-stop shop for building modern, multi-page web apps. It has various integrations that allow you to use the various flavors of JavaScript and CSS, such as TypeScript, PostCSS, SCSS, Less, Stylus, and SugarSS.
Svelte has three distinguishing characteristics:
Let’s discuss how each of these core characteristics benefits developers.
Svelte wants developers to be more productive. Reducing the amount of code you have to write is one of its explicit goals. It wants to reduce boilerplate and favor patterns that allow developers to naturally write less code.
One example is state variables. In Svelte, you update local component state with an assignment operator:
let count = 0; function increment() { count += 1;}
While in React, you use the useState
Hook:
const [count, setCount] = useState(0); function increment() { setCount(count + 1);}
Svelte is expressing the exact same concept, but with over 60 percent fewer characters.
Another example is reactive declarations, which essentially do the same work as React’s useMemo
, useCallback
and useEffect
Hooks without the boilerplate. This is possible because Svelte is a compiler and isn’t constrained to the peculiarities of JavaScript. The focus is on creating the best component authoring experience, rather than having to fit it around the semantics of the language.
There are several other things that make coding in Svelte more succinct. You can read more about this in the Svelte team’s Write less code article.
A core requirement of a frontend framework is the ability to react to state changes in user interfaces. To do this, the application’s state needs to be tracked by the framework. When a change is detected, the data and the DOM need to be synchronized.
The challenge is that it’s expensive to frequently re-render the user interface. So, then, how do you minimize re-rendering?
Frameworks such as React started to use a virtual DOM (VDOM) to address this challenge. The VDOM is a programming concept where an ideal representation of a UI is kept in memory and synced with the “real” DOM.
This approach works by re-rendering your entire application to the desired state in the VDOM for each state change. Then, it has the framework work out the minimum number of changes required (diffing) to bring the browser’s actual DOM in line with that desired state (reconcilation).
Although this minimizes re-rendering, the problem with the VDOM is that its operations are performed in addition to the eventual operations on the real DOM. The overhead is high for both CPU and memory usage.
Svelte took a different approach to this problem. It knows at build time how things can change in your app. Instead of keeping an in-memory copy of the DOM, Svelte knows precisely what should be updated and does it directly in the DOM. This proves to be more efficient.
Reactivity is a first-class citizen in Svelte. Svelte uses compile-time reactivity, using let
, =
, the export
keyword, and the $:
label to identify reactive state. Dependents of a variable are determined when Svelte compiles your component. You are mostly writing regular, vanilla JavaScript.
As an app grows in complexity, dealing with shared state between components gets increasingly complex and problematic. You might have more trouble identifying how app-wide state changes cascade to different parts of an app. This becomes easier to track and maintain if we follow design patterns such as the observer pattern, which is where state management libraries can help.
Many other frameworks have separate state management libraries. React has many, such as Redux and MobX, to name just two examples. Most of these libraries require you to use a particular function to set and update the state, and another function to subscribe for updates.
Svelte provides its own built-in lightweight global state management solution called stores. This provides complete reactivity in the simplest possible way. It cuts out the setting and subscribing logic by adding it during compilation.
Svelte 5 looks to unlock universal, fine-grained reactivity with runes. It addresses some of the reactivity gotchas that can come with more complex and demanding apps, leading to puzzling, undocumented behaviors.
Components are the building blocks of Svelte applications. They’re written in .svelte
files.
Since Svelte is a superset of HTML, the contents of these files resembles a HTML file with HTML markup, CSS styles includes in a <style>
block, and JavaScript included using a <script>
block:
<script> // logic goes here </script> <!-- markup (zero or more items) goes here --> <style> /* styles go here */ </style>
Often, this is referred to as a single file component (SFC).
Being a compiler, Svelte can extend HTML, CSS, and JavaScript without any runtime overhead. To implement templating, Svelte extends these languages in the following ways:
{#if answer === 42} What was the question? {/if}
svelte-123az
$:
, using JavaScript’s label syntax. Svelte 5 has taken this further by adding runes — including symbols such as $state
, $derived
, and $effect
— to provide universal, fine-grained reactivityExtensions to the JavaScript language are minimal and are carefully picked to avoid breaking JavaScript syntax or alienating developers. In fact, you will be mostly working with vanilla JavaScript when using Svelte. The compiler only intervenes in specific situations for .svelte
files.
To understand what the compiler outputs, you can look at the examples on the Svelte website. It has a code playground (called a REPL) that shows examples. Different tabs in this playground show the Svelte source code, the rendered result, the JavaScript output, and CSS output. Below is the “hello world” example:
Svelte source code:
<script> let name = 'world'; </script> <h1>Hello {name}!</h1>
JavaScript output:
/* App.svelte generated by Svelte v4.2.18 */ import { SvelteComponent, detach, element, init, insert, noop, safe_not_equal } from "svelte/internal"; import "svelte/internal/disclose-version"; function create_fragment(ctx) { let h1; return { c() { h1 = element("h1"); h1.textContent = `Hello ${name}!`; }, m(target, anchor) { insert(target, h1, anchor); }, p: noop, i: noop Reactive statements, o: noop, d(detaching) { if (detaching) { detach(h1); } } }; } let name = 'world'; class App extends SvelteComponent { constructor(options) { super(); init(this, options, null, create_fragment, safe_not_equal, {}); } } export default App;
Looking at Svelte’s version history can help us understand why and how it works today:
You can learn more about the new features coming up in Svelte 5 from the preview documentation, as well as by watching Rich Harris’s presentation from the most recent Svelte Summit. The highlights include:
We’ve talked about some compelling reasons to use Svelte already. But let’s get into some more detail about important factors to consider: the learning curve, performance, bundle size, DX, documentation, integrations, and community & ecosystem.
Svelte prides itself on being incredibly easy to learn. It sticks closely to the classic web development model of HTML, CSS, and JavaScript.
Arguably, Svelte has fewer concepts and tools to learn than many other framework options. You can get started writing Svelte apps in a matter of minutes.
Svelte applications are fast, generally outperforming both React and Vue. The key is that Svelte optimizes everything at build time. It produces highly optimized vanilla JavaScript that has a minimal runtime overhead.
Not only that, but Svelte is getting faster. Svelte 4 creates smaller and faster hydration code than previous versions. The expectation is that Svelte 5, which will be a rewrite of the Svelte compiler and runtime, should yield further improvements.
Svelte produces small bundles. The prototypical ToDoMVC application creates a bundle of HTML, CSS, and JavaScript of the following sizes in the different frameworks:
Subsequent releases of Svelte have improved the bundle size. For example, on the kit.svelte.dev website, the JavaScript generated across the whole site was reduced in size by 12.7 percent (from 126.3 kB to 110.2 kB) when it was upgraded from version 3 to version 4.
Svelte is a superset of HTML and has less abstractions than other frameworks. As discussed above, Rich Harris made DX a key concern of the framework. He put a strong emphasis on the readability of the syntax and favoring patterns that allow developers to naturally write less code.
This extends to many details, including removing redundant constraints (such as not requiring a single top-level element), providing convenient conventions (such as making variables reactive through labeled statements), and providing shorthands.
This care and attention to syntax results in shorter, more succinct components. It enable you to express ideas more concisely. The difference is that a Svelte component is typically around 40 percent smaller than its React equivalent.
Svelte also has many out-of-the-box features that other frameworks don’t, such as state management, animations, and a plugin system. You don’t need to go searching for third-party solutions as often as you might when using other frameworks.
Lastly, Svelte has built-in code quality checking. It gives feedback on accessibility and unused CSS. For example, whenever you forget to put the alt
attribute on an <img>
tag, Svelte will display a warning like so:
A11y: <img> element should have an alt attribute
The official Svelte site is well written and maintained. It has an excellent interactive tutorial, a collection of examples, and clear docs. You can try Svelte online using the REPL without needing to configure anything.
Mozilla Developer Network (MDN) has a Svelte Guide. As an established and popular framework, you can find a plethora of tutorials and courses on Svelte.
Svelte provides a lot of features out of the box that relieve you of the burden of looking for third-party solutions. As Svelte is a mature framework, it has an excellent choice of integrations.
Svelte removes some constraints that you can encounter with other frameworks that build components on top of JavaScript. You can write more idiomatic JavaScript in Svelte, which can make it easier to integrate with other libraries, and there is less need for wrapper libraries as well.
The official application framework for Svelte is SvelteKit, though other application frameworks such as Astro support Svelte as well. SvelteKit allows you to build a multi-page application using Svelte components. It provides all the pieces you need to build a modern web app such as:
…and more.
There are plugins for all the major web bundlers to handle Svelte compilation, such as Vite (vite-plugin-svelte) and webpack (svelte-loader). They will output .js
and .css
files that you can insert into your HTML. There are also plugins for major testing frameworks to enable testing a Svelte codebase, such as Vitest and Playwright.
Furthermore, there is a good selection of component libraries compatible with Svelte, such as Flowbite, Skeleton, and Bits UI.
You can also find Svelte integrations for major code editors such as:
Svelte can also be used for mobile development via Svelte Native.
You can explore Svelte Society’s list of packages to find other integrations.
Svelte is an open source project that has a core team and many volunteer contributors. A volunteer organization called Svelte Society promotes Svelte and its ecosystem. They run a quarterly Svelte Summit. It is a well-loved and maintained project.
Though it’s open source, there are many established companies using Svelte, and it has sufficient financial backing. Rich Harris joined Vercel to work full-time on the project in 2021. Svelte also has an open collective organization and receives funding from the open source community.
As mentioned earlier, Svelte provides an interactive playground called the REPL (short for Read–Eval–Print Loop) that enables you to write and save Svelte applications in the browser. It’s the easiest way to get started with Svelte.
You can use the REPL any machine without having to install anything. If you want to share an idea, ask for help, or report an issue, it’s always extremely useful to create a REPL instance demonstrating the issue.
If you’d like a more fully-featured environment in the browser, you can try Svelte on StackBlitz.
The Svelte team recommends using SvelteKit for new projects:
npm create svelte@latest myapp cd myapp npm install npm run dev
SvelteKit manages the Svelte compiler and provides all the other pieces you need to build a complete multi-page web application such as a development server, routing, deployment, and SSR support.
If you want a minimal setup, you can use Svelte with Vite. You can scaffold a project by running npm create vite@latest
and selecting the svelte
as the framework. It will create a skeleton project for you:
With this, npm run build
will generate HTML, JS, and CSS files inside the dist
directory. This will enable you to to build a single-page app. If you want to build a multi-page app, you will need to choose a routing library as well.
Let’s take a quick walk through some of the key features of Svelte. I recommend the interactive tutorial on svelte.dev to learn more.
In Svelte, an application is composed of one or more components. A component is the atomic unit that contains everything that is needed to render a piece of the UI. It’s written in a .svelte
file that resembles a HTML file and contains HTML, CSS, and JavaScript:
<script> // logic goes here </script> <!-- markup goes here --> <style> /* styles go here */ </style>
All three sections — script
, styles
, and markup
— are optional.
To demonstrate the basic premise, let’s create a component that issues a simple greeting where you provide the name:
<!-- Greeting.svelte --> <script> let name = 'Joe'; </script> <h1>Hey <span>{name}</span>!</h1> <style> span { color: hsl(12,94%,62%); } </style>
Here’s the result:
Here is the demo.
The name of the component is taken from the file name. The convention is to capitalize the names of the components to distinguish them from HTML elements, which is why we named the above component Greeting.svelte
.
It would be impractical to put your entire app in a single component! You can nest components by importing components from other files and including them in your markup:
<!-- App.svelte ---> <script> import Greeting from './Greeting.svelte'; </script> <p>Below is our nested component 👇</p> <Greeting />
Svelte uses let
, =
, the export
keyword, and the $:
label to identify reactive states. Dependents of a variable are determined when Svelte compiles your component.
Let’s do the obligatory counter example that increments a number when a button is clicked:
<script> let count = 0; const increment = () => { count += 1; }; </script> <button class="button" on:click={increment}> Count is {count} </button>
You work with a variable as you do in vanilla JavaScript. You declare a variable with let
, and add 1 to its value! Svelte will take care of the updates to the DOM for you.
Here is the demo.
Often, some parts of a component’s state need to be computed from other parts, such as a fullname
derived from a firstname
and a lastname
. For these situations, Svelte has reactive declarations.
For example, we could do the following to show the square of the count variable:
<script> let count = 0; $: squared = count * count; </script>
Now any time count
changes, squared
is recomputed. If a reactive statement consists entirely of an assignment to an undeclared variable, Svelte will inject a let
declaration on your behalf. We can use squared
in our markup the same as count
:
<div>Squared: {squared}</div>
Here’s the result:
Here is the demo.
Styles are added to a <style>
block. All styles are scoped to a component by default. Svelte adds a class with a hashed value to each style rule in the output CSS.
The style block from our greeting example:
<style> span{ color: hsl(12, 94%, 62%); } </style>
Becomes this:
span.svelte-1mdkc4p { color:hsl(12,94%,62%); }
Svelte also allows you to provide global styles from within a Svelte component by using :global
should you need it:
<style> :global(.noscroll) { overflow: hidden; } </style>
However, typically, you would have a separate global stylesheet.
In an application, you’ll need to pass data from one component down to its children. To do that, you need to declare properties (props). In Svelte, this is done with the export
keyword.
For example, in a to-do app, you have a list of items you need to do. We can create a TodoList
component that receives an array of to-dos. We declare the array with export
and name it todos
:
<!-- TodoList.svelte --> <script> export let todos = []; </script> {#if todos.length > 0} <ul> {#each todos as todo} <li >{todo.name}</li> {/each} </ul> {:else} <p>Congratulations, all done!</p> {/if}
Now, we can supply our to-do items to the TodoList
component with the todos
prop (attribute):
<!-- App.svelte --> <script> import TodoList from "./components/TodoList.svelte"; let todos = [ { id: 1, name: "Create a Svelte starter app", completed: true }, { id: 2, name: "Create your first component", completed: true }, { id: 3, name: "Complete the rest of the tutorial", completed: false } ]; </script> <TodoList todos={todos} />
Now, the app shows the list of our to-dos! You may want to augment it to edit the items:
Here is the demo.
Svelte enables two-way binding between data and the UI through the bind
directive. This is especially useful with forms.
The simplest bindings reflect the value of a property such as input.value
. For example, if we want to change our greeting component to take a name from an user:
<!-- Greeting.svelte --> <script> let name = 'world'; </script> <input type="text" bind:value={name}> <h1>Hello {name}!</h1>
Now, any time we change the text in the input, it will update the <h1>
:
Here is the demo.
If the variable name matches the property name, you can use a shorthand:
<script> let value = 'world'; </script> <input type="text" bind:value>
To listen to DOM events, you use the on:
directive in the form of: on:eventname={handler}
.
When we want to respond to a button’s click we use on:click
as an attribute, and can provide a handler inline as below:
<button on:click={() => alert('clicked')}> Click me </button>
This will pop up an alert box saying clicked every time the button is clicked. Usually, you will have a separate event handler function in the <script>
block like we showed in our Counter
example.
DOM event handlers can have modifiers that alter their behavior. For example, a handler with a once
modifier will only run a one time:
<button on:click|once={() => alert('clicked')}> Click me </button>
Some other modifiers include:
preventDefault
— calls event.preventDefault()
before running the handlerstopPropagation
— calls event.stopPropagation()
, preventing the event reaching the next elementModifiers can be chained together; e.g., on:click|once|preventDefault={...}
.
For state management, Svelte provides its own built-in lightweight solution called stores. It cuts out the setting and subscribing logic by adding it during compilation.
You only need to create a readable, writable, or derived store. Then, you can use the reactive $store
syntax in components. It feels like using any other JavaScript variable:
<script> import { writable } from 'svelte/store'; const count = writable(0); console.log($count); // logs 0 $count += 1; console.log($count); // logs 1 </script>
It’s as simple as that.
Svelte can be used to build any type of modern web application. SvelteKit can produce a static site, single-page app, or a multi-page app that can be deployed to many web platforms. With Svelte Native, you can even build mobile applications.
Nevertheless, Svelte is particularly appropriate to tackle the following situations:
The output of a Svelte application is nothing more than a bunch of HTML, CSS, and JavaScript files. All you need is a web server capable of serving static files, and you can upload the output folder to deploy your app. This means you have plenty of deployment options to choose from.
You’re most likely to use Svelte through an application framework such as SvelteKit that will build and package the project for your target environment. SvelteKit provides adapters, so you can adapt it for your deployment target. You can read SvelteKit’s build and deploy documentation for more information.
While you can deploy your project manually, you probably will want to avoid that task!
To automate the process, it’s typical to have a CI/CD pipeline to deploy your app whenever a commit is pushed to a particular branch of a git repository. Platforms such as Vercel let you link a project to a repository on GitHub and other Git hosts. They’ll take care of triggering a deployment whenever changes are detected.
Most major hosting platforms have dedicated deployment guides for Svelte and SvelteKit:
Choosing between frameworks depends on many factors: project requirements, existing infrastructure, team expertise, and personal preferences, to name a few. This makes it difficult to give definitive advice on which framework to choose.
However, it’s useful to understand the strengths and weaknesses of each. Let’s look at how React and Vue compare to Svelte. These frameworks share the goal of making it easier to build modular, interactive user interfaces:
Svelte | React | Vue | |
---|---|---|---|
Learning curve | Easiest to learn. | Steepest learning curve due to its syntax, JSX, and ecosystem. | Gentle learning curve. |
Performance | Excellent performance. Svelte’s performance is particularly noticeable in smaller applications and animations. | React is the least performant of the three. It uses VDOM. It is best suited to larger scale apps. | Vue’s performance is generally considered to be good, especially for small to medium-sized applications. It uses the VDOM. |
Features | Svelte has many out-of-the-box features that other frameworks don’t such as advanced state management, animations, motion primitives, and a plugin system. You don’t need to go searching for third-party solutions often. SvelteKit is the official application framework. | React sees itself as more of a library. Its focus is on building stateful UIs. You need to use third-party libraries for solutions related to styling, advanced state management, and other concerns. Application frameworks such as Next.js to provide everything you need to make web apps. | Vue has a Single-File Component format similar to Svelte. It comes with scoped styling. It has official libraries for routing (Vue Router) and state management (Pinia). It has application frameworks such as Nuxt to provide everything you need to make web apps. |
Bundle size | Smallest bundle size. | Largest bundle size. | Moderate bundle size. |
Integrations | Svelte has all the base covered. What you find is that you don’t need to reach for as many libraries as React and Vue, and that wrapper libraries are often not necessary because Svelte favors writing idiomatic JavaScript.
However, overall the options are not as extensive as React’s or Vue’s. |
The popularity of React ensures a wide range of developer tools and a vast collection of community-driven libraries and frameworks are available. | Vue has a comprehensive ecosystem that rivals React’s. |
Support | Svelte is backed by Vercel with Rich Harris as a full-time employee. It is also supported by its open-source community. It is well supported but not as strongly as the other two. | React is supported by Facebook. It has the strongest support. | Vue has full-time resources on its core team that is funded by its open-source community. |
Community | Svelte has a growing community that is passionate about the framework. While not as large as React’s or Vue’s community, Svelte’s community is active and supportive. | React has one of the largest and most active communities among JavaScript frameworks. It has been adopted by many large companies and has a vast number of contributors and maintainers. | Vue is the second most widely used framework. It has a strong community. |
Documentation | Svelte has great documentation. | React’s documentation was lagging. It has improved a lot and now is of a good standard. | Vue’s documentation is the gold standard. It has always had high quality documentation. |
You can compare performance in a more rigorous way by consulting Stefan Krause’s js-framework-benchmark
project. Here are results based on the latest snapshot:
React is a popular and robust choice for large-scale applications, but it has shortcomings with regard to performance and developer experience. Vue is user-friendly and versatile — a solid choice all around. Svelte excels in simplicity and performance, it really shines for apps that are smaller and are data-intensive.
Consider the trade-offs and strengths of each framework before making your decision.
Svelte is a great frontend framework. With its emphasis on developer experience and simplicity, Svelte has won over many developers. It regularly outperforms its competitors, as a compiler-centric framework it produces highly optimized code with small bundle sizes.
Svelte has many out-of-the-box features that other frameworks don’t, and can’t offer as runtime-centric frameworks. It’s a mature and established framework with all the key integrations that you need to build modern web apps.
While Svelte is behind React and Vue in terms of popularity and community, it is continually growing. Svelte is definitely worth exploring for your next frontend project.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowConsider using a React form library to mitigate the challenges of building and managing forms and surveys.
In this article, you’ll learn how to set up Hoppscotch and which APIs to test it with. Then we’ll discuss alternatives: OpenAPI DevTools and Postman.
Learn to migrate from react-native-camera to VisionCamera, manage permissions, optimize performance, and implement advanced features.
SOLID principles help us keep code flexible. In this article, we’ll examine all of those principles and their implementation using JavaScript.