I’m excited to try this more but I have mixed feelings about Svelte. The concept is brilliant but I feel like there’s too much API and some weird gotchas. I hope there’ll be an effort to simplify it if possible.
I think the 'too much API' feelings might be more unfamiliarity than anything. The API surface area is much smaller than anything like Angular, Vue etc, and although it's a fundamentally different approach to React I'd argue Svelte has a much shallower learning curve there as well. We're very open to feedback and suggestions though!
For example, what exactly does a tag starting with colon mean? Is it just arbitrary syntax for things that don't fit in? What does a colon in an attribute mean? (i.e., why on:click rather than onclick or onClick or even something simpler like :onClick?) Why is there both {{#if condition}}<p>Content</p>{{/if}} and {{{condition && '<p>Content</p>'}}}? I feel like all these different concepts break the "it's just HTML" promise, when it seems like it could be simplified a lot.
Yes, JSX has similar gotchas, but at least it has references and specifications.
And what's up with the crazy semantics of computed properties?
Sorry if this sounds negative, but these have been genuine problems for me in getting a hang of Svelte.
{{#if condition}}...{{/if}} tells Svelte something about the structure of your app. {{{condition && '<p>Content</p>'}}} doesn't, and you can't add interactivity to the <p> if it's just a string. Moreover, if `condition` is `undefined`, then that's the string that will get rendered to the DOM. Generally, {{{triples}}} should be used for blobs of HTML you get from data sources, such as a blog post.
If you can overcome your distaste for the computed property dependency injection, you'll hopefully find it's an extremely easy and compact syntax for declaring arbitrarily complex graphs of properties. The advantage of doing it this way is that Svelte can generate, at compile time, very efficient code for updating computed properties without any wasteful runtime dependency tracking. I realise it's slightly controversial (because it's a Svelte idiom, rather than something in JS itself), but for those who have embraced them, computed properties are one of the best features of Svelte!
Why not simply use the "correct" ES6 syntax to do the same thing? It's almost identical:
computed: {
hours: ({time}) => time.getHours(),
minutes: ({time}) => time.getMinutes(),
seconds: ({time}) => time.getSeconds()
}
This way, the compiler could simply optimise idiomatic cases where it's easy to see which data is depended on, without breaking the language.Trouble is, coming from a Vue background (where computed props do not have to rely on a state item), the pre-requisite in Svelte to do so seemed at first a major PITA (then I saw the light/benefits and was actually easily able to re-work the Vue versions to Svelte).
Unless this is the only place Svelte goes slightly 'off-piste' in terms of JS then personally I'd leave as is, otherwise make the change
What made you turn away from javascript and into templates?
We've basically covered all those idioms in a few paragraphs. There's very little extra stuff to learn. Now if I may be blunt in return, I was converting the React RealWorld implementation to Svelte for the purposes of this post, and there were moments that I spat out my coffee at how absurd some of it was — twice as much code, with some truly bizarre (but idiomatic-to-React) constructs. It's all a matter of perspective and familiarity!
Performance-wise, you'll get great results with either framework. You mention debugging — Svelte creates useful sourcemaps, and the generated code is very readable anyway. Svelte has a few features you might find interesting (AFAIK Marko doesn't offer these, though I'm not intimately familiar with it):
* it can compile directly to custom elements * your styles are scoped to the component * declarative transitions * built-in global store (think Redux, but zero boilerplate) * useful element bindings (for e.g. customisable media players https://svelte.technology/repl?example=binding-media-element...) * computed properties. these are a lifesaver when you're doing a lot of complex reactive stuff
and so on. Also, I don't think Marko has an equivalent of Sapper.
Finally, while Marko is slimmer than the likes or React or Vue, there's still a runtime library you need to include on your pages. A typical Sapper page is about the same size as Marko by itself, before you've added any app code.