A comparison between React & Svelte

Mayank C
Tech Tonic

--

Among the front-end frameworks, React and Svelte have emerged as contenders, each offering distinct approaches and advantages. This article presents a comparative analysis of React and Svelte, starting with a bit of history, current popularity, core functionalities, potential trade-offs, and three simple applications to help developers/leads/architects in taking the right decisions for their projects.

History

React was created in 2013 by Jordan Walke, an engineer at Facebook, initially for internal use. Its innovative concept of leveraging a virtual DOM (Document Object Model) for efficient updates got widespread attention, leading to its adoption by an extensive community of developers. Today, React enjoys immense popularity. It has one of the largest active developer communities and a vast ecosystem of libraries and tools.

Svelte emerged in 2016, developed by Rich Harris with the aim of offering a different paradigm for building user interfaces. By adopting a compile-time approach, Svelte eliminates the need for a virtual DOM, resulting in smaller bundle sizes and potentially faster performance. Although younger than React, Svelte has garnered significant traction with its focus on simplicity, efficiency, and developer experience.

Popularity and Community Support

According to the 2023 State of JS survey, React remains the most popular JavaScript framework, used by nearly 67% of respondents. Svelte, though having an impressive growth, holds a lower share at approximately 13%. However, alternative metrics like GitHub stars and developer satisfaction surveys suggest a closer contest. Svelte consistently ranks high in developer happiness, and often surpasses React in these measures.

Both frameworks benefit from active communities. React’s community is larger and more established, offering extensive documentation, tutorials, and third-party resources. Svelte’s community, while smaller, is known for its strong engagement and rapid growth, actively creating libraries and tools to expand the framework’s capabilities.

The following graphs show their comparison taken from Google search trends:

Blue is React & Red is Svelte

The following is a comparison of the GitHub stars:

Core Functionalities and Architectural Approaches

Component-based architecture

Both React and Svelte have a component-based architecture, where applications are structured as reusable building blocks. This approach promotes modularity, maintainability, and code reusability.

Template syntax

React uses JSX, a syntax extension for JavaScript that integrates HTML-like structures directly within JavaScript code. Svelte, in contrast, uses standard HTML, CSS, and JavaScript, with reactivity defined within components using declarative syntax.

State management

React relies on external libraries like Redux for complex state management scenarios. Svelte, on the other hand, offers built-in reactive functionalities for managing both local and global application state, potentially reducing dependence on additional libraries.

Virtual DOM vs. Compile-time approach

React utilizes a virtual DOM to compare the desired UI state with the actual DOM and efficiently update only the necessary elements. Svelte, through its compile-time approach, eliminates the need for a virtual DOM, potentially resulting in faster performance and smaller bundle sizes.

Potential Trade-offs and Considerations

Learning curve

React’s established ecosystem and extensive documentation provide a predictable learning curve for developers familiar with JavaScript. Svelte’s unique syntax and compile-time approach may require some additional learning for developers accustomed to more traditional frontend frameworks.

Ecosystem and Community Support

React’s larger community offers a wider range of readily available third-party libraries and components. However, Svelte’s rapidly growing community actively contributes to expanding its ecosystem, often focusing on providing lightweight and performant solutions.

Performance and Bundle Size

Svelte’s compile-time approach generally leads to smaller bundle sizes and potentially faster performance compared to React, especially for smaller and highly interactive applications. However, these benefits may not be as significant for larger projects with complex routing or data flows.

Maturity and Stability

React’s longer history and extensive testing contribute to its overall maturity and stability. Svelte, being younger, is still evolving and refining its feature set, although it receives frequent updates and enjoys widespread community support.

Pros and Cons

React: Pros

  • Extensive ecosystem and mature tools: React enjoys a vast ecosystem of third-party libraries, components, and tools, readily available and well-tested. This simplifies development tasks and provides efficient solutions for most common challenges.
  • Large and active community: With a massive developer community, React offers extensive support, readily available answers to questions, and active participation in forums and discussions.
  • Component-based architecture: React’s well-established component structure promotes code reusability, modularity, and maintainability, leading to cleaner and more manageable codebases, especially for large-scale projects.
  • Job market demand: React consistently ranks as one of the most in-demand skills in the web development job market. Mastering React can provide developers with career opportunities and access to various job possibilities.

React: Cons

  • Steeper learning curve: React’s unique syntax (JSX) and reliance on external libraries like Redux for complex state management can create a steeper learning curve for beginners compared to some frameworks.
  • Potential performance overhead: While performant overall, React’s use of a virtual DOM might introduce slight performance overhead in highly interactive applications compared to frameworks with compile-time approaches.
  • Over-reliance on third-party libraries: The vast ecosystem can sometimes lead to over-reliance on third-party libraries, potentially increasing bundle size and introducing compatibility concerns.

Svelte: Pros

  • Simpler syntax and learning curve: Svelte’s utilization of standard HTML, CSS, and JavaScript simplifies the learning process for developers familiar with these technologies. Its clear and declarative syntax promotes easy readability and understanding.
  • High performance and small bundle size: The compile-time approach eliminates the need for a virtual DOM, leading to smaller bundle sizes and potentially faster performance, especially for smaller and interactive applications.
  • Built-in state management: Svelte’s integrated reactive mechanisms for managing local and global state potentially reduce the need for additional libraries like Redux, simplifying the development process.
  • Developer experience focus: Svelte prioritizes developer experience through features like built-in error handling, clear output during compilation, and a concise debugging experience.

Svelte: Cons

  • Emerging ecosystem and community: Compared to React, Svelte’s ecosystem of libraries and tools is still under development, requiring developers to sometimes create custom solutions or rely on fewer options.
  • Younger framework and evolving features: While rapidly maturing, Svelte’s younger age means some features might be less stable or polished compared to more established frameworks like React.
  • Learning curve for unique approach: While simple at its core, Svelte’s compile-time approach and syntax might require developers accustomed to traditional frameworks to adapt to a new paradigm.
  • Job market adoption: Although growing, Svelte’s adoption in the job market is currently lower than React. This may limit job opportunities specifically requiring Svelte experience.

Use case 1 — Button counter application

Let’s move beyond the theory and get into some code samples. We’ll start with the classic button counter problem. This is almost like a ‘hello world’.

React app

The React counter app uses three main components:

  1. Counter: This component manages the state (count) and renders the current value. It also holds two buttons: "+" and "-". Clicking these buttons triggers functions that update the count state using useState hook.
  2. IncrementButton: This component simply fires an event when clicked, notifying the Counter component to increase the count by 1.
  3. DecrementButton: Similar to the IncrementButton, this component triggers an event, prompting the Counter to decrease the count by 1.

Here’s a snippet of the Counter component:

function Counter() {
const [count, setCount] = useState(0);

const increment = () => setCount(count + 1);
const decrement = () => setCount(count - 1);

return (
<div>
<span>{count}</span>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
</div>
);
}

Svelte app

Svelte takes a more integrated approach:

  1. Counter.svelte: This single component defines the entire counter functionality. It directly uses HTML for layout and JavaScript for logic.
  2. The count variable holds the current value displayed within an <span>.
  3. <button on:click> events directly bind to functions that manipulate the count variable reactively, removing the need for separate event handlers.

Here’s the core logic of the Counter.svelte component:

<script>
let count = 0;

function increment() {
count++;
}

function decrement() {
count--;
}
</script>

<span>{count}</span>
<button on:click={increment}>+</button>
<button on:click={decrement}>-</button>

Use case 2 — Dark and Light Theme

Modern web applications enhances user preferences by offering light and dark theme options. Let’s see how React and Svelte approach implementing this functionality.

React app

  1. CSS Classes: Define distinct CSS classes for both light and dark themes, targeting common elements like text color, background, and borders.
  2. State Management: Use a state management library like Redux or Context API to store the current theme preference (e.g., “light” or “dark”).
  3. Conditional Rendering: Based on the theme state, conditionally apply the appropriate CSS class to the main app container or individual components.
// CSS
.light-theme {
background-color: #fff;
color: #000;
}

.dark-theme {
background-color: #000;
color: #fff;
}

// App.js
import React, { useState } from 'react';

function App() {
const [theme, setTheme] = useState('light');

const toggleTheme = () => setTheme(theme === 'light' ? 'dark' : 'light');

return (
<div className={`App ${theme}-theme`}>
{/* App content */}
<button onClick={toggleTheme}>Toggle Theme</button>
</div>
);
}

Svelte app

  1. CSS Variables: Define separate CSS variables for relevant theme properties like colors and backgrounds.
  2. Reactive Logic: Within Svelte components, manipulate these variables based on user interaction or system preferences.
  3. Direct Application: Use the manipulated variables directly within styles, eliminating the need for conditional rendering.
<script>
let isDarkMode = false;

function toggleTheme() {
isDarkMode = !isDarkMode;
}
</script>

<style>
:root {
--background-color: #fff;
--text-color: #000;
}

.dark-mode {
--background-color: #000;
--text-color: #fff;
}
</style>

<body class:dark-mode={isDarkMode}>
{/* App content */}
<button on:click={toggleTheme}>Toggle Theme</button>
</body>

Use case 3 — Countdown Timer

React app

  1. State: Utilize variables within React state to store values like remaining time and end time.
  2. useEffect Hook: Set up an interval using useEffect that repeatedly updates the remaining time in the state based on the initial setting and current time.
  3. Conditional Rendering: Based on the remaining time, display the current value or trigger an “expired” message and clear the interval.
import React, { useState, useEffect } from 'react';

function CountdownTimer(props) {
const [remainingTime, setRemainingTime] = useState(props.duration);

useEffect(() => {
const interval = setInterval(() => {
setRemainingTime(Math.max(0, remainingTime - 1000));
}, 1000);

return () => clearInterval(interval);
}, []);

return (
<div>
{remainingTime > 0 ? (
<span>{remainingTime / 1000}s</span>
) : (
<span>Expired!</span>
)}
</div>
);
}

Svelte app

  1. readable Function: Utilize Svelte's readable function to create a reactive timer that automatically calculates the remaining time based on the initial setting and current time.
  2. Direct Binding: Bind the timer’s output directly to elements within the template, displaying the current value dynamically.
  3. Conditional Rendering: Based on the timer’s value, conditionally display the remaining time or an “expired” message.
<script>
let duration = 5;
let remainingTime = readable(duration, (set) => {
const interval = setInterval(() => {
set(Math.max(0, duration - new Date().getTime()));
}, 1000);

return () => clearInterval(interval);
});
</script>

<span>{remainingTime}s</span>

<span if={remainingTime <= 0}>Expired!</span>

That’s all about. Thanks for reading!

--

--