The likely reason it never caught on, is that the library has similar pitfalls to Backbone. The entire application and component lifecycle has to be coded explicitly:
- manually attaching DOM elements to view controllers
- manually attaching child views
- models which have to be wired individually via .listenTo
- models can be out of sync
- possibility of infinite loops if the events accidentally recurse
A better tiny alternative would be hyperapp[1] or even Preact, that has a similar bundle size.
Modern React code with hooks, contexts and all went almost full circle though, it's now not too far off from the amount of code you'd write with Backbone, maybe more.
Hooks, by themselves, can be ok, since you avoid componentDidMount, componentDidUnmount, etc.
I’ve started enjoying functional components more once I realized I could destructure props in the function parameters rather than in the very first line of the method.
I hate the boilerplate in react. Import, types for props, exports and all the hooks. Many codebases I've seen have even conventions which increase it. Small things but it adds up and I unconciously avoid creating new components when possible. Many people use some shortcuts to autogenerate all of this stuff, but I don't like tools like this.
Svelte is the gold standard of no boilerplate. An empty file is a valid component.
The infinite loop for example, is easy to get with a circular chain: 'change' -> .listenTo subscriber -> triggers another change. Probably won't happen in a single file, but because updates can come from anywhere, as an app grows you are exponentially more likely to accidentally get one.
The example demonstrates a couple of the downsides, like directly wiring listenTo -> render, but it has no child views or interaction between different models / collections. With a bit more complexity I'm sure it would hit all of those points.
Did you ever end up building a production app with the library?
It does have child views (to do item). You can't get a circular chain any more than with react. ListenTo is written manually only for special cases there, otherwise a controller is simply bound to a model and it's all handled for you.
When React was first released, general JS public was skeptical towards it, but ClojureScript community immediately embraced it. One of the early articles praising React for it’s performance was written by David Nolen: https://swannodette.github.io/2013/12/17/the-future-of-javas...
Something I notice when dabbling in random client side frameworks is how it’s not obvious how to go from the building blocks in the docs to more complex use cases.
SwiftUI is a great example of this struggle where the docs show API building blocks but tend to end before getting across the sort of higher level understanding that lets you synthesize less-trivial patterns on your own.
The Combine docs (SwiftUI’s reactive/observable abstraction) will go on and on but never explain that this is the tool you are supposed to use for, say, computed properties, so most people will try to create more @State constructs that get updated in a didUpdate block or come up with some other solution.
It’s something that’s easy to take for granted when using React where the docs try to give you at least a raging clue about intended use cases and are considered failures if they don’t, and it’s popularity means at least many have asked the same questions before you.
It’s a major point we dismiss when we complain about people “cargo culting” popular tech, especially in the UI space where the Best Solution remains an open question and the subject of continual experimentation.
Broadly speaking, I think this is one area where people struggle when getting started with programming.
You can read the docs about given library function but often it's not clear how that certain function should be used in practice, leading to confusion and ultimately Stack Overflow.
This is painfully true in every area. I wish documentation writers would focus less on exhaustively documenting every single thing and instead really explain the surprising parts.
Maybe don't even worry about documenting the "height" parameter. I'll figure out if it's in pixels or percent or rems soon enough.
But if you have a parameter called "snefbolian" I really want a paragraph or more explaining that, it isn't sufficient to give the unit.
"Why are you giving me a pixel? In this context we switch to a unit defined as 1/72 of an inch on a screen with standard pixel density."
- Poppler
(Yes, I know it's because they're using printer vocabulary for rendering. I know this because I googled the magic numbers in their example code. It would have been nice to read something on the docs)
I remember the original react docs were great for teaching the vocabulary, but then it seemed we had to figure out sentences and paragraphs on our own. To be fair, I started that journey during (or soon after?) the beta. It would be unreasonable to expect more from the docs at that point.
But we definitely need an intermediate and advanced level of documentation for these things:
> Now that you know how to use vars, loop, etc, let's build a [app] from scratch to see how it all works together.
And then...
> Now that you understand how to build [app] from scratch, let's use some advanced techniques to improve the app. Here's why we do this, that, and a third as our app grows.
And it needs to be something more significant than a TODO app. I get the appeal of a TODO app. It's basically the simplest useful form of CRUD. But that simplicity is why it's not the best example beyond introduction.
In HN fashion it was more of an open thought I had about the topic in general rather than a response to your library.
But even reading code for projects like a todo app will show you how the code can be put together but necessarily higher level understanding.
In other words, the kind of eurekas you think people should be able to glean from a real world example are great to establish in plain text. For example, imagine what you would write if you had a blog post that walks the user through how to build the todomvc.
Another example is how I launched two macOS apps to the app store before I realized that the Combine api was supposed to be used and abused rather than a lower level api to be avoided in favor of other state management levers. And all it took was for someone with much more experience to simply tell me.
I think it’s the hardest part of writing docs. And maybe you do it somewhere, I only read the api reference pages.
The best example of this I can think of is mhartl’s Ruby in Rails tutorial. It has lots of wisdom about the “why” instead of just the “how”.
This is not a React alternative. It achieves the same end result as React, it's smaller, and it's probably faster in some situations. But those are things that pretty much every app shouldn't need to care much about - every framework is fast enough to nail 60fps if you're using it properly, and few of them are so bloated that they add more than a couple of percentage points to the page weight. 3KB is definitely better than 30KB, but if your main bundle is 3000KB your users aren't going to be impressed when you switch. Clearly this varies with the audience you cater for too - a B2B app with 500 users can afford to add a bit more weight to a page than a B2C app with 200,000,000 users. We need to choose our tech accordingly.
What most JS developers should really care about is the ecosystem, the tooling, the documentation, the code quality, and the testability of their chosen framework. React really shines here. There's a ton of good libraries, there are some superb tools, the docs are very well written (especially the new beta docs), React's core code is accessible and readable, and (mostly thanks to Kent Dodds) React apps are very testable. A React-based app can be (but too often isn't) written well, be mostly bug free, be fast, and be easy to build a business on.
This is why Espresso.js isn't an alternative to React. A dev using it just won't be as capable as a dev using React, because the surrounding tooling isn't there. React isn't just the code that gets bundled in. It's everything else as well. Libraries that claim to be smaller and faster but that lack that quality of dev experience should really concentrate on improving that rather than shaving another 1ms or 0.1KB off the load time.
This is a weird comment and makes a lot of assumptions on why someone would even choose a view library like this to begin with. React is just React; a small virtual dom library with little opinions on how you test and structure your application. Of course, React has the largest and most mature ecosystem of any modern JavaScript view library, which is what you are getting at.
I think the comment is actually completely on-point and tells that OP isn't just some random backend developer that rants about frontend development. If you're using something in a professional manner, you need to leverage the existing tooling, ecosystem and libraries.
Do you have time to rewrite things from scratch like react-testing-library, styled-components, Apollo GraphQL, DraftJS, react-hook-form, and various component libraries? If you want to actually focus on your business logic you don't have time to do this stuff, otherwise you'll spend two weeks making a dropdown.
I disagree, to me it seems like they are having an argument by themselves simply because the post dare call a minimal view library a "React alternative".
EDIT: It's also just kind of off-topic and representative of stereotypical HN cynicism.
Also "using something in professional manner" itself is a huge assumption -- are we going to forget that people do front-end development in non-corporate or professional settings?
Calling a minimal view library a "React alternative" may be borderline offensive to professional React developers, but it's also actually helpful to people who are looking for an alternative when React doesn't fit their use-case.
Espresso.js is a React alternative like TempleOS is a Windows alternative. The ecosystem is a core part of React, because of course it is.
It's similar to how people build "wordpress alternatives" that are just a blog with zero plugin capability and then wonder how their better product isn't getting traction. Sure, technically, wordpress is just a blog; but that is not why people choose it. (And I have no love for it)
I prefer to compare apples to apples. Maybe a better example would be comparing [less popular view library] to React is like comparing Linux w/ Proton to Windows for the purpose of gaming.
It's also just kind of off-topic and representative of stereotypical HN cynicism.
I don't think that's the tone I was aiming for. My point is really that for Espresso, or any other library that's aiming to be an alternative to another big and popular library, needs to do more than just being technically better. It needs good examples, clear docs, support from the community, and ultimately a well thought out "ethos". Espresso is lacking a few of those things. That's not even really a criticism of the library; it's just the state of library development and populism in the JS ecosystem in general. A large part of a devs decision making process comes down to things that aren't code.
It's a bit like the "build it, they will come" route to market that kills so many startups. Just making something great isn't enough. You also need to handhold your users to get them to try it.
Contrived in that OP focused on particular developer needs and ignored the rest.
> What most JS developers should really care about is the ecosystem, the tooling, the documentation, the code quality, and the testability of their chosen framework
This isn't just OP's opinion. OP is lite gatekeeping by suggesting that most JS developers should share their opinion. I will agree that testability is paramount, but lacking specific contexts (embedded, high-perf, security, etc) the rest of the heuristic deals with a series of trade-offs.
OP has possibly worked in a limited context when writing front-end code, and has not been forced to make trade-offs. The most glaring issue with their argument is that developers should stick with libraries that have large ecosystems and tooling. This is an anti-progress, anti-innovation sentiment which does not even hold up. Like another poster said, there was no reason to ever drop jQuery and move to view libraries if ecosystem and tooling were paramount.
To play devil's advocate for a bit, what you said applies to jQuery as well. It has an enormous plugin ecosystem. I know, I know, people are going to now start pointing out how X or Y specific thing is "better" in React, but then isn't bundle size, application space code conciseness, etc also W and Z specific things?
At what point is the argument for one toolchain over another simply circular reasoning / backpatting? Trade-off analysis isn't just pointing at X, it's about looking at the balance of X and Y vs W and Z.
jQuery is a bit of an interesting case, because it was so successful that it APIs got implemented in browsers themselves.
The advice that I’ve seen is that you should replace jQuery selector stuff with vanilla js and css whenever possible, and for a lot of projects that doesn't leave much.
Indeed, which is why I use React even though new frameworks are popping up; the network effect of the ecosystem is just too strong. I originally learned VueJS but had to abandon it because the libraries I wanted to use just weren't there or were very sparsely supported.
As somebody who has done some very gross things with jQuery/vanilla JS when I should've really been using the pattern of "components just redraw themselves based on props/state" (or whatever it is that Reacts boils down to), I'm not so sure this is the right answer.
Vanilla JavaScript/jQuery projects probably start off small/without bad intentions. It's what happens to them overtime as they grow (fall apart) in my opinion.
Is Espresso to React what Flask is to Django, or Sinatra to Rails? I haven't used React, but I far prefer Flask to Django; in many cases you don't need all that extra overhead and complexity that the "full-featured" framework provides.
I wouldn’t compare React to Django and Rails, as in being a “full framework” that is opinionated and has specific ways of doing things. React is still more of just a rendering library than a framework in the traditional sense.
48 comments
[ 3.0 ms ] story [ 122 ms ] thread- manually attaching DOM elements to view controllers
- manually attaching child views
- models which have to be wired individually via .listenTo
- models can be out of sync
- possibility of infinite loops if the events accidentally recurse
A better tiny alternative would be hyperapp[1] or even Preact, that has a similar bundle size.
[1] https://github.com/jorgebucaran/hyperapp
So much boilerplate, I could spend a whole day writing code and barely have the same stuff written that it would take me two hours to do with React.
I love stuff that makes me more productive and minimizes my boilerplate writing.
I’ve started enjoying functional components more once I realized I could destructure props in the function parameters rather than in the very first line of the method.
Svelte is the gold standard of no boilerplate. An empty file is a valid component.
Check out an example app: https://github.com/akrymski/espresso.js/tree/master/examples...
The example demonstrates a couple of the downsides, like directly wiring listenTo -> render, but it has no child views or interaction between different models / collections. With a bit more complexity I'm sure it would hit all of those points.
Did you ever end up building a production app with the library?
It does have child views (to do item). You can't get a circular chain any more than with react. ListenTo is written manually only for special cases there, otherwise a controller is simply bound to a model and it's all handled for you.
When React was first released, general JS public was skeptical towards it, but ClojureScript community immediately embraced it. One of the early articles praising React for it’s performance was written by David Nolen: https://swannodette.github.io/2013/12/17/the-future-of-javas...
You could as accurately imagine it as "scary new thing."
SwiftUI is a great example of this struggle where the docs show API building blocks but tend to end before getting across the sort of higher level understanding that lets you synthesize less-trivial patterns on your own.
The Combine docs (SwiftUI’s reactive/observable abstraction) will go on and on but never explain that this is the tool you are supposed to use for, say, computed properties, so most people will try to create more @State constructs that get updated in a didUpdate block or come up with some other solution.
It’s something that’s easy to take for granted when using React where the docs try to give you at least a raging clue about intended use cases and are considered failures if they don’t, and it’s popularity means at least many have asked the same questions before you.
It’s a major point we dismiss when we complain about people “cargo culting” popular tech, especially in the UI space where the Best Solution remains an open question and the subject of continual experimentation.
You can read the docs about given library function but often it's not clear how that certain function should be used in practice, leading to confusion and ultimately Stack Overflow.
Maybe don't even worry about documenting the "height" parameter. I'll figure out if it's in pixels or percent or rems soon enough.
But if you have a parameter called "snefbolian" I really want a paragraph or more explaining that, it isn't sufficient to give the unit.
- Poppler
(Yes, I know it's because they're using printer vocabulary for rendering. I know this because I googled the magic numbers in their example code. It would have been nice to read something on the docs)
I remember the original react docs were great for teaching the vocabulary, but then it seemed we had to figure out sentences and paragraphs on our own. To be fair, I started that journey during (or soon after?) the beta. It would be unreasonable to expect more from the docs at that point.
But we definitely need an intermediate and advanced level of documentation for these things:
> Now that you know how to use vars, loop, etc, let's build a [app] from scratch to see how it all works together.
And then...
> Now that you understand how to build [app] from scratch, let's use some advanced techniques to improve the app. Here's why we do this, that, and a third as our app grows.
And it needs to be something more significant than a TODO app. I get the appeal of a TODO app. It's basically the simplest useful form of CRUD. But that simplicity is why it's not the best example beyond introduction.
But even reading code for projects like a todo app will show you how the code can be put together but necessarily higher level understanding.
In other words, the kind of eurekas you think people should be able to glean from a real world example are great to establish in plain text. For example, imagine what you would write if you had a blog post that walks the user through how to build the todomvc.
Another example is how I launched two macOS apps to the app store before I realized that the Combine api was supposed to be used and abused rather than a lower level api to be avoided in favor of other state management levers. And all it took was for someone with much more experience to simply tell me.
I think it’s the hardest part of writing docs. And maybe you do it somewhere, I only read the api reference pages.
The best example of this I can think of is mhartl’s Ruby in Rails tutorial. It has lots of wisdom about the “why” instead of just the “how”.
What most JS developers should really care about is the ecosystem, the tooling, the documentation, the code quality, and the testability of their chosen framework. React really shines here. There's a ton of good libraries, there are some superb tools, the docs are very well written (especially the new beta docs), React's core code is accessible and readable, and (mostly thanks to Kent Dodds) React apps are very testable. A React-based app can be (but too often isn't) written well, be mostly bug free, be fast, and be easy to build a business on.
This is why Espresso.js isn't an alternative to React. A dev using it just won't be as capable as a dev using React, because the surrounding tooling isn't there. React isn't just the code that gets bundled in. It's everything else as well. Libraries that claim to be smaller and faster but that lack that quality of dev experience should really concentrate on improving that rather than shaving another 1ms or 0.1KB off the load time.
Do you have time to rewrite things from scratch like react-testing-library, styled-components, Apollo GraphQL, DraftJS, react-hook-form, and various component libraries? If you want to actually focus on your business logic you don't have time to do this stuff, otherwise you'll spend two weeks making a dropdown.
EDIT: It's also just kind of off-topic and representative of stereotypical HN cynicism.
Also "using something in professional manner" itself is a huge assumption -- are we going to forget that people do front-end development in non-corporate or professional settings?
Calling a minimal view library a "React alternative" may be borderline offensive to professional React developers, but it's also actually helpful to people who are looking for an alternative when React doesn't fit their use-case.
It's similar to how people build "wordpress alternatives" that are just a blog with zero plugin capability and then wonder how their better product isn't getting traction. Sure, technically, wordpress is just a blog; but that is not why people choose it. (And I have no love for it)
I don't think that's the tone I was aiming for. My point is really that for Espresso, or any other library that's aiming to be an alternative to another big and popular library, needs to do more than just being technically better. It needs good examples, clear docs, support from the community, and ultimately a well thought out "ethos". Espresso is lacking a few of those things. That's not even really a criticism of the library; it's just the state of library development and populism in the JS ecosystem in general. A large part of a devs decision making process comes down to things that aren't code.
It's a bit like the "build it, they will come" route to market that kills so many startups. Just making something great isn't enough. You also need to handhold your users to get them to try it.
> What most JS developers should really care about is the ecosystem, the tooling, the documentation, the code quality, and the testability of their chosen framework
This isn't just OP's opinion. OP is lite gatekeeping by suggesting that most JS developers should share their opinion. I will agree that testability is paramount, but lacking specific contexts (embedded, high-perf, security, etc) the rest of the heuristic deals with a series of trade-offs.
OP has possibly worked in a limited context when writing front-end code, and has not been forced to make trade-offs. The most glaring issue with their argument is that developers should stick with libraries that have large ecosystems and tooling. This is an anti-progress, anti-innovation sentiment which does not even hold up. Like another poster said, there was no reason to ever drop jQuery and move to view libraries if ecosystem and tooling were paramount.
At what point is the argument for one toolchain over another simply circular reasoning / backpatting? Trade-off analysis isn't just pointing at X, it's about looking at the balance of X and Y vs W and Z.
The advice that I’ve seen is that you should replace jQuery selector stuff with vanilla js and css whenever possible, and for a lot of projects that doesn't leave much.
I wish everyday that this was true. It's far from it, unfortunately.
Also, I like hooks.
IMHO X is an alternative to React if you can build a web app with X.
Sometimes less is more. Some people prefer vanilla JS or a lightweight library to a huge framework with an "ecosystem" of baggage.
Vanilla JavaScript/jQuery projects probably start off small/without bad intentions. It's what happens to them overtime as they grow (fall apart) in my opinion.
- Clear separation between HTML markup and code, the DOM is static and is not generated by createElement(..)
- No virtual DOM or HTML diffing: every component has an internal state and updates the corresponding DOM attributes as needed
TO DO example: https://github.com/akrymski/espresso.js/tree/master/examples...