Svelte vs React: First impressions

Murat Catal
Oct 16 · 7 min read
Photo by Coffee Geek on Unsplash

3 years ago, Rich Harris created a framework which is called Svelte. The biggest impact on that new framework was that it’s not working on Virtual DOM like ReactJS, VueJS or AngularJS.

I created exactly same todo list application both in Svelte and React. What i mean with exactly is not only about its functionality or visuality but also i did not used any 3rd party libraries and used their internal APIs to manage a working application.

Our todo application will have listing, adding and removing items. Each items will be stored in a global state. Also there will be component which will subscribe global store and will show current value whenever it changed

Both Svelte and React source codes are on github

Todo list

SvelteJS

$ npx degit sveltejs/template svelte-todo-list

Brief information about Svelte

  • Works on DOM, no Virtual DOM

ReactJS

$ npx create-react-app react-todo-list

Brief information about ReactJS

  • Works with Virtual DOM

Some code comparisons

Let’s compare some key points between Svelte and React.

App.svelte

<script>
import TodoHeader from "./TodoHeader.svelte";
import TodoList from "./TodoList.svelte";
import { itemStore } from "./store";
</script>
<style>
main {
font-family: sans-serif;
text-align: center;
}
</style>
<main>
<div>Total item: {$itemStore.length}</div>
<TodoHeader />
<TodoList />
</main>

App.js

import React from 'react';
import './App.css';
import { TodoHeader } from './TodoHeader';
import { TodoList } from './TodoList';
import { TodoListProvider } from './store';
import { Total } from './Total';
function App() {
return (
<TodoListProvider todoList={[]}>
<Total />
<TodoHeader />
<TodoList />
</TodoListProvider>
);
}
export default App;

App files are entry points in both framework. There is not much difference between two, they both have components to render. The only difference is here that global style binding. In React, a Wrapper Component for React.ContextAPI is a parent of all children whereas in Svelte, you do not need a wrapper for global state.


svelte/store.js

import { writable } from "svelte/store";const createItemStore = () => {
const { subscribe, update } = writable([]);
return {
subscribe,
addItem: newItem => update(items => {
if (!items.find(item => item === newItem)) {
items.push(newItem);
}
return items;
}),
removeItem: removedItem => update(items => {
const newItems = items.filter(item => item !== removedItem);
return newItems;
})
};
};
export const itemStore = createItemStore();

react/store.js

import React, { useState } from 'react';export const TodoListContext = React.createContext({});export const TodoListProvider = ({ todoList, children }) => {
const [todos, setTodos] = useState(todoList);
const addItem = (item) => {
if (!todos || !todos.find(listItem => listItem === item)) {
setTodos([...todos, item])
}
};
const removeItem = (item) => {
setTodos(
todos.filter(listItem => listItem !== item)
)
};
return (
<TodoListContext.Provider
value={{
todoList: todos,
addItem,
removeItem
}}
>
{children}
</TodoListContext.Provider>
)
}
export const TodoListConsumer = TodoListContext.Consumer;

These two store does same things. They have both action methods to mutate store data. However, in React using Context API and creating same structure like in Svelte can be some painful. As shown in above example, at first, we created a Context from createContext and in our Provider we had to use hooks to store values locally. Things are more simpler in Svelte, you just create a writeable store and initialize its value and return your value with its actions.


svelte/TodoList

<script>
import { itemStore } from "./store";
const handleRemoveItem = item => {
itemStore.removeItem(item);
};
</script>
<style>
ul {
list-style-type: none;
}
</style>
<ul>
{#each $itemStore as item}
<li>
{item}
<button on:click={() => handleRemoveItem(item)}>Remote Item</button>
</li>
{/each}
{#if $itemStore.length === 0}
<div>There is not any item added. Please add one</div>
{/if}
</ul>

react/TodoList

import React, { useContext } from 'react';
import { TodoListContext } from './store';
export const TodoList = () => {
const todoListContext = useContext(TodoListContext);
const handleRemove = (item) => {
todoListContext.removeItem(item);
}
const { todoList } = todoListContext;return (
<ul>
{todoList && todoList.map(todoList => {
return (
<li>
{todoList}
<button onClick={handleRemove.bind(null, todoList)}>Remote Item</button>
</li>
)
})}
{(todoList.length === 0) && (<div>There is not any item added. Please add one</div>)}
</ul>
)
}

The thing that forced me writing my first Svelte application was using conditions and loops in component. Using syntax another then pure javascript for loops or conditions are the things i do not like. But, accessing store item with only import and not needing to any external hook or layer for accessing global store is the key difference between Svelte and React.


svelte/TodoHeader

<script>
import { onMount } from "svelte";
import { itemStore } from "./store";
let value;
onMount(() => {
value = "";
});
const handleAddItem = () => {
itemStore.addItem(value);
value = "";
};
</script>
<style>
.disabled {
color: graytext;
}
</style>
<input type="text" bind:value placeholder="Item name" />
<button on:click={handleAddItem} disabled={!value} class:disabled={!value}>
Add Item
</button>

react/TodoHeader

import React, { useContext, useState } from 'react';
import { TodoListContext } from './store';
export const TodoHeader = () => {
const todoListStore = useContext(TodoListContext);
const [itemName, setItemName] = useState('')
const handleAddItem = (e) => {
e.preventDefault();
todoListStore.addItem(itemName);
setItemName('');
}
return (
<>
<input placeholder="Item name" type="text" value={itemName} onChange={(event) => setItemName(event.target.value.trim())} />
<button onClick={handleAddItem} disabled={!itemName} className={!itemName && 'disabled'}>Add Item</button>
</>
)
}

In Svelte, you do not need to store your input’s value in a state externally. Svelte makes it easier with binding keyword to any existing property, with a plus additional feature that you can track that prop changes with reactive declaration without extra effort for values (not for arrays).


Results

Also, let’s share some results about building process, difficulty and conveniences which i faced while developing.

I followed exactly same pattern while developing both. I did not use any external libraries and used only internal API’s both frameworks support. There are components connected to global state. There are components subscribed to global state variables.

What i like in Svelte ❤️

  • Building is really fast. But this may be also because of using Rollup as a bundler, i think it would be good to test bundling with Webpack also.

What i dislike in Svelte 💔

  • I really do not like writing templates in a file, such as #each , #if. I do not like to prefer using new approaches for which i can do it with purely in JavaScript.

Production Build Comparison

SvelteJS uses Rollup and ReactJS Webpack in defaults and i didn’t touched their configurations, they have both default configuration. Svelte built time was 1.40s where React builds 5.49s. Here Svelte wins! ❤️

Build Times

Both application is server by serve npm package. Svelte exports its bundles into public folder whereas react app put them into build folder.

serve -s build  // this is for react app
serve -s public // this is for svelte app

When i checked network tab, Svelte’s bundle is just 2.9 KB after gzip whereas React’s bundle is just 42.1 KB after gzip. here again Svelte w️️ins with its bundle sizes on production ❤️

Svelte vs React in production build instead of size

If you like my articles, you can support me by clapping and following me.
I’m also on
linkedin, all invitations are welcome.

JavaScript in Plain English

Learn the web's most important programming language.

Murat Catal

Written by

Enjoys sharing!

JavaScript in Plain English

Learn the web's most important programming language.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade