This looks nice: a Javascript framework for expressing _concepts_ that compiles down to vanilla JS. It looks like it ships a lot less code to the user. From the project's first [blog post](https://svelte.technology/blog/frameworks-without-the-framew...):
> The Svelte implementation of TodoMVC weighs 3.6kb zipped. For comparison, React plus ReactDOM without any app code weighs about 45kb zipped. It takes about 10x as long for the browser just to evaluate React as it does for Svelte to be up and running with an interactive TodoMVC.
I didn't study the thing, but the first question that comes to my mind is: if each component is rendered as a self contained piece of vanilla js, isn't the size of an app with lots of components going to increase much faster than with the library approach?
A complete library by itself can be pretty big, but it stays the same size no matter how many components you add.
I wondered that as well at first but then I realised that it probably doesn't have much shared code as it will be using the DOM directly and that is the shared dependency
I tried peeking at the EachBlock example and it came out at 7.5kb uncompressed. Copying and pasting the loop a few times makes that grow fairly quickly. Four copies of that example code is enough to make it grow over 22kb. For comparison, the render method in Mithril.js is about 21kb uncompressed. I imagine you would only need another 20 or 30 times more code to reach the size of React (~140kb).
Good point. I tested the demos and found the output (compiled down to ES5 and minified) is around 2-3KB for the minimal demos, and 9KB for the complex SVG clock demo.
The equivalent JSX output for that clock demo is about 1KB. So yes, I would guess that apps with many components would end up bigger (in total JS bundle size) than equivalent React apps.
Possible counterarguments:
- Bundling and gzipping several Svelte components together might compress well – a lot of their size comes from repetitive substrings like `.parentNode.removeChild` and `.setAttribute` etc.
- Once downloaded, the Svelte approach would probably be faster than React (at both rendering and updating) and would use less memory (no virtual DOM, no diffing, just fast granular updates).
- The self-contained nature of Svelte components makes it easier to treat them as atomic downloads and use them as needed. For example, you could get to a working UI extremely fast, and then download more components for below-the-fold or other pages in the background. This could work well with HTTP/2.
Storing state in Dom and reading from it could be dangerous. It's very easy to force layouts when you don't need. Frameworks like react and preact essentially do this. Abstract updating the view in a performant manner. Preact is 3kb. Magnitudes smaller than React.
I don't think it stores state on the DOM and reads from it. Pretty sure it just stores state in an object, and it updates the DOM granularly when that state changes. (That said, I did notice a bit of DOM traversal (node.parentNode...), which doesn't count as reading state from the DOM, but does rely on the structure of the DOM not having been altered by someone else since the last render – not sure why it needs to do this.)
The biggest problem with web apps today is the initial load time, not the total size of the app. If you can't render the first page the user lands on without serving a large framework, you're stuck.
But yes, an app built entirely out of standalone components would eventually overtake the total size of an app built using a more conventional framework. (By the time you get there, your app is probably already too big anyway, and you should be code-splitting.) We're going to add a compiler mode that addresses that very soon by deduping some code within an app.
Web components and polymer solve this problem "completly" by full encapsulation.
With some css preprocessing + vulcanizing you can even use separate js/css files from your component templates if that is your thing - they can get inlined in the build process.
A side note about that website. Thin and Extra-Thin fonts have no place in web design (there are some exceptions in huge title text). They are an unnecessary burden for people with limited eyesight and elderly people[1]. Even for me, on my 1366x768 screen (which is still the single most common resolution for cheap notebooks, dear HiDPI web designers[2]), the bullet text is hardly readable, the copyright line is completely unreadable. This effect is made even worse by choosing inadequate contrasts[3]. One can use subtle colors for increased contrast.[4]
Not sure why you were downvoted, I think it's entirely reasonable to bring up his concerns in an issue regardless of whether they are eventually implemented.
Precompilation is cool, but please don't imply that your framework is the first to do it. Precompiled templates significantly predate HTML, they were common in the mainframe world. In the HTML world there are tons of other templaters that allow precompilation. Handlebars is a common one: http://handlebarsjs.com/precompilation.html
This is a huge part of Javascript fatigue for me. I love the fact that we're recycling old concepts and mashing them up to get constant improvements and better tooling. It's the relentless hype and pretending that everything is new that really gets to me.
Handlebars templates have a runtime dependency (even when precompiled). Svelte does not.
Also, a precompiled Handlebars template is just a function for outputting an HTML string (with a runtime dependency). By comparison, the compiled Svelte output is a dependency-free JavaScript module for a dynamic view, which knows how (and when) to granularly update the browser DOM in response to state changes. It's unprecedented.
The Svelte compiler uses some ES2015 features (for...of, etc) that aren't currently supported in all browsers. It's designed primarily for use in Node.
Why not transpile the Svelte compiler to ES5 so it will run on all browsers? Otherwise devs may get the impression Svelte generated applications will not work on all browsers.
Exactly. My main gripe is that it won't even display the source code. I would be okay with the execution part of the REPL not working, but this just creates the impression that Svelte literally cannot display a block of text without ES6.
I don't want to be too harsh on the Svelte author. It's a minor inconvenience.
The guy did some incredible work - he wrote all of this code in a week. I'll look at the REPL code to see if there's a simple fix. All the levels of indirection, code generation and bundling may take a while for my non-Rich-Harris brain to sort out.
Svelte has a runtime dependency too, it's just bundled into the output. Everytime I've used handlebars I've bundled the runtime into my final application file. But I do it myself so it only gets bundled once rather than N times like it would be for svelte.
See the `update` method in the output of the Hello World example:
update () {
text1.data = root.name
}
This is the entire DOM manipulation code for this component.
There is no runtime library. The trick here is that the generated code is aware of exactly what DOM updates are needed. Instead of a large, general-purpose reconciliator like React's, you have specialized code for changing the DOM, generated from your templates.
Love it. I think the most discussion-worthy quote I found in the docs is this:
> It's currently fashionable to avoid two-way binding on the grounds that it creates all sorts of hard-to-debug problems and slows your application down, and that a one-way top-down data flow is 'easier to reason about'. This is in fact high grade nonsense. It's true that two-way binding done badly has all sorts of issues, and that very large apps benefit from the discipline of a not permitting deeply nested components to muck about with state that might affect distant parts of the app. But when used correctly, two-way binding simplifies things greatly.
I wonder what the author considers "used correctly" and "done badly" and how Svelte approaches this.
Trying to avoid boilerplate is in my experience not about laziness - especially when you consider the extreme lengths a lot of developers will go to to eliminate duplication and boilerplate from their codebases. Copying a Redux reducer that implements a standard set of CRUD actions is lazier in my mind than trying to abstract common patterns away.
For me at least, the reason boilerplate bothers me so much is that it impacts the readability of my code. Ideally, I'd like my codebase to express the business requirements of my solution as succinctly as possible - every line of boilerplate code I need to include to express yet again how to make an AJAX call, or update a piece of state, is a distraction from what I'm actually trying to accomplish with the application.
Taken to its extreme, that argues for writing everything in assembly language.
React's virtual DOM diffing makes components more readable than the previous style of writing code to explicitly manipulate the DOM and totally hides what's really happening. However, we trust that it's going to do the right thing, just as we trust that the JavaScript engine will do the right thing when it JITs and interprets our code.
It's not that people said "Everything is bad, do assembly". It's just that people identified 2WB as problematic and you just shouldn't do that one thing.
What I find interesting is that while I actually agree that 2WB as was done before was problematic, MobX which looks like previous-generation 2WB may actually be just fine because of features specific to its implementation of the idea (actions, and better tools for use in development)
Currently JS frontend folks also classify MVC as "problematic", yet a lot of successful software was written that way. So along with J2EE folks, this isn't really the community to look for style standards by default.
Honestly, given that I know of no two developers that have the same understanding of what MVC is and how the code should be divided, I have a feeling there's something wrong with the pattern itself, too.
I don't have a link handy, but I read a piece by one of the original MVC pioneers claiming that the pattern was designed for encapsulated components, usually fairly small, not entire applications. I suspect many of the quirks and disagreements between different MV* architectures derive from this fundamental misapplication of the pattern.
If the thing that I'm abstracting is routine, and unrelated to the business problem I'm solving, I don't need to know what's happening (at least in the sense of me or someone else coming back to read the code later). I don't need to know how an HTTP server, or the particulars of an AJAX request work most of the time.
true, but when there is something unexpected about how the AJAX request or the HTTP server are working then debugging is going to be harder because of the abstraction.
I guess I agree with that; I was thinking specifically in framework defined abstraction / usage.
And if the framework has abstracted away something that you end up needing to understand - well bad framework or bad usage I guess, but still difficult to figure out what's going on.
No, the work in fact will be easier - because something unexpected will either happen above, below or on abstraction boundary - as opposed to "somewhere in this big blob of function invocations". Also, you'll get to fix the bug in one place instead of having to hunt down every similarly looking piece of code because it may contain the same issue.
'illusion' and 'readability' are interesting choices for words, given that both refer to how something is perceived.
The argument I'd make is that the illusion is the point when you're writing well abstracted code. The abstraction makes it possible to write code with the assumption that some specific detail is taken care of automatically. While it's true that the detail is hidden, that lets the author and reader of the code focus on other details that might be more important.
Of course, this doesn't absolve anybody from needing to be at least somewhat aware of the abstractions, but hopefully most of the abstractions can fade into the background most of the time. (Anybody who's ever worked with a buggy compiler can attest to how frustrating it can be when this is not the case.)
Redux fixes two way binding by forcing the developer to emulate it using such a convoluted mechanism that there's no way to see that it's still broken; great job, FB rockstars!
If u don't like it you don't have to use it. And redux is nothing like that. It reduces a tonne of bugs among a lot of not so smart developers or beginners.
Wow. How can someone even understand it like that! No way. I actually meant what I wrote and im not really worried about what someone else might think about my comment. Cause it's way way softer.
My understanding is that there are two issues with two-way binding that are structural, and will be difficult to fix no matter how you approach it.
First is that if you look at the system as a graph of updates, automatically closing all cycles between variable update and widget means that any additional two-way binding links you add become a cycle, which makes it difficult to implement, model, and debug. If the framework only initially links the variable to the widget or the widget to the variable, the graph is a lot less populated to start with and creating a cycle is much harder.
Second is that the developer ends up wanting more and more complicated transforms over time, and having to implement both directions of them at once is much more difficult than having to implement only one direction, because not only are you writing two transforms instead of one, you also really ought to make sure the transforms are able to be roundtripped without data loss, and also that any invalid states on either side of the transform are handled sanely in some manner. Very few developers think this way; it's one of those places in programming where you really need to approach it with a mathematical state of mind, but it's generally being written by the "I don't see how programming is connected to math" types. (Which is something a two-way binding advocate needs to keep in mind when writing their library; you're not going to get your users to deeply understand the way the library works before they can benefit from it, they're going to want to just dive in and get something useful going.)
These are not necessarily insurmountable problems, but they are fundamental problems to having two-way binding. I think these two things are why it has never really taken off despite the fact I've seen at least half-a-dozen attempts over the years. I can imagine programming language tools that could help with both problems, but as what I'm seeing getting sketched up in my head requires a type system at least as strong as Haskell's to be practically usable without so many holes as to be insignificantly different from what we already have, it's not going to take off anytime soon.
This is a really helpful way of describing the problem. Concretely describing behavioural coupling in terms of graphs is much less hand-wavy than the normal, "things become tightly coupled and which becomes hard to deal with."
"...you also really ought to make sure the transforms are able to be roundtripped without data loss, ..."
In my experience this happens inevitably; either you code it right the first time or end users discover it and it comes back as an issue that gets fixed later. There is little math involved in my experience and it's pretty hard to miss this kind of issue unless you're a complete cowboy coder or have never seen it before. Once it bites you in the ass it's not likely to recurr.
I didn't say it involved math. I said it involved mathematical thinking.
You may have bodged together the relevant concepts by experience. That works perfectly fine. But there is a faster way to learn and teach it... if you can get people past the idea that there's some sort of virtue in bragging (for lack of a better word) about how math has nothing to do with programming and how little they know about the mathematics involved in programming. It's all way easier if you start with the concept of an isomorphism and learn how to compose them from the beginning, rather than having to rewrite the same concepts in your code over and over again without realizing it.
Two-way binding is being used without popular mention in some industry-specific areas. The area I'm familiar with is control software for audio processing hardware. Lots of different processing platforms allow the creation of control panels with a drag-and-drop UI, and all widgets assigned to the same hardware state variable are also linked to each other, in all directions.
I also implemented my own two-way/omnidirectional data binding system ages ago (before I knew what it would even be called) in Java Swing for another audio UI, and all the challenges you mention are real, but as you say, not insurmountable. Multiple copies of my UI can be controlling the same hardware, and they will all remain in sync without infinite feedback loops, but getting there took lots of work.
Dataflow constraints with solvers like DeltaBlue solve these problems and allow you to incrementally add additional constraints.
I show how this works for a simple example in my paper "Constraint as Polymorphic Connectors"[1]. I also show that constraints are useful for expressing the high-level architecture of many interactive systems and suggest how to two might be connected.
If not "used correctly" means a buggy app, and it's easy for an inexperienced developer to make those mistakes, you're still in for a world of pain. If you need to be an expert to avoid accidentally screwing everything up, there's still work to be done.
This is the whole "pit of success" thing Facebook talks about, the path of least resistance should be towards a functional nearly bug-free app. Certainly an app where bugs are relatively well-quarantined.
Hard to say when his only argument is "is in fact high grade nonsense". He's missing the big picture though: performance matters but not completely, it's not two way binding that makes two way binding bad, its developers using two way binding that makes it bad.
I also think it's ignorant to say it's fashionable to avoid two way binding, I've seen teams greatly benefit from avoiding it, teams with less experienced devs and devs who I've previously seen write terrible code. Maybe now two way binding would be easier for them, though I don't know; I'm unlikely to suggest they 180 on tech that has made them much more successful.
One counter argument to the author's point is that there were many not-very-popular 2WB frameworks, until React and Angular came along. 1-way, top down clearly outcompeted 2WB.
In my own experience, I worked on an app that migrated from a 2WB (forgot the name, sorry) to React, and it was night-and-day difference.
> Normally, this is the part where the instructions would tell you to add a <script> tag to your page or install something from npm. But because Svelte runs at build time, it works a little bit differently.
Something that doesn't say "normally, you'd be asked here to install something from npm, but" and then immediately goes on to ask that you install something from npm.
The 'Mustaches' bit killed it for me, but up until then I was enjoying the simplicity of the API. I like React (and React-like implementations) because of being able to use JS to build up a view
Yeah I interpreted his comment to be about syntax. OTOH React (JSX) lacks these control structures inline in the templates, it has to be done in separate steps, not a clear win for all situations.
In the past, I used virtual-dom. It works fine, but it's discontinued and doesn't address the problem of encapsulated component state. Now using this: https://github.com/AlexGalays/kaiju/
We should do a better job of clarifying: this isn't Mustache-the-language, it's just using {{ and }} as delimiters. The syntax is simpler than Mustache, and allows you to use any inline JavaScript expression, which will become fully reactive.
See e.g. http://bit.ly/2fRcyJq. The {{#if ...}} part is a control flow directive that allows Svelte to understand the structure of your app, but the condition of that if block is just a JS expression
Isn't the problem of including only the code the component actually needs already solved with dead code elimination? So the framework authors can include new features but as long as your component doesn't use them the code for those feature does not end up in the final bundle you serve to the user.
I sure am missing something here because the author of Svelte is actually also the author of rollup.js [1] which does exactly that, it eliminates dead code via its tree-shaking mechanism.
Unfortunately, UI frameworks are extremely hard to modularize in a way that makes them amenable to tree-shaking. So you're left with the alternative – cobbling together your own pseudo-framework out of 'small modules', which loses all the ergonomic advantages of a good framework. As you might imagine, I've been thinking about this problem for a long time :)
As far as I understand, ReactJS is a tightly weaved 40kB chunk of code which will be delivered to the browser no matter how ferociously you shake the tree.
React fanboy chiming in to say... an interesting approach to what is probably a problem.
i wonder, though, if compilation is really better than creating a library? if we look at the REPL output [0], we can see what comprises the bones of a Svelte component, and how much generated code will be replicated.
it also shows that the more interesting part here is it's method for rendering. it's use of data binding and compilation means we don't really need something like VDOM to stay efficient (at least, not a VDOM running in the browser).
GWT was backend oriented and sucked at delivering a nice UX in a decent timeframe. So it's actually extremely different.
You could compare this to vue, ractive + a strong compilation step.
The only other thing I like is CSS scoping, though. I think that CSS scoping is a problem in React, and current ideas on how to implement that in React are absolutely horrible IMHO.
Two-way binding is a step back I think, I don't love the name (lots of people will judge a new technology by its name), and the thought of introducing yet another framework is a nightmare.
I'd personally go with Polymer if you like scoped CSS, since it's already established and it's a good project.
I wonder if these ideas can be somehow applied to React, doing precompiling on React components, so that one can continue taking advantage of all freely available React components out there, and keep using Redux.
Look at css-module-values [0]. It's not perfect, but it lets you share values between JS and CSS. All values in the file are visible on the imported module.
I think the name will work out just fine (witness MySQL and PostgreSQL).
From looking at the docs, the two-way binding seems entirely optional and I can't find anything that would prevent a developer from using a redux model of state management.
I've got framework fatigue, too, but on the surface this project seems to embody the best of what I love: a tiny API, little magic, and getting out of the way.
Yes, I was thinking whether it would be possible to use Redux. You would need to add some code to hook that up to the components, though.
As for the name sure, but now there's a lot of competition between frameworks, and you want to get all help you can marketing-wise. I might be shallow, but I've not looked at projects a lot of times just because I didn't like the name. I just have no time to make informed decisions, there's too much stuff to look at. I'll see if besides the concept/purpose I like the logo and name a lot of times.
You don't have to use it – its effects are restricted to the subtree where you've explicitly opted in to it. I've personally found it to be a huge timesaver, and would never go back to a world where I didn't have the option of using it. But you're in no way forced into it.
> I wonder if these ideas can be somehow applied to React
A lot of people have wondered that, including me. Unfortunately, a compiler wouldn't be able to generate a good picture of the structure of a JSX component – because it's 'just JS' it resists the kind of meaningful static analysis that Svelte can take advantage of. I'd love to be proven wrong, but sadly I just don't think any JSX-based framework will ever be able to fully embrace these techniques.
Got it. I've been reading the guide, it looks good.
You did an awesome job.
I'm really scared about trying out yet another framework since I've tried pretty much all of them before settling on React, (and I guess a lot of people will be, too, since there's a new one every couple of months) but I'll try this weekend.
> Unfortunately, a compiler wouldn't be able to generate a good picture of the structure of a JSX component – because it's 'just JS' it resists the kind of meaningful static analysis that Svelte can take advantage of.
Can you elaborate more on this? It seems like passing the compiled JS through Esprima and checking the call graph would give you a fairly detailed structural representation of a JSX UI. You may need to do some graph stitching across module boundaries, haven't tried this myself.
The way I see it is Svelte treating the browser JS implementation as "machine code": while frameworks such as React or Vue are by definition a (runtime) layer on top of vanilla JS, Svelte _compiles_ your code to vanilla JS.
Vanilla JS has long been used to refer to a lower-level JavaScript; ie not using any abstractions. Vanilla JS was often used to compare to jQuery. Of course jQuery is JavaScript.
Vue.js has single file components [1] and template precompilation [2] (or optionally JSX support, which is basically a precompiled template).
I don't see the point of yet another framework here.
The "no dependencies" argument seems to fall down for me, since it would seem to me that they would need to duplicate a lot of code for state management and rendering, bloating the code for anything more complex.
And if there's some clever tree shaking or whatever going on, than I don't see the point as opposed to just including another JS file...
I couldn't find any explanation of what's so different here, worthy of creating another framework for it. Would love to be enlightened!
there is always room for a framework smaller than other frameworks. mature frameworks tend to get bloated overtime, become hard to reason about and learn for new developers.
if it wasn't for projects like that we'd be coding in some feature rich ims/cobol framework.
Yep, we'll be adding more examples soon – definitely on the TODO list. In the meantime you can take a look at our TodoMVC implementation – it's 3.6kb zipped (Vue is 17.2kb without any app code. Not a criticism, just context)
So if you want to use a router in Vue what do you do? Well, you install vue-router. The point of Svelte is that it can infer all of the features you are using for you, and not compile the ones that you aren't.
235 comments
[ 7.8 ms ] story [ 273 ms ] thread> The Svelte implementation of TodoMVC weighs 3.6kb zipped. For comparison, React plus ReactDOM without any app code weighs about 45kb zipped. It takes about 10x as long for the browser just to evaluate React as it does for Svelte to be up and running with an interactive TodoMVC.
A complete library by itself can be pretty big, but it stays the same size no matter how many components you add.
I tried peeking at the EachBlock example and it came out at 7.5kb uncompressed. Copying and pasting the loop a few times makes that grow fairly quickly. Four copies of that example code is enough to make it grow over 22kb. For comparison, the render method in Mithril.js is about 21kb uncompressed. I imagine you would only need another 20 or 30 times more code to reach the size of React (~140kb).
https://www.reddit.com/r/javascript/comments/5fcwhz/svelte_t...
The equivalent JSX output for that clock demo is about 1KB. So yes, I would guess that apps with many components would end up bigger (in total JS bundle size) than equivalent React apps.
Possible counterarguments:
- Bundling and gzipping several Svelte components together might compress well – a lot of their size comes from repetitive substrings like `.parentNode.removeChild` and `.setAttribute` etc.
- Once downloaded, the Svelte approach would probably be faster than React (at both rendering and updating) and would use less memory (no virtual DOM, no diffing, just fast granular updates).
- The self-contained nature of Svelte components makes it easier to treat them as atomic downloads and use them as needed. For example, you could get to a working UI extremely fast, and then download more components for below-the-fold or other pages in the background. This could work well with HTTP/2.
But yes, an app built entirely out of standalone components would eventually overtake the total size of an app built using a more conventional framework. (By the time you get there, your app is probably already too big anyway, and you should be code-splitting.) We're going to add a compiler mode that addresses that very soon by deduping some code within an app.
I suppose that's why it's so critical that the app zips down while it's going across the wire.
I can't help but wonder if shipping a rudimentary bootstrap framework that wraps those methods would be helpful.
The Preact TodoMVC version is ~2x bigger than this example, but it states nowhere how this stuff scales with more components.
[0] https://preactjs.com/
With some css preprocessing + vulcanizing you can even use separate js/css files from your component templates if that is your thing - they can get inlined in the build process.
[1] http://www.aiga.org/typography-and-the-aging-eye
[2] http://blog.typekit.com/2013/05/01/hi-dpi-typography/
[3] https://www.nngroup.com/articles/low-contrast/
[4] https://www.viget.com/articles/color-contrast
or submit a pull request
What a nightmare being a programmer who has poor eyesight. My eyes kill me after a whole day of looking at code and I have 10/10.
This is a huge part of Javascript fatigue for me. I love the fact that we're recycling old concepts and mashing them up to get constant improvements and better tooling. It's the relentless hype and pretending that everything is new that really gets to me.
Also, a precompiled Handlebars template is just a function for outputting an HTML string (with a runtime dependency). By comparison, the compiled Svelte output is a dependency-free JavaScript module for a dynamic view, which knows how (and when) to granularly update the browser DOM in response to state changes. It's unprecedented.
Check out the output from this SVG Clock demo: https://svelte.technology/repl/?gist=44e20b4e0224617d228e3c3...
Why not transpile the Svelte compiler to ES5 so it will run on all browsers? Otherwise devs may get the impression Svelte generated applications will not work on all browsers.
The guy did some incredible work - he wrote all of this code in a week. I'll look at the REPL code to see if there's a simple fix. All the levels of indirection, code generation and bundling may take a while for my non-Rich-Harris brain to sort out.
There is no runtime library. The trick here is that the generated code is aware of exactly what DOM updates are needed. Instead of a large, general-purpose reconciliator like React's, you have specialized code for changing the DOM, generated from your templates.
> It's currently fashionable to avoid two-way binding on the grounds that it creates all sorts of hard-to-debug problems and slows your application down, and that a one-way top-down data flow is 'easier to reason about'. This is in fact high grade nonsense. It's true that two-way binding done badly has all sorts of issues, and that very large apps benefit from the discipline of a not permitting deeply nested components to muck about with state that might affect distant parts of the app. But when used correctly, two-way binding simplifies things greatly.
I wonder what the author considers "used correctly" and "done badly" and how Svelte approaches this.
I have the feeling most programmers are just lazy, that's why they use 2WB.
And I can't blame them. Redux is much more boilerplate than MobX, for example.
For me at least, the reason boilerplate bothers me so much is that it impacts the readability of my code. Ideally, I'd like my codebase to express the business requirements of my solution as succinctly as possible - every line of boilerplate code I need to include to express yet again how to make an AJAX call, or update a piece of state, is a distraction from what I'm actually trying to accomplish with the application.
But if you hide boilerplate you not really improve readability. Not seeing what is really happening just creates the illusion of readability.
React's virtual DOM diffing makes components more readable than the previous style of writing code to explicitly manipulate the DOM and totally hides what's really happening. However, we trust that it's going to do the right thing, just as we trust that the JavaScript engine will do the right thing when it JITs and interprets our code.
It's not that people said "Everything is bad, do assembly". It's just that people identified 2WB as problematic and you just shouldn't do that one thing.
And if the framework has abstracted away something that you end up needing to understand - well bad framework or bad usage I guess, but still difficult to figure out what's going on.
The argument I'd make is that the illusion is the point when you're writing well abstracted code. The abstraction makes it possible to write code with the assumption that some specific detail is taken care of automatically. While it's true that the detail is hidden, that lets the author and reader of the code focus on other details that might be more important.
Of course, this doesn't absolve anybody from needing to be at least somewhat aware of the abstractions, but hopefully most of the abstractions can fade into the background most of the time. (Anybody who's ever worked with a buggy compiler can attest to how frustrating it can be when this is not the case.)
Don't write things like that, it always reads like "Noone cares about your opinion, so stop using X and also stop writing about how bad X is"
You could have written your comment without that sentence and it would still convey your opinion :)
First is that if you look at the system as a graph of updates, automatically closing all cycles between variable update and widget means that any additional two-way binding links you add become a cycle, which makes it difficult to implement, model, and debug. If the framework only initially links the variable to the widget or the widget to the variable, the graph is a lot less populated to start with and creating a cycle is much harder.
Second is that the developer ends up wanting more and more complicated transforms over time, and having to implement both directions of them at once is much more difficult than having to implement only one direction, because not only are you writing two transforms instead of one, you also really ought to make sure the transforms are able to be roundtripped without data loss, and also that any invalid states on either side of the transform are handled sanely in some manner. Very few developers think this way; it's one of those places in programming where you really need to approach it with a mathematical state of mind, but it's generally being written by the "I don't see how programming is connected to math" types. (Which is something a two-way binding advocate needs to keep in mind when writing their library; you're not going to get your users to deeply understand the way the library works before they can benefit from it, they're going to want to just dive in and get something useful going.)
These are not necessarily insurmountable problems, but they are fundamental problems to having two-way binding. I think these two things are why it has never really taken off despite the fact I've seen at least half-a-dozen attempts over the years. I can imagine programming language tools that could help with both problems, but as what I'm seeing getting sketched up in my head requires a type system at least as strong as Haskell's to be practically usable without so many holes as to be insignificantly different from what we already have, it's not going to take off anytime soon.
You may have bodged together the relevant concepts by experience. That works perfectly fine. But there is a faster way to learn and teach it... if you can get people past the idea that there's some sort of virtue in bragging (for lack of a better word) about how math has nothing to do with programming and how little they know about the mathematics involved in programming. It's all way easier if you start with the concept of an isomorphism and learn how to compose them from the beginning, rather than having to rewrite the same concepts in your code over and over again without realizing it.
I also implemented my own two-way/omnidirectional data binding system ages ago (before I knew what it would even be called) in Java Swing for another audio UI, and all the challenges you mention are real, but as you say, not insurmountable. Multiple copies of my UI can be controlling the same hardware, and they will all remain in sync without infinite feedback loops, but getting there took lots of work.
Dataflow constraints with solvers like DeltaBlue solve these problems and allow you to incrementally add additional constraints.
I show how this works for a simple example in my paper "Constraint as Polymorphic Connectors"[1]. I also show that constraints are useful for expressing the high-level architecture of many interactive systems and suggest how to two might be connected.
[1] https://www.hpi.uni-potsdam.de/hirschfeld/publications/media...
If not "used correctly" means a buggy app, and it's easy for an inexperienced developer to make those mistakes, you're still in for a world of pain. If you need to be an expert to avoid accidentally screwing everything up, there's still work to be done.
This is the whole "pit of success" thing Facebook talks about, the path of least resistance should be towards a functional nearly bug-free app. Certainly an app where bugs are relatively well-quarantined.
I also think it's ignorant to say it's fashionable to avoid two way binding, I've seen teams greatly benefit from avoiding it, teams with less experienced devs and devs who I've previously seen write terrible code. Maybe now two way binding would be easier for them, though I don't know; I'm unlikely to suggest they 180 on tech that has made them much more successful.
In my own experience, I worked on an app that migrated from a 2WB (forgot the name, sorry) to React, and it was night-and-day difference.
Similar things have been said about memory allocation in 'do whatever you want' languages like C++.
For how it actually looks.
Interestingly, it shares most similarities to vue. I guess vue is winning mindshare.
> Normally, this is the part where the instructions would tell you to add a <script> tag to your page or install something from npm. But because Svelte runs at build time, it works a little bit differently.
> First, install the CLI:
> npm install -g svelte-cli
They might want to change their opening
> installs something from npm
> In other frameworks, you'd have to install something with npm...
>Run npm install -g svelte-cli
does it try and do as much as it can without javascript?
I sure am missing something here because the author of Svelte is actually also the author of rollup.js [1] which does exactly that, it eliminates dead code via its tree-shaking mechanism.
[1]: http://rollupjs.org
i wonder, though, if compilation is really better than creating a library? if we look at the REPL output [0], we can see what comprises the bones of a Svelte component, and how much generated code will be replicated.
it also shows that the more interesting part here is it's method for rendering. it's use of data binding and compilation means we don't really need something like VDOM to stay efficient (at least, not a VDOM running in the browser).
[0] https://svelte.technology/repl/?gist=0ed5146aa22c28410dfcff2...
Drawbacks would be maturity, community size, template closed expresiveness and not typescript friendly. Nothing too major.
The only other thing I like is CSS scoping, though. I think that CSS scoping is a problem in React, and current ideas on how to implement that in React are absolutely horrible IMHO.
Two-way binding is a step back I think, I don't love the name (lots of people will judge a new technology by its name), and the thought of introducing yet another framework is a nightmare.
I'd personally go with Polymer if you like scoped CSS, since it's already established and it's a good project.
I wonder if these ideas can be somehow applied to React, doing precompiling on React components, so that one can continue taking advantage of all freely available React components out there, and keep using Redux.
I've tried a few solutions to add styles to React components but they all had something that didn't make them see as the perfect solution.
This looks very good, I've never tried it before.
Thanks.
The only tiny issue left with that approach is that you still can't share code (for instance, colors) between JS & CSS.
but overall, I think it's the best compromise today.
[0] https://github.com/css-modules/postcss-modules-values
From looking at the docs, the two-way binding seems entirely optional and I can't find anything that would prevent a developer from using a redux model of state management.
I've got framework fatigue, too, but on the surface this project seems to embody the best of what I love: a tiny API, little magic, and getting out of the way.
As for the name sure, but now there's a lot of competition between frameworks, and you want to get all help you can marketing-wise. I might be shallow, but I've not looked at projects a lot of times just because I didn't like the name. I just have no time to make informed decisions, there's too much stuff to look at. I'll see if besides the concept/purpose I like the logo and name a lot of times.
You don't have to use it – its effects are restricted to the subtree where you've explicitly opted in to it. I've personally found it to be a huge timesaver, and would never go back to a world where I didn't have the option of using it. But you're in no way forced into it.
> I wonder if these ideas can be somehow applied to React
A lot of people have wondered that, including me. Unfortunately, a compiler wouldn't be able to generate a good picture of the structure of a JSX component – because it's 'just JS' it resists the kind of meaningful static analysis that Svelte can take advantage of. I'd love to be proven wrong, but sadly I just don't think any JSX-based framework will ever be able to fully embrace these techniques.
You did an awesome job.
I'm really scared about trying out yet another framework since I've tried pretty much all of them before settling on React, (and I guess a lot of people will be, too, since there's a new one every couple of months) but I'll try this weekend.
Thanks!
Can you elaborate more on this? It seems like passing the compiled JS through Esprima and checking the call graph would give you a fairly detailed structural representation of a JSX UI. You may need to do some graph stitching across module boundaries, haven't tried this myself.
What static analysis does Svelte provide?
What kind of logic are they using here? Isn't any javascript just vanilla JS?
It's a very slight but interesting distinction.
I don't see the point of yet another framework here.
The "no dependencies" argument seems to fall down for me, since it would seem to me that they would need to duplicate a lot of code for state management and rendering, bloating the code for anything more complex.
And if there's some clever tree shaking or whatever going on, than I don't see the point as opposed to just including another JS file...
I couldn't find any explanation of what's so different here, worthy of creating another framework for it. Would love to be enlightened!
[1] https://vuejs.org/v2/guide/single-file-components.html
[2] https://www.npmjs.com/package/vue-template-compiler
if it wasn't for projects like that we'd be coding in some feature rich ims/cobol framework.
https://svelte-todomvc.surge.sh
He's an inventing and implementing machine.
closes tab