spy vs spy

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

About React and Svelte

Let's compare React and Svelte, the JavaScript frameworks.

To do that, let's examine a pitch deck app using both frameworks, making the code as identical as possible.

https://github.com/julianeon/pitch-deck-react/

React is the dominant JavaScript framework today. While React, created by FaceBook, has competitors, it's the framework you're most likely to encounter at startups and in front end job postings.

https://github.com/julianeon/pitch-deck-svelte/

Svelte is an up-and-comer created by the developer Rich Harris, formerly of the New York Times. It offers something different: a simplified structure and typically better run-time performance, like faster load times.

App Setup

The app used to compare them basically has one webpage which changes state to the next webpage when you click on it. More precisely, 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 educational comparison is in seeing how React and Svelte manage this state. It's a little different but not too different.

state react svelte

See the code for more details.

svelte code | react 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.

I think of state as 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/

Conclusion: Learn Svelte

I'd describe myself as a React developer. This was my first time using Svelte, and this showed me the more intuitive JavaScript-ese of Svelte.

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.

Svelte reads like almost pure JavaScript. If you're used to React, you can pick up Svelte almost immediately. If you're new to them both, the concepts you learn in Svelte will have analogues in React.

Either way, you can start with Svelte. React has a bigger ecosystem, but Svelte's got a lot going for it.

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.

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. You're a developer. The quality of your blog reflects on you. Don't be that person with the slow site.

I have two blogs here, 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

Spoiler: the Svelte results are about twice as good.

Look at that difference in time to interactive. The React one is more than twice as large - 3.7 seconds vs. 1.7 seconds. If you can sidestep that, you should.

Recommendation: Use Svelte If You Can

If you're doing a blog from scratch, I suggest you use Svelte.

If you have more interactivity than we would expect from your average blog, or if you know you'll need libraries in the React ecosystem, use React - but think carefully. You might not need it.

Be willing to learn and use Svelte. The speed difference is worth it.