DEV Community

Cover image for Getting Started with Svelte from React Dev Perspective, with Code Comparison
Syakir
Syakir

Posted on • Originally published at devaradise.com

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

Checkout the original post to read with Table of Contents

Learn React with The Complete React Bootcamp only for $49 a year (Free 1 month trial) *affiliate link


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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

2. State and Reactivity

<script>
  let count = 0;

  function increment() {
    count += 1;
  }
</script>

<button on:click={increment}>
  Clicked {count} {count === 1 ? 'time' : 'times'}
</button>
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

4. DOM Event

<!-- App.svelte -->
<script>
  function handleClick() {
    alert('Button clicked!');
  }
</script>

<button on:click={handleClick}>
  Click me
</button>
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

6. Conditional Rendering

<script>
  let isVisible = true;
</script>

{#if isVisible}
  <p>Now you see me!</p>
{/if}

<button on:click={() => isVisible = !isVisible}>
  Toggle
</button>
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

Related post

7. List Rendering

<script>
  let items = ['Apple', 'Banana', 'Cherry'];
</script>

<ul>
  {#each items as item}
    <li>{item}</li>
  {/each}
</ul>
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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}
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

9. Form Binding

<script>
  let name = '';
</script>

<input bind:value={name} placeholder="Enter your name" />
<p>Hello {name}!</p>
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
    );
}
Enter fullscreen mode Exit fullscreen mode

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

Feature Svelte React
Component Syntax Uses single-file components with .svelte Uses JSX in .js or .jsx files
State Management Local state handled directly in components, stores for global state useState and useReducer for local state, Context API, and external libraries like Redux for global state
Reactivity Automatic reactivity with direct assignments Explicit state updates with hooks
Event Handling Uses on:event directives for DOM and custom events Uses onEvent attributes for DOM events, props for custom events
Conditional Rendering {#if} and {/if} blocks JavaScript conditional expressions
List Rendering {#each} and {/each} blocks JavaScript map function
Form Binding bind:value for two-way data binding Controlled components with value and onChange attributes
Lifecycle Methods onMount, beforeUpdate, afterUpdate, useEffect, componentDidMount, componentDidUpdate, componentWillUnmount
Performance Compiles to highly optimized imperative code, resulting in faster runtime performance and smaller bundle sizes Uses virtual DOM to optimize updates, but can result in larger bundle sizes and slightly slower runtime performance compared to Svelte
Learning Curve Easier for beginners, simpler syntax and concepts Steeper learning curve, requires understanding of JSX and hooks
Tooling SvelteKit for full-featured applications, Vite for simple setups Create React App, Next.js for server-side rendering and static site generation
Popularity Growing, smaller community Widely adopted, large community and ecosystem
File Size Smaller bundle sizes due to compiled code Larger bundle sizes, depends on the size of the library and dependencies
Ecosystem Fewer libraries and plugins Rich ecosystem with numerous libraries and plugins available
First-Party Support SvelteKit for advanced applications Next.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 😄.

Thank you. Happy coding!

Top comments (0)