Getting Started with Svelte from React Developer Perspective, with Code Comparison

Muhammad Syakirurohman
Frontend Engineer
Published on
Getting Started with Svelte from React Developer Perspective, with Code Comparison

Svelte is an open-source component-based javascript framework to build user interfaces. But unlike traditional frameworks like React or Vue, which perform much of their work in the browser (with Virtual DOM), Svelte shifts that work into a compile step that happens in build process.

By compiling components into optimized code that directly manipulates the DOM, Svelte apps run faster and are more responsive than those built with other frameworks.

Additionally, Svelte reduces the amount of boilerplate code developers need to write, leading to increased productivity and easier maintenance. The framework also offers a reactive programming model out of the box, which simplifies state management and makes it easier to build complex, dynamic user interfaces.

Svelte’s popularity has been steadily increasing since its release. It has gained a significant following due to its innovative approach and the enthusiastic support from its community. The framework is frequently praised for its simplicity and the positive developer experience it provides.

On the recent StackOverflow survey 2024, Svelte becomes one of the most admired and desired web frameworks.

The future prospects for Svelte look promising, as more developers and companies recognize its potential for building high-performance web applications. Notable companies that have adopted Svelte include The New York Times, for interactive content, and Apple, for parts of their web infrastructure.

With its strong community support, continuous development, and growing ecosystem of tools and libraries, Svelte is well-positioned to become a mainstream choice for front-end development in the coming years.

How to Start Svelte Project in 2024

There are 2 ways to start a Svelte Project from scratch

1. Using Vite + Svelte Template

If you’re new to Svelte, it’s recommended to start with the Vite + Svelte template to learn the fundamentals.

# Create a new project
npm create vite@latest my-svelte-app -- --template svelte
 
# Navigate to the project directory
cd my-svelte-app
 
# Install dependencies
npm install
 
#Run the development server
npm run dev

This will set up a basic Svelte project using Vite, giving you a solid foundation to learn Svelte’s core concepts.

2. Using SvelteKit

SvelteKit is a framework for building web applications with Svelte, providing a more advanced setup for routing, server-side rendering, and more. Its like Next.js for React.

# Create a new project
npm create svelte@latest my-sveltekit-app
 
# Choose the `skeleton project` option when prompted.
 
# Navigate to the project directory
cd my-sveltekit-app
# Install dependencies
npm install
 
#Run the development server
npm run dev

Starting with Vite + Svelte is great for exploring and understanding Svelte fundamentals. Once comfortable, you can move to SvelteKit for more complex, real-world applications.

Related Post

Svelte Codes, compared to React

1. Component

<!-- App.svelte -->
<script>
  let name = "World";
</script>
 
<style>
  h1 {
    color: purple;
  }
</style>
 
<h1>Hello {name}!</h1>

This Svelte component defines a name variable, styles a heading, and uses the variable in the markup. The <script> tag is used for JavaScript, the <style> tag for CSS, and the markup is written directly in the component.

Here is the equivalent codes in React:

// App.js
import React, { useState } from 'react';
 
function App() {
	const [name, setName] = useState('World');
 
	return (
		<div>
			<h1 style={{ color: 'purple' }}>Hello {name}!</h1>
		</div>
	);
}
 
export default App;

2. State and Reactivity

<script>
  let count = 0;
 
  function increment() {
    count += 1;
  }
</script>
 
<button on:click={increment}>
  Clicked {count} {count === 1 ? 'time' : 'times'}
</button>

In Svelte, state and reactivity are handled directly within the component. The count variable is reactive, and the increment function updates it. The on:click directive is used to handle the click event.

Here is the equivalent codes in React:

import React, { useState } from 'react';
 
function App() {
	const [count, setCount] = useState(0);
 
	function increment() {
		setCount(count + 1);
	}
 
	return (
		<button onClick={increment}>
			Clicked {count} {count === 1 ? 'time' : 'times'}
		</button>
	);
}
 
export default App;

3. Props

<!-- Parent.svelte -->
<script>
  import Child from './Child.svelte';
</script>
 
<Child name="World" />
 
<!-- Child.svelte -->
<script>
  export let name;
</script>
 
<h1>Hello {name}!</h1>

In Svelte, props are passed to child components using attributes. The export let syntax is used in the child component to declare props.

Here is the equivalent codes in React:

// Parent.js
import React from 'react';
import Child from './Child';
 
function Parent() {
  return <Child name="World" />;
}
 
export default Parent;
 
// Child.js
import React from 'react';
 
function Child({ name }) {
  return <h1>Hello {name}!</h1>;
}
 
export default Child;

4. DOM Event

<!-- App.svelte -->
<script>
  function handleClick() {
    alert('Button clicked!');
  }
</script>
 
<button on:click={handleClick}>
  Click me
</button>

Svelte uses the on:click directive to handle DOM events.

Here is the equivalent codes in React:

import React from 'react';
 
function App() {
	function handleClick() {
		alert('Button clicked!');
	}
 
	return <button onClick={handleClick}>Click me</button>;
}
 
export default App;

5. Component Custom Event

<!-- Parent.svelte -->
<script>
  import Child from './Child.svelte';
 
  function handleCustomEvent(event) {
    console.log('Event received from child:', event.detail);
  }
</script>
 
<Child on:customEvent={handleCustomEvent} />
 
<!-- Child.svelte -->
<script>
  import { createEventDispatcher } from 'svelte';
 
  const dispatch = createEventDispatcher();
 
  function triggerEvent() {
    dispatch('customEvent', { message: 'Hello from Child' });
  }
</script>
 
<button on:click={triggerEvent}>Trigger Custom Event</button>

In Svelte, custom events are dispatched from child components using createEventDispatcher, and parent components handle these events using the on:eventName directive.

Here is the equivalent codes in React:

// Parent.js
import React from 'react';
import Child from './Child';
 
function Parent() {
  function handleCustomEvent(data) {
    console.log('Event received from child:', data);
  }
 
  return <Child onCustomEvent={handleCustomEvent} />;
}
 
export default Parent;
 
// Child.js
import React from 'react';
 
function Child({ onCustomEvent }) {
  function triggerEvent() {
    onCustomEvent({ message: 'Hello from Child' });
  }
 
  return <button onClick={triggerEvent}>Trigger Custom Event</button>;
}
 
export default Child;

6. Conditional Rendering

<script>
  let isVisible = true;
</script>
 
{#if isVisible}
  <p>Now you see me!</p>
{/if}
 
<button on:click={() => isVisible = !isVisible}>
  Toggle
</button>

Svelte uses {#if} and {/if} blocks for conditional rendering.

Here is the equivalent codes in React:

import React, { useState } from 'react';
 
function App() {
	const [isVisible, setIsVisible] = useState(true);
 
	return (
		<div>
			{isVisible && <p>Now you see me!</p>}
			<button onClick={() => setIsVisible(!isVisible)}>Toggle</button>
		</div>
	);
}
 
export default App;

Related post

7. List Rendering

<script>
  let items = ['Apple', 'Banana', 'Cherry'];
</script>
 
<ul>
  {#each items as item}
    <li>{item}</li>
  {/each}
</ul>

Svelte uses {#each} and {/each} blocks for list rendering.

Here is the equivalent codes in React:

import React from 'react';
 
function App() {
	const items = ['Apple', 'Banana', 'Cherry'];
 
	return (
		<ul>
			{items.map((item) => (
				<li key={item}>{item}</li>
			))}
		</ul>
	);
}
 
export default App;

8. Await Block

<script>
  let promise = fetch('https://jsonplaceholder.typicode.com/posts')
    .then(response => response.json());
</script>
 
{#await promise}
  <p>Loading...</p>
{:then data}
  <ul>
    {#each data as post}
      <li>{post.title}</li>
    {/each}
  </ul>
{:catch error}
  <p>Error: {error.message}</p>
{/await}

Svelte’s {#await} block handles promises directly in the markup.

Here is the equivalent codes in React:

import React, { useState, useEffect } from 'react';
 
function App() {
	const [data, setData] = useState(null);
	const [loading, setLoading] = useState(true);
	const [error, setError] = useState(null);
 
	useEffect(() => {
		fetch('https://jsonplaceholder.typicode.com/posts')
			.then((response) => response.json())
			.then(setData)
			.catch(setError)
			.finally(() => setLoading(false));
	}, []);
 
	if (loading) return <p>Loading...</p>;
	if (error) return <p>Error: {error.message}</p>;
 
	return (
		<ul>
			{data.map((post) => (
				<li key={post.id}>{post.title}</li>
			))}
		</ul>
	);
}
 
export default App;

9. Form Binding

<script>
  let name = '';
</script>
 
<input bind:value={name} placeholder="Enter your name" />
<p>Hello {name}!</p>

Svelte’s bind:value directive provides two-way data binding for form inputs.

Here is the equivalent codes in React:

import React, { useState } from 'react';
 
function App() {
	const [name, setName] = useState('');
 
	return (
		<div>
			<input value={name} onChange={(e) => setName(e.target.value)} placeholder='Enter your name' />
			<p>Hello {name}!</p>
		</div>
	);
}
 
export default App;

10. Lifecycle

<script>
  import { onMount } from 'svelte';
 
  onMount(() => {
    console.log('Component mounted');
    return () => {
      console.log('Component cleanup');
    }
  });
</script>
 
<p>Check the console for lifecycle logs.</p>

Every component has a lifecycle that starts when it is created, and ends when it is destroyed.

Here is the equivalent codes in React:

import React, { useEffect } from 'react';
 
function App() {
	useEffect(() => {
		console.log('Component mounted');
		return () => {
			console.log('Component destroyed');
		};
	}, []);
 
	return <p>Check the console for lifecycle logs.</p>;
}
 
export default App;

11. Stores (Global state management)

<!-- store.js -->
import { writable } from 'svelte/store';
 
export const count = writable(0);
 
<!-- App.svelte -->
<script>
  import { count } from './store.js';
</script>
 
<button on:click={() => $count += 1}>Clicked {$count} times</button>

Svelte has built-in global-state management with writable stores. The $ prefix is used to subscribe to the store. Beside stores, Svelte also has Context API, which is similar to React Context API.

import React, { createContext, useContext, useState } from 'react';
 
const CountContext = createContext();
 
function CountProvider({ children }) {
	const [count, setCount] = useState(0);
 
	return <CountContext.Provider value={{ count, setCount }}>{children}</CountContext.Provider>;
}
 
function App() {
	const { count, setCount } = useContext(CountContext);
 
	return <button onClick={() => setCount(count + 1)}>Clicked {count} times</button>;
}
 
export default function Root() {
	return (
		<CountProvider>
			<App />
		</CountProvider>
	);
}

As you can see, Svelte codes are mostly more straightforward than React for the same functionality. For me, its like a simplified version of Vue. The event and directive is similar with Vue.

However, We’ve just explored the basic syntaxes for Svelte. There are a lot more to learn if you really want to use it for real projects. You can learn more about it through the official docs with interactive tutorial.

Svelte VS React comparison table

FeatureSvelteReact
Component SyntaxUses single-file components with .svelteUses JSX in .js or .jsx files
State ManagementLocal state handled directly in components, stores for global stateuseState and useReducer for local state, Context API, and external libraries like Redux for global state
ReactivityAutomatic reactivity with direct assignmentsExplicit state updates with hooks
Event HandlingUses on:event directives for DOM and custom eventsUses onEvent attributes for DOM events, props for custom events
Conditional Rendering{#if} and {/if} blocksJavaScript conditional expressions
List Rendering{#each} and {/each} blocksJavaScript map function
Form Bindingbind:value for two-way data bindingControlled components with value and onChange attributes
Lifecycle MethodsonMount, beforeUpdate, afterUpdate,useEffect, componentDidMount, componentDidUpdate, componentWillUnmount
PerformanceCompiles to highly optimized imperative code, resulting in faster runtime performance and smaller bundle sizesUses virtual DOM to optimize updates, but can result in larger bundle sizes and slightly slower runtime performance compared to Svelte
Learning CurveEasier for beginners, simpler syntax and conceptsSteeper learning curve, requires understanding of JSX and hooks
ToolingSvelteKit for full-featured applications, Vite for simple setupsCreate React App, Next.js for server-side rendering and static site generation
PopularityGrowing, smaller communityWidely adopted, large community and ecosystem
File SizeSmaller bundle sizes due to compiled codeLarger bundle sizes, depends on the size of the library and dependencies
EcosystemFewer libraries and pluginsRich ecosystem with numerous libraries and plugins available
First-Party SupportSvelteKit for advanced applicationsNext.js, Create React App for application scaffolding

Conclusion

Svelte and React are both powerful tools for building modern web applications, each with its unique strengths. Svelte stands out with its straightforward syntax, automatic reactivity, smaller bundle sizes and faster runtime performance. Its simplicity makes it an excellent choice for beginners and developers looking for a lightweight solution.

React, on the other hand, offers a rich ecosystem, extensive libraries, and robust tooling options. Its use of the virtual DOM optimizes updates, although it can lead to larger bundle sizes and a steeper learning curve. Ultimately, the choice between Svelte and React depends on the specific needs of your project and your familiarity with each framework.

Do you have your own opinion about this? Don’t hesitate to share it in the comment below. If you find this article helpful, kindly give it a like and share :smile:.

Thank you. Happy coding!