Why Svelte is our choice for a large web project
github.com
github.com
Elm is awesome! There's nothing quite like it that I know of in its design space to bring user-friendly functional programming to the web. Similar to Svelte, its design holistically packages up the web's languages. Compared to PureScript, it's focused on a small and beginner-friendly feature set, trading general power to optimize for the webapp use cases. Elm has also been influential to a lot of toolmakers!
One important difference with Svelte versus Elm is that Elm makes a clean break from web technologies, while Svelte is designed to work with future versions of the web's languages.
These are the complaints that standout for me with Svelte after using it for a few months:
* Sub-par editor support. For me, the litmus test is whether I can use F2 to rename a variable, and it often does not work inside a Svelte template. There are other places where the editor does not know what to do with your code, because it is not pure JS. Vue is much worse with this since so many things are just strings; React really shines with editor support. This makes a big difference when you are using a large project where you didn't write the code.
* I don't love that you have to re-assign a object/array variable to get Svelte to notice it changed, and you can do that inside a Svelte template to a const variable and you won't get a complaint from the compiler.
* Much smaller ecosystem compared to React and Vue, which is expected at this point.
Other than this, I absolutely love Svelte. Stores are such an amazing abstraction. Animation is well thought out. Storybook works perfectly. Mostly it is pure JS once it gets inside the browser, so you can debug effectively which is not the case with Vue for example.
I also wouldn't consider that a disadvantage vs React/Redux, since that also requires using immutable data.
Passing around components as variables is such a common pattern in React, and there's no good replacement in Svelte. The lack of dynamism in components and styles makes theming and crafting reusable components (outside of simple widgets) very tedious [1][2]. I'm genuinely curious how someone can come from React and not be bothered by it.
https://github.com/sveltejs/svelte/issues/1037 (open since 2017)
https://github.com/sveltejs/svelte/issues/2079
The simple usage of passing a component to a component, which almost every decently-sized project will make use of, has no convenient syntax, only workarounds:
// parent.svelte
<script>
import Nested from './nested.svelte'
import Child from './child.svelte';
</script>
<Child>
<div slot="bar"> <-- Extra wrapper DOM node
<Nested foo="Foo"/>
</div>
</Child>
// child.svelte
<slot name="bar" {...data}/>
Passing down an element as a prop requires separating the component constructor and its data and manually re-conciliating the two in the child component every time, since components can't be rendered from functions. It works but it's unnecessary boilerplate. // parent.svelte
<script>
import Nested from './nested.svelte';
import Child from './child.svelte';
</script>
<Child nested={Nested} nestedData={{ foo: "Foo" }}/>
// child.svelte
<script>
let export Component;
let export componentData;
</script>
<Component {...componentData}/> <script>
import RedThing from './RedThing.svelte';
import GreenThing from './GreenThing.svelte';
import BlueThing from './BlueThing.svelte';
const options = [
{ color: 'red', component: RedThing },
{ color: 'green', component: GreenThing },
{ color: 'blue', component: BlueThing },
];
let selected = options[0];
</script>
<select bind:value={selected}>
{#each options as option}
<option value={option}>{option.color}</option>
{/each}
</select>
{#if selected.color === 'red'}
<RedThing/>
{:else if selected.color === 'green'}
<GreenThing/>
{:else if selected.color === 'blue'}
<BlueThing/>
{/if}https://svelte.dev/tutorial/svelte-component
But yea that's indeed what I should have done in my example if I wanted the component to be reactive, as you can see that's even more verbose and still doesn't take care of props.
And, isn't it likely this will be easier to support with Svelte eventually? My reasoning is that you just need to add a little syntactic sugar to the language and the compiler can add whatever code is necessary? With a runtime like React and Vue, it seems much harder to add in.
> With a runtime like React and Vue, it seems much harder to add in.
As a rule of thumb, it's almost always easier to add things at runtime than at compile time. That's why it took us so long to get Rust.
On point 1, this issue is the one to watch. https://github.com/sveltejs/svelte/issues/4518 Language server support will work for both JavaScript and TypeScript and error/type checking and editor support should be pretty comprehensive when it's ready. Svelte 3 was written with TypeScript in mind, so the idioms are fairly compatible with type checking. (a nice pit of success for design!)
This should also fix reassigning to a const mentioned in point 2.
I think Svelte is refreshing, but I would not be comfortable using it on a large-scale web application just yet given the downsides, particularly an enterprise LOB application with many moving pieces. This is why frameworks like Angular, Ember and Aurelia on the front-end lend themselves better to the enterprise and React and other more component-based libraries do not.
In terms of community size, I don't think that matters in 2020. You don't need a big community if you have something straightforward and easy to work with. Great read.
The template language's restrictions compared to JavaScript/JSX-built views are part of Svelte's performance story. It's able to optimize things ahead of time that are impossible with dynamic code because of the constraints. Here's a couple tweets from the author about that -
1 - https://twitter.com/Rich_Harris/status/1224414679021301761
2 - https://twitter.com/Rich_Harris/status/948231770725605377
The Svelte template language is quite small, and compositional features like slots and <svelte:component> are powerful. There are currently some unwanted edge-case restrictions as this comment points out - https://news.ycombinator.com/item?id=22541100
https://github.com/noahlh/celestite
Two slightly obscure (but growing) languages/frameworks, but hey, gotta pick a niche. Contributions & feedback welcome!
Found a straggler "CrystalVue" substring in the main .cr file, you should give 'er the old find-and-replace all to change them.
I'm trying to think of some downsides to balance my enthusiasm for the framework, but can't think of any. The article mentions the smaller community as a possible issue, but the community on Discord seem very welcoming.
Re "using Svelte means adopting a new language" - it didn't feel like that to me. Every framework has its own way of doing things; Svelte's way didn't annoy me as much as some other frameworks have done in the past (eg: Angular before it became Angular2).
I've got another personal project rebuild coming up - I reckon I'll be treating that as an opportunity to learn more Svelte.
[1] My poetry website (you have been warned!) - https://rikverse2020.rikweb.org.uk/ I blogged about my experiences with Svelte, starting here: https://blog.rikworks.co.uk/2020/02/01/Recoding-the-RikVerse...
Me neither, but I've been around long enough to remember the handlebars.js days. To someone that's only used React I imagine that at first sight things like {#if} {/if} look ugly as hell. To those people I can only say to stick it out: it starts to feel very natural very quickly.
The readme does a good job of pointing out its shortcomings, too. Primarily, no typescript support yet & the unknown bundle size inflection point. As soon as these are solved, I can't imagine it not becoming the best (albeit not most popular) solution.
I love the pragmatism of this framework - no solutions looking for problems or complex, badly documented abstractions.
Even if Svelte won't be the next generation framework everyone will be using, the ideas it presents are definitely something the web needs.
There are certainly a few rough edges, but it's all related to the immaturity of the language. Specifically, I had a hard time understanding transitions and it wasn't at all obvious how to integrate it with D3. Hopefully as it grows we will see improved docs and examples.
Also, I'm holding out for more mainstream TypeScript support. At that point, it would be hard to convince me to use anything else.
[1] http://musetree.stevenwaterman.uk
[2] http://optimisation.stevenwaterman.uk + https://blog.scottlogic.com/2020/02/17/minesweeper-optimisat...
The article goes into this more, but Svelte's DSL is an extension of web languages - not much to learn really! Your existing knowledge of HTML, CSS, and JS transfers directly.
The templating in Svelte and Vue is (almost) html with some magic sprinkled here and there, so much closer to the end result. Using JS for everything is moving further away from the metal.
What is it about writing views the React way that appeals to you more?
You can't ship until it looks good, and the longer features are in-flight the worse management feels about the team's abilities.
You don't want situations where senior staff have to intervene on what should be a straightforward issue. It gums up the works.
JSX is JS thus it's powerful. I prefer to use JS to "sprinkel the magic", rather than using yet another (awkward) template language. Using JS for everything is keeping my mental consistent. I enjoy getting full editor support for the entire app (typing (via TS), warnings, auto-suggestions, etc...). Overall it feels more consistent, more composable and more functional (as in Functional Programming) to me.
IMO a just a simple function/array based templates work better like this that I have used recently:
div({class: 'test'}, b({}, 'Hello world!'))
Or for the array syntax:
['div', {class: 'test'}, ['b', {}, 'Hello world!']]
I ended up with Skeleton/jQuery for the front end and PHP Slim for the backend. This is a 5 page, 2 forms, site targeted at 100 people. There's no need to SPA this, npm that.
No rational person would advocate using Svelte or React for a static, one-off, informational site to be maintained by a single person.
In fact, you didn't even need jQuery at all. Vanilla JS works across browsers in a way that it didn't when you learned web coding 10 years ago.
Where frameworks become useful is for large projects that many people work on over a long period of time. Turnover is an issue for non-standardized code, as is poorly organized code.
And none of that even touches on security, which absolutely requires libraries, packages, and many of the other benefits of reusing the ecosystem that you seem to eschew.
This is where we disagree, and I think that's the problem. In my use case, I just wanted an HTML template file with at most a few CSS files. There's a dearth of those frameworks/templates compared to bigger packages.
> I ended up with Skeleton/jQuery for the front end
So rather than install a dependency via a package manager you installed it manually. Okay.
The whole point was that it's simple enough that I don't have to deal with a package manager, and a lot of projects don't need to.
To be honest, if you're going for "as simple as possible" there's no reason to use jQuery at all these days, it's a waste. Modern browsers have perfectly capable APIs!
1) Svelte gives you a solid foundation and lots of flexibility
2) difficulty scaling for large apps is mostly orthogonal to the component library
3) Svelte provides flexible and sugary integration points for these orthogonal concerns
For example, since we're talking large projects, the biggest concern is state management. Svelte is like React here, in that you could use MobX or Redux with a connector library, or RxJS with Redux, or other combinations. As long as your solution is compatible with stores like RxJS is, you benefit from Svelte's auto-subscriptions[1] and sugary store dereferencing[2] that's agnostic to your underlying state management solution.
> It's interesting that Svelte is positioned as a Javascript framework: it seems to be practically a different language, far more so than JS+JSX.
> The downside is that it's hard to integrate with much of the Javascript ecosystem, e.g. TypeScript.
> Yet at the same time, it doesn't fully embrace being a different language, so it does not add features like e.g. how Elm supports pattern matching.
> It does make it an easier sell, I suppose, which does certainly count for something. Am I missing something else?
After having read it, it does seem that the author does both consider it a separate language, but also still presents it as a JS framework. I wonder if the former isn't being underestimated?
[1] https://twitter.com/VincentTunru/status/1237422539128868865
That said, I'm also really enjoying TS so could understand why someone may want to stick with React for a new project until Svelte gets TS.
My big Svelte project isn't public but my personal site is a Svelte app too: https://mikemaccana.com source is at https://github.com/mikemaccana/mikemaccana.com
The idea of having markup+logic+styles in the same file works for small components but it gets muddy on bigger ones. It can be argued that components should be as small as possible but OTOH having to create a new file for every damn component gets old very quickly.
For the past 2-3 years I've been working again with JSX based libraries and being able to create micro components on the same JS file makes a lot more sense.
I've also gone back to regular SASS and moved all CSS outside of components (except for dynamic CSS). It works better IMO than single file components.
Too many options, not enough Blessed Solutions for basic things.
Take routing for example, in Svelte you have a lot of options but no real #1 "Svelte Recommends (tm)". They should solve this problem before it gets out of hand. It killed Meteor.
I sometimes use external libraries. For example handlebars if I want to template something clientside.
But no more frameworks.
I think pure Javascript is plenty enough these days.
For those who can't live without a framework: What would you miss?
It’s pretty innovative in that it’s not really big JS bundle, but more of a compiler for what is essentially quite vanilla JS code. In the end, if you use Svelte, then your final product will be pure HTML/CSS/JS.
I love it because it lets me bundle logically related markup, styling, AND javascript in the same .svelte file. Plus, it’s blazing fast.
I'm on my 5th or 6th project w/ svelte and it's been an overall joy to use so far.
Part of me feels like using "overkill" frameworks for everything is a better bet. It builds more familiarity and expertise. It certain makes some projects more complex than they need to be, but it makes it easier to switch from project to project.
My organization has tossed so many manhours into maintaining webpack and our build that you could recreate our entire site numerous times over in a bog standard LAMP stack with a fraction of the headcount. The cost of a modern web dev stack is no joke. And for what, I might ask? The UX of a single page app is atrocious. The canonical example of SPA done right is Google Maps. Ever tried Google Maps on a mobile browser? There is a reason the native app still exists.
SPA is, at best, a desktop-first experience that we're trying to force into a mobile-first world we live. It's nearly the definition of insanity, what we're trying to do with the web today.
In the process of everyone following Google and Facebook, we are also destroying the essential ingredient of the web: links. Everything is a walled garden with internal state and incredibly fragile external links (if any at all). Pinterest and Quora, everywhere. What will define the web of the 2010-2020+ is that everything is broken and everything sucks.
The thing I miss the most is a good component and state abstraction. That's it.
I would be very happy using ASP.NET WebForms today: components are rendered 100% in the server but the state is persisted by the client using a <input type=hidden> field. The server can be 100% stateless.
Too bad it is impossible to convince anyone to pick up ASP.NET WebForms in 2020 :)
Modern backend frameworks such as Rails and Django have similar "component-ish" helpers, but those always fall short of the capabilities of both React/Vue and ASP.NET WebForms, and you have to worry about state by yourself.
Phoenix Live View is cool, but needs a stateful server, requires JS and polyfills up the wazoo. At this point I'd rather use Vue or React.
Components in Blazor actually look like Svelte, or maybe it's the other way around.
Well, my favourite of choice is Elm, and it's correctness guarantees are really a huge deal to me. Whenever I have to do react or even just vanilla js for work, unless it's really miniscule I will nearly always run into runtime errors because I just forget to check something for null or do something stupid like not awaiting a promise (and that's before any other developers get involved). Typescript helps out a certain extent but I find it isn't nearly prescriptive enough. It's not like I'll ever convince my company to adopt Elm though (and believe me, I tried), so c'est la vie.
Although I suppose these might be considered different languages rather than just a framework, which is where the benefit comes from? It might be just that I'm not very good with dealing with JS as a language rather than needing a framework specifically.
That means you can write in a more functional style: input data -> output HTML+CSS.
Our team has diverse experience with the other tools in this space. I would say that the consensus is that Svelte is far more intuitive and fun than other tools.
JSX really spoiled me to the point that if there isn't JSX, I don't want it.
I'd really encourage all front-end devs to take Svelte for a spin, if for no other reason than to see a framework really trying to do things differently. There are a lot of nice ideas in there, and the works-out-of-the-box level is admirable.
Why is it flawed and why are you citing a flawed study? You mention that it's flawed twice but then immediately cite data from it. If you're telling me it's flawed why should I care about the data?
Like all surveys, there's a selection bias. For example where are the world's millions of jQuery developers?
There's also a lot of controversy around Angular's treatment in the survey and an alleged pro-React bias. This shouldn't affect the Svelte numbers much.
Thanks for bringing it up - I'll improve the text somehow.
If you're using a bundler that can create chunks, your user is at best downloading this once in a blue moon.
The reply page I'm using now is 10% bigger total than these packages and has to be pulled every time apparently.
By what metric are these "huge runtime libraries"?
Gzipped. Uncompressed React is 6.3KB and react-dom is 114.5KB (and of course you're going to include react-dom, how else would you use it?!)
Uncompressed matters because it takes a device longer to parse more code. Particularly in a world where low end Android devices are being shipped with slow CPUs and very little RAM.
The real killer combination is React plus a giant blob of state that has to be parsed, and then hydrated into individual elements. It's a giant, giant waste of CPU time that is acceptable on my iPhone XS, but when I plug in a Nokia 2 it's horrifying. VDOM itself is needlessly CPU intense in many ways.
Even if you don't want to use Svelte it baffles me that more people don't use Preact. 9.5KB uncompressed and it does 95% of what React does. But people just don't seem to care.
This is...a trivial thing to measure, at best. Engineers write way worse code that will be much bigger targets to care about that will likely never be worked on.
> Particularly in a world where low end Android devices are being shipped with slow CPUs and very little RAM
The benchmarks for this (todomvc for example) aren't egregious, even for mobile devices.
> The real killer combination is React plus a giant blob of state that has to be parsed, and then hydrated into individual elements.
That is a bad end-engineer design choice, you don't have to write react that way.
> But people just don't seem to care.
Because they largely don't need to: Even if the end-engineer wrote and designed things in a performant way, it wouldn't account for the slowness of business process.
FWIW I did Lighthouse audits on React TodoMVC and Svelte TodoMVC In the performance category React gets 74 while Svelte gets 100.
First contentful paint:
React: 3.8s
Svelte: 0.9s
Time to interactive:
React: 4.8s
Svelte: 0.9s
I can't make you care about this stuff but the numbers are very straightforward.
Or Inferno, or Mithril, or Solid.
Using mithril/vue/react, there are assertions you can make about how a given action will modify the state, and given some state, how that state will be rendered.
I've not found a good way to make assertions on the behavior of code without resorting to poking through the DOM and dealing with asynchronous behaviors.
The compiler paradigm is really powerful. What if you could extend Svelte to give it knowledge of your db schema and it would figure out an optimized way to load data by generating all that code if needed. Probably something like this exists already somewhere and was forgotten about, but one can dream.
I'm concerned I'll spend all of my time restarting my application to validate changes. Is this a non-issue?
https://github.com/6eDesign/svelte-calendar
As for the other components, as the ecosystem grows, these things start to appear. The advantage to Svelte is that it's super-easy to integrate any vanilla component into, much more so than other frameworks. You can totally do away with nonsense wrapping projects, and just add the component verbatim.
This isn't specific to Svelte though. In fact your code is much more obfuscated with Svelte than with most comparable tools, since you're not serving the code you actually wrote, but rather the output of a compiler (while this is technically true if you're using TypeScript/a minifier/whatever, it's qualitatively different).
Not having a run time on the client is huge. But, the developer experience is exactly the same as you get from React and Vue.
You can trust this guy here, he knows what he is talking about.
It actively encourages mutability, which is a one way avenue to bugs bugs and more bugs. ie, shit like this is all over the official documentation:
<script>
let mutable = 1;
function f1() {
onMount(() => {
mutable = /* do some complex shit here */
});
}
function f2() {
onMount(() => {
mutable = /* do some complex shit here */
});
}
</script>
<Component onclick={f1}>
<Component2 onclick={f2}>
</Component2>
</Component>
Complete non-deterministic state changes. Absolutely abhorrent stuff. Cannot believe my coworkers and others actually like using this absolute garbage of a framework.I was thinking the same thing at first, why have this monstrous global state which is against every good practice you have ever heard of.
But then, if you want to keep state when switching between pages, you need to hoist up that state to the parent component. At some point, there's going to be a component near the root that keeps a lot of state for its children, that then has to be trickled down the component tree.
If you don't need to reuse those components in a different setting, then the redux solution feels quite ergonomic.
Now, this is coming from an embedded C programmer point of view, and this is my first foray into react/redux, so I'm obviously lacking context. But we're writing a front end for our embedded device, and I have to say I am pleasantly surprised with the experience.
You might want to watch my talk on "The State of Redux" from Reactathon 2019, where I covered some of this:
https://blog.isquaredsoftware.com/2019/03/presentation-state...
Also, note that we have a new Redux Toolkit package, which is intended to simplify many common Redux use cases, and is now our recommended approach for writing Redux logic:
Not sure if all this immutability talk in the JS community is parroting because "it's what Facebooks does" or what. Maybe it makes sense once you are building really big front end projects but personally I've never had an issue with mutable state in small to medium sized projects (less than 50k LOCs). Although I admit I've never worked on a Facebook-scale kind of project.
If you wouldn't mind reviewing https://news.ycombinator.com/newsguidelines.html and taking the spirit of this site more to heart, we'd be grateful. The idea is curious conversation, and you'll be better able to persuade others about mutability that way anyhow.