Skip to content

Instantly share code, notes, and snippets.

@Rich-Harris
Last active October 13, 2024 17:18
Show Gist options
  • Save Rich-Harris/0f910048478c2a6505d1c32185b61934 to your computer and use it in GitHub Desktop.
Save Rich-Harris/0f910048478c2a6505d1c32185b61934 to your computer and use it in GitHub Desktop.
The truth about Svelte

I've been deceiving you all. I had you believe that Svelte was a UI framework — unlike React and Vue etc, because it shifts work out of the client and into the compiler, but a framework nonetheless.

But that's not exactly accurate. In my defense, I didn't realise it myself until very recently. But with Svelte 3 around the corner, it's time to come clean about what Svelte really is.

Svelte is a language.

Specifically, Svelte is an attempt to answer a question that many people have asked, and a few have answered: what would it look like if we had a language for describing reactive user interfaces?

A few projects that have answered this question:

(Idyll is an outlier as it's geared towards a specific use case, rather than general purpose app development, but I think it qualifies as an example.)

These projects are all very cool, but there's a reason they haven't hit mass adoption: they want to control the entire world. You can't adopt Elm or Imba incrementally, and they need dedicated tooling far beyond just the compiler itself (e.g. syntax highlighting, unless you like your code monochrome). In some cases (Elm stands out), interop with the JS ecosystem is less than seamless.

Beyond that, they have a steep learning curve, which is hard to justify when there are so many options that are more accessible.

Thinking inside the box

What if we had a language that was designed for building reactive user interfaces, but that also worked with your existing tools? What if you didn't need you to discard your years of experience using HTML, CSS and JavaScript, because it extended those languages?

  • It would extend HTML by adding JavaScript expressions in markup, directives for controlling behaviour and reacting to input, syntax for using conditions, loops and asynchronous values
  • It would extend CSS by adding a scoping mechanism that kept styles from clobbering each other
  • It would extend JavaScript by making reactivity a language primitive

How do we make reactivity a language primitive without introducing invalid syntax, or breaking the relationship with existing tooling (like TypeScript)? By hacking existing syntax:

This, to me, is the best of all possible worlds: we can lean on decades of accumulated wisdom by extending well-known languages, author components in a delightfully concise and expressive way, and yet still generate apps that are bleeding-edge in terms of performance and everything that goes with it.

@hannah23280
Copy link

hannah23280 commented Jun 11, 2021

I like Svelte's loop

	{#each cats as cat}
		<li><a target="_blank" href="https://www.youtube.com/watch?v={cat.id}">
			{cat.name}
		</a></li>
	{/each}

although it reads "each cats as cat"... could it be "loop cats as cat"? It could be "each cat of cats".
I feel weird with

<ul id="example-1">
  <li v-for="item in items">
    {{ item.message }}
  </li>
</ul>

or

<li *ngFor="let product of products">
    <h2>{{product.name}} / ${{product.price}}</h2>
    <p> {{product.description}} </p>
</li>

It is like, you have to read <li ... and then the for, and then move that for to the left of <li ..., to make it
for ... <li .... instead... maybe I am just not used to reading code that needs a programmer to backtrack.
If it can be

  <li repeated-for="item in items">
    {{ item.message }}
  </li>

then it reads "<li repeated for ... the following", and it is more natural.

  <li repeated-for-each="item in items">
    {{ item.message }}
  </li>

and

  <li for-each="item in items">
    {{ item.message }}
  </li>

also read naturally.
I feel ok with this too:

    <ul>
      {elements.map((value, index) => 
        <li key={index}>{value}</li>
      )}
    </ul>

Some people don't like the JSX, but you can just view it as mapping from the HTML code to some DOM creation code. (which is what it really does).

Don't you think for-each, repeated-for-each, repeated-for is too lengthy?

Actually for the loop, i prefer angular version. Cos svelte add additional lines to specify the loop. Imagine the below

<div *ngFor="let product of products">{{product}}</div>
//other elements in between
<div  *ngFor="let product of products">{{product}}</div>
//other elements in between
<div  *ngFor="let product of products">{{product}}</div>

For angular, i can just add the loop construct (i.e ngFor) without introducing extra lines. But for svelte, will introduce 6 more extra lines to achieve the loop. This will make the html more cluttered.
I truely hope that there will be a day where svelte will provide syntactic sugar where we can add the loops construct as an attributes of the element to loop (similar to that of angular). The svelte compiler wlll then be able to convert that syntatic sugar back to the current syntax.

That goes the same for if/else

See sveltejs/svelte#3288 on similar discussion

@chenzx
Copy link

chenzx commented Mar 16, 2022

I like Svelte, and i'm reading its impl internals. Some code hard to understand for now.

I have an idea: to extend vanilla JS to gain a "Typed DSL", which means JS with type annotations, then use AOT compile to translate to other forms of code: like JS (JS to JS, with runtime for reactive, which is used by Svelte), i want to get wasm or C++ native to boost performance in NodeJS env...

@tomaz-on
Copy link

tomaz-on commented May 8, 2022

Hello guys, I think svelte / sveltekit like:

svelte = compiler

sveltekit = framework

If I am wrong, please teach me and I would appreciate it.

and sveltekit is my first JavaScript framework I'm in ... Almost went with Vue, but with Blazor I decided to wait and keep with .NET Core things, but sveltekit made me join and I love it like I love .NET Core ecosystem

@worldpeaceenginelabs
Copy link

worldpeaceenginelabs commented Jun 17, 2022

irislib/iris-messenger#113

We have a discussion going, about using Svelte, which will be the base for Metaverse-Gun https://github.com/worldpeaceenginelabs/METAVERSE-GUN

I did read your article "The truth about Svelte", i dont disaggree, just my explainer is better 😜

Join us! It could help!

Metaverse-Gun

@damienzm
Copy link

damienzm commented Sep 9, 2022

Fabulous clickbait: "I've been deceiving you all".. very nice following your progress, even if your twitter page did rickroll me lol. Keep up the great work!

@digitaldrreamer
Copy link

@Rich-Harris I love Svelte man! You gave me the best escape I could ever hope for: an escape from React's depressing JSX and obsessive community(Like everyone wants to use react for everything).
I'm moving to SvelteKit next. Then I'm ditching React Native for Svelte Native.
Thanks a lot. Svelte is literally what I've been dreaming of.
PS: I especially love the interactive tutorial. Webcontainer is impressive

@efpage
Copy link

efpage commented Mar 13, 2023

@Rich-Harris: "Svelte is a language"? Maybe, that is the weakest point of Svelte. It isn´t really a "programming" language! Or maybe, a fairly limited one. There are - for good reason - about 10 different ways to use loops in Javascript. Svelte knows ? 1 ?

Don´t get me wrong: Svelte is absolute fantastic and possibly the best we could get for the web community today, but I absolutely miss the option to do all the things we can do with a "real" programming language.

What, if we coud turn things around and not embed scripting elements into HTML, but vice versa:
In Svelte, you write:

<script>
	const percentage = [0, 25, 50, 75, 100]
</script>

{#each percentage as p}
<button on:click="{() => progress.set(p/100.0)}">
	{p}%
</button>
{/each}

which is nice and easy to understand. But "#each" is not as powerful as loops in JS are.

If we could use JS directly, this could be:

<script>
      for (p of [0, 25, 50, 75, 100]){
         <button on:click="{() => progress.set(p/100.0)}">
	      {p}%
         </button>
      }
</script>

I do not pray for the JSX-syntax, this is a false friend as well. But using a full featured programming language would bring much more power to the task.

As my grandma said: Never do a thing for a computer, that a computer can do for you.

@rbenzazon
Copy link

rbenzazon commented Mar 18, 2023 via email

@oofdere
Copy link

oofdere commented Jul 12, 2023

<script>
      for (p of [0, 25, 50, 75, 100]){
         <button on:click="{() => progress.set(p/100.0)}">
	      {p}%
         </button>
      }
</script>

You can pretty much already do this:

<script>
	let progress = 0;
</script>

<progress value={progress} />

{#each [0, 25, 50, 75, 100] as p}
	<button on:click="{() => progress = p/100.0}">
		{p}%
	</button>
{/each}

https://svelte.dev/repl/f3a28a0ab1134c6fa877f89faaa0c9f5?version=4.0.5

@kaspersky3550879
Copy link

Cool

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment