two developers facing each other, in split screen, working

React vs. Svelte: A Side-by-Side Comparison

About React and Svelte

If you're doing web development with JavaScript, you've heard of React and Svelte. They stand out for their distinct approaches to building web applications.

To compare them, we'll examine a pitch deck app using both frameworks, making the code as identical as possible.

React, the brainchild of Facebook, has firmly established itself as the dominant JavaScript library in the world. In the bustling realm of startups and front-end job opportunities, React reigns supreme.

React has an extensive ecosystem and a level of community support that make it the go-to choice for countless developers and organizations. Its component-based architecture promotes modularity and code reusability. This feature-rich library also offers a virtual DOM, ensuring efficient updates and rendering optimizations.

Svelte, crafted by Rich Harris, formerly of The New York Times, presents itself as a leaner and more streamlined alternative. The Svelte framework compiles components into highly optimized JavaScript code during the build process. This results in remarkably efficient runtime performance and a smaller bundle size.

Svelte's selling points are its simplified component structure and impressive default runtime performance. The two-word pitch would be: it's fast. The site you're reading this on now is written in Svelte.

Svelte's also very developer friendly. It seems like every framework promises to be "JavaScript-like," but there's no translation to the 'real JavaScript' with Svelte (as there is with React and JSX). It really is just JavaScript. That can make it easier to think and reason about over the long haul.

Now that you know what they're about, let's dive in.

Key React Features

Key Svelte Features

App Setup

I wrote an app to compare React and Svelte, which basically has one webpage which flips to the next webpage when you click on it.

React app: code | demo

Svelte app: code | demo

The demonstration app is a series of HTML and CSS 'cards' which are held in state and changed to the next card with every click.

The app doesn't have a router because that would've obscured the differences between them. Routing is usually done by libraries and I wanted to stick to 'vanilla' React and Svelte.

The pitch deck is for a fictional stock photography company called Eye Captain. I created about 10 pages, or cards, to have enough code for comparison.

In addition to clicking through the cards sequentially, you can also click on a button to change their formatting.

In desktop mode, it can either be letterboxed - surrounded by blank black space - or fullscreen - where the card, and its blue background, stretches to the corners of the screen.

In mobile mode, there's less space, so the mobile view is only fullscreen.

How the App Works

When you click on a card, it advances the card index plus one, and that index is used to find the next card. If you're at the last card, it loops back to the first one.

The card index and the styles affecting the cards are all stored within the framework's state.

The most illuminating part is seeing how React and Svelte manage this state in their own way. It's a little different but not too different.

state react svelte

React:

 const Deck = ({infoDesk,infoMobile}) => {
    const [index,setIndex]=useState(0);
    const [display,setDisplay]=useState(true);

    function advanceClick(object) {
        if (index===object.length-1){
	    setIndex(0);
        } else {
	    setIndex(index+1);
        }
    }
 }

Svelte:

 export let infoDesk;
  export let infoMobile;
  import MediaQuery from "./MediaQuery.svelte";

  let index = 0;
  let display = true;

  function advanceClick(object) {
      if (index===object.length-1){
	  index=0;
      } else {
	  index+=1;
      }
  }

react code | svelte code

Components

I tried to lay out the two apps to be as identical as possible.

code react svelte

Both of them have a main app component where the text is defined, and passed as an argument to the component that actually implements the page, called Deck in both apps. In React, it's Deck.js, and in Svelte, it's Deck.svelte.

I'll start with Svelte.

 let index = 0;
  let display = true;
  
  function advanceClick(object) {
      if (index===object.length-1){
	  index=0;
      } else {
	  index+=1;
      }
  }

<style>
  .fullscreen {
      background-color: #294582;
      padding-right: 3vw;
      ...      
</style>

<MediaQuery query="(max-width: 800px)" let:matches>
  {#if matches}
    <div class="mobilefull" on:click={advanceClick(infoMobile)}>
      <h1 class="mobileh1">{infoMobile[index].title}</h1>
      <p class="mobilepad">{@html infoMobile[index].text}</p>
    </div>
  {:else}
    <div class="{display ? 'fullscreen' : 'letter'}" on:click={advanceClick(infoDesk)}>
      <button
	class="{display ? 'active' : ''}"
	on:click="{() => display = !display}"
	>
	{display ? 'letterbox' : 'fullscreen'}
      </button>

      <div class="{display ? '' : 'card'}">
	<h1 class="deskh1">{infoDesk[index].title}</h1>
	<p class="deskpad">{@html infoDesk[index].text}</p>
      </div>
    </div>
  {/if}
</MediaQuery>

In Svelte, at the top, as I've written it, you have some script definitions.

Below that, you have the CSS.

At the bottom, you have the page content, plus some JavaScript.

In the case of the React app, it's a standard React implementation, using hooks.

const Deck = ({infoDesk,infoMobile}) => {
    const [index,setIndex]=useState(0);
    const [display,setDisplay]=useState(true);
    
    function advanceClick(object) {
        if (index===object.length-1){
	    setIndex(0);
        } else {
	    setIndex(index+1);
        }
    }
    return (
          <Media query="(max-width: 800px)">                  
          {matches =>
           matches ? (
               <div style={MobileFull} onClick={()=>{ advanceClick(infoMobile); }}>
                   <MobileH1>{infoMobile[index].title}</MobileH1>
                   <MobilePad>{infoMobile[index].text}</MobilePad>
               </div>
           ) : (
               <div style={display ? Fullscreen : Letter} onClick={()=>{ advanceClick(infoDesk); }}>
                 <Buttn style= {display ? Active : {} } onClick={() => setDisplay(!display)}>
                   {display ? 'letterbox' : 'fullscreen'}
                 </Buttn>
                 <div style= {display ? {} : Card }>            
                   <H1>{infoDesk[index].title}</H1>
                   <Pad>{infoDesk[index].text}</Pad>
                 </div>
               </div>
           )
          }
          </Media>
        
    )
}

export default Deck; 

Managing State

State is important in both versions. To quote the React docs:

State is reserved only for interactivity, that is, data that changes over time.

My working definition of state here is that it's the program's 'memory' (note: don't say this in a job interview). Just like you use your memory to remember when something has changed locations, your app does that too.

One state variable is for the index. Its purpose is to show the card associated with that index number, and increment it on click.

In both programs, a function with the same name, advanceClick, moves the index forward by one, when you click on the screen (onClick in React, on:click in Svelte).

Another state variable is for 'fullscreen' or 'not fullscreen' - which is to say, mobile. The variable is called display.

When it's true, you see the fullscreen version of the site. When it's false, you see the mobile version.

You flip between those versions by clicking on a button which toggles the value of display, with every click.

Live Demos

The live Svelte app is here:

http://pitch-deck-svelte.s3-website-us-east-1.amazonaws.com/

The live React app is here:

http://pitch-deck-react.s3-website-us-east-1.amazonaws.com/

When To Use Svelte vs. React

I sometimes see tutorials that say something like, 'Use the framework that's best for your situation.' I find that frustrating.

I'll give clearer advice:

Whenever you can use Svelte, use Svelte. When you can't, use React.

You know what's a common use case for Svelte - meaning a situation where you should use Svelte over React?

Blogs. Like this one, also written in Svelte.

See this essay, Second Guessing the Modern Web:

There is a sweet spot of React: in moderately interactive interfaces. Complex forms that require immediate feedback, UIs that need to move around and react instantly.

There is a swath of use cases which would be hard without React and which aren’t complicated enough to push beyond React’s limits. But there are also a lot of problems for which I can’t see any concrete benefit to using React. Those are things like blogs, shopping-cart-websites, mostly-CRUD-and-forms-websites...

I can, for example, guarantee that this blog is faster than any Gatsby blog (and much love to the Gatsby team) because there is nothing that a React static site can do that will make it faster than a non-React static site.

Time to Load: Where Svelte Scores Higher Than React

For blogs, I think the average developer underestimates the advantage of speed. That should be your main priority!

I know I've clicked on developer portfolio sites on my iPhone, only for it to essentially time out before loading.

The quality of your blog reflects on you. Don't be that person with the slow site.

For this example I created two blogs, one in React, one in Svelte, both deployed to S3. I decided to test them using the Audit feature in Chrome's Developer Tools.

The Svelte result is here.

svelte result

The React result is here.

react result

Look at that difference in time to interactive. The Svelte scores, in this comparison, are definitely superior.

So the short answer is, without any optimization, the Svelte results are better.

Conclusion

React's component-driven architecture and extensive ecosystem make it a reliable choice for complex applications, while Svelte's efficiency and minimalistic approach shine in scenarios where performance and bundle size are paramount.

If you're doing something that's not very architecturally complex, use Svelte.

If you have more interactivity than we would expect from, say, a blog, if you know you'll need libraries in the React ecosystem, or if you know you'll eventually need to hire React developers, use React.

But think carefully. You might not need it.

Be willing to learn and use Svelte. You might just learn to love it, as I have.