Jay Taylor's notes

back to listing index

Why React/Redux is inferior as a paradigm | Hacker News

[web search]
Original source (news.ycombinator.com)
Tags: react news.ycombinator.com
Clipped on: 2017-08-12

Image (Asset 1/2) alt=
Image (Asset 2/2) alt=
To be honest, this whole thing just seems like a vague rant. It's full of hand-wavy statements like 'Once you learn Elm or Cycle, getting things done will be more productive' with only vague anecdotes to back them up, with no specific examples of worked problems.

The section on JSX & the React.createElement API is a weird diversion, because these aspects are so unrelated to the high level code structure complaints that they belong in a different article. Putting that aside, this section seems unfair at best. Firstly the JSX syntax is disregarded due to verbosity[0]. Okay, not to everyone's taste. However the author then goes on to making a comparison between React's createElement/createFactory APIs and the hyperscript-helpers npm package, which is incredibly uncharitable as the former is a performant, low level API intended for building ergonomic APIs on top of, and the latter is a high level, ergonomics-centric API.

Redux is a small library, which needs to be used underneath application-specific abstractions to avoid boilerplate. Not everyone will want to come up with such abstractions themselves. I can certainly see the value for an ergonomic, high-level, Rails-like project on top of React + Redux. Maybe that's the article the author should have written.

[0] I would argue many developers actually find the verbosity of JSX helpful when dealing with large trees of components, as compared to nested function calls. The fact that JSX closing tags repeat the tag name is key to this.

Agreed, opting not to use JSX and then complaining about a lack of ergonomics seems pretty contrived. Yeah, the raw function calls aren't particularly friendly, that's why JSX exists. If more people opted not to use JSX, I'm sure there would be better options for friendly createElement/createFactory.

He also doesn't mention the learning curve, and I'd argue that function calls for DOM is less beginner friendly. It's pretty easy to mentally map a render function to its output because they're so syntactically similar.

Not sure how much relevant it is, but author's stance on JSX reminds me of a meme known as "Baton Roue" which depicts person throwing a stick into the wheel of the bicycle he's riding. In other words - sure you don't have to use JSX, but if you really decided to work with React you are highly advised to go with JSX because that's what makes work with it much easier: you get familiar syntax which is easily parseable when somebody else is reading a code. However, if you decided against JSX then you're doing yourself a disservice, because sticking to raw JS does not improve development process at all, probably even opposite.

Furthermore, in the situations where I cannot use JSX, I actually like the explicit nature of how you need to specify properties.

In fact, as a general comment, the article actually solidifies my choice of using React precisely because it's 'verbose' in the right way: it makes working with something (inherently?) messy explicit, and as a result much easier and pleasant.

As I learned how to work with React I've had quite a few moments where I got frustrated trying to get something done, only to realize that I was doing it wrong and that React was 'coaxing' me into doing things right. Very often, without trying, I'd do things in a way that suddenly made things 'click', where in the past my solution would've turned out messy, and where in the future even using other libraries/frameworks and applying what I learned will lead to a better result. I really think the 'pit of success' idea applies (which was mentioned in the initial video presenting React).

> However the author then goes on to making a comparison between React's createElement/createFactory APIs and the hyperscript-helpers npm package, which is incredibly uncharitable

It's more than uncharitable; it's nonsensical. There is quite good hyperscript support for React. If hyperscript is so great that being able to use it with Cycle is a plus for Cycle, then logically it's also a plus for React.

It does feel vague, I'd love to see examples of how the paradigm helps you 'focus on features'. The examples given in the blog seem mostly about syntax/verbosity in nature which is not as interesting as evolving clarity of thought and mental overhead.

I haven't explored Cycle.js or Elm, but a few comments on the React/Redux side as I've recently adopted it at work and have found it to be a huge pleasure to work with. There does tend to be a lot of syntactic boilerplate/wiring up of things in Redux which is definitely a bit of a drag, but the most important thing that Redux has done for me is make data flow very clear and easy to trace and understand. Even with Facebook's impls of Flux, and Backbone before that, data flow was very tricky and cloudy at best.

As for the criticism that setup has a lot of moving pieces, I sort of agree, but I found myself up and running in a few hours after reading the (incredibly well written) documentation and within a few days I was already more productive than I was previously without Redux.

Elm also gets out your way by having immutable types built-in, signals built-in, “dispatcher” (Mailbox) built-in, and ADTs for action types built-in. The experience is great for a developer and the initial setup is quicker.

Built-ins are a tradeoff just like anything else. Redux gives you enough to get going, and has a strong ecosystem and community of libs that most people will use (react-redux, thunk middleware). Built-ins might help you get started faster, but maybe that doesn't fly for a company of 100 engineers where use cases vary and customization is important.

Lastly, the author claims Cycle.js lets you 'focus on features'. From past experience, this makes it sound like there's just a lot of magic and it's easy to get lost in it all (see Rails). This may or may not be the case with Cycle.js, but that is immediately my gut reaction. I feel Redux gives a pretty powerful philosophy and clear way to handle front-end apps that can scale well to larger apps. If there are some things Cycle.js is doing well over Redux, I want to hear more about those! The arguments against Redux without that context feel pretty weak.

in keeping with the spirit of extracting sense and meaning where it may be implied rather than enumerated, I grokked: 1) noise is bad. 2) web fashions come and go 3) the trendy is not always right.

i happen to agree with these points in many regards, so perhaps I'm a poor reader and merely projecting...

but yeah, I'm pretty over the militant "a react in every stack" approach... ditto every other myopic temporary obsession... you realize this after a couple hegelian cycles of thesis, antithesis, synthesis... i mean, when yesterdays baby becomes todays bathwater and it's time to throw it all out, or perhaps consider renaming "common sense" that rare balanced mix of functional object-oriented reactive structured aspect oriented programming as a service platform...in the cloud

I don't think it's as much "a React in every stack" as "observables solve a lot of problems that couldn't previously be solved with promises."

Handling async events can be difficult and error probe. Observables finally provide a useful pattern to that can be used to effectively manage async operations on data.

React os the poster child because it came first but Angular2 also uses Rxjs (ie Reactive Extensions for JS).

The poster goes to the opposite extreme, "if we're doing functional programming in JS, everything should be functional. Here's what I use, everybody who doesn't also use it is dumb."

Subjective opinion addressed as fact.

>To be honest, this whole thing just seems like a vague rant. It's full of hand-wavy statements like 'Once you learn Elm or Cycle, getting things done will be more productive' with only vague anecdotes to back them up, with no specific examples of worked problems.

Perhaps missed the whole second part of the article, which gives several concrete examples and concerns.

Newsflash: Guy who created Cycle.js because he didn't like React thinks Cycle.js is better than React. (He also thinks Elm is better than Redux, but I think he's significantly overstating the differences between Elm and Redux's patterns, and significantly understating some of the drawback's inherent in the Elm language, as opposed to the Elm patterns. Developers I know who have used Elm for production projects seem to have very mixed feelings about it, and many have since abandoned it for Purescript.)

He's probably right about Cycle though, for some devs, on some projects. Then again, I've spoken to people who went all in on Cycle and got burned, and found it inferior to React. A guide to when you might prefer Cycle to Redux would be interesting, but this isn't it.

(And as others have noted, his comments about JSX versus hyperscript is quite odd. React is not tied to JSX, and you can easily use hyperscript with React if you choose. It's just that people don't, because most people don't find hyperscript as awesome as he does. Which is sort of the article in a nutshell; "X is better than Y because I like X!")

Can you share why and how these Cycle.js users were burned by the framework? I've been considering it for a project and would love to hear about how it's gone wrong for others.

Unfortunately, I can't; it was some idle chatter after a meetup, and I may have had a couple of drinks at the time. :)

From memory, it was based around the way the redux patterns is very top down with a single state atom, smart reducers, and dumb components, but the cycle pattern is very bottom up with smart components and no centralization. So as your app gets complicated with cycle, you can start to lose track of all the different streams and start to struggle with figuring out what your app is doing in total.

Mind you, they may have just been doing cycle wrong, and you have to take people complaining about their tools with a grain of salt. But the impression I got is that cycle is not a magic bullet that makes large, complicated apps with difficult state management problems easy to code, any more than redux is. Cycle is great when you start looking at redux and go "oh shit, I do NOT want to start coding these reducers, can I just break it down into tiny parts and solve each one on its own", but redux is great when you start looking at cycle and go "oh man, I do NOT want to try and figure out how all these bits work together, can I just put all this crazy logic in one place?"

(Disclaimer: Have never used cycle; just talked to some people who have.)

I really liked the guide for 'x versus y' that Vue.js provided. It was fair, honest, and actually resulted in me choosing React.js for a particular project while simultaneously leaving Vue.js on my radar for other projects.

(I vaguely recall Ractive.js doing something similar, which led me to make the opposite choice and use that instead of React.)

The jsx part is a bit of saying "X is better than Y because I like X!" but I see the rest of the article as more about why he thinks React+Redux are harder to use. A lot of it has to do with the number of things to learn and functional instead of OO. The last part is a belief held by many developers.

I haven't tried Elm or Cycle in production but think our code would be much easier to work with if it were written in any of those that it is today with React. There might be other problems like stability and some special features we might miss or the learning period might be much longerthan I think but overall both alternatives looks better to me.

> I haven't tried Elm or Cycle in production but think our code would be much easier to work with if it were

This is yet one more article that makes me want to try Elm. It has been mentioned more and more often here, but I don't know if its actual usage has grown as much.

Cycle.js has the most elegant and powerful component composition mechanism of any JS framework I've ever used. With React you have to be extremely careful in how you design components to make them re-useable and flexible.

The inversion of control that happens with Cycle.js makes it really easy to compose components together. At first it feels weird to not manually specify event handlers (e.g. onClick) in DOM-generation code, but as a result there's much less embedded opinion on how the component be should be used. Instead each component simply returns a collection of queryable observables, which is extremely flexible and adaptable.

It's also cool how components have the exact same function signature as a full Cycle.js app, so you can think of your app as being composed of several mini-apps. It's very clear Cycle.js was designed with composability in mind from the start.

I really would like to see an article about this, can you point me in the right direction. Natural component composition(nesting) where "component" includes markup, state and events, and how cyclejs makes this better. This is the article Andre should have written btw, i think vanilla react doesn't handle this all that well and redux makes the composition story worse (composition is a non-goal of redux though) - but it is very much still a research problem

Take a look at domvm [1], disclaimer: mine. It was written expressly to allow for imperative AND declarative sub-view composition using a concise, js syntax. I used Mithril for a while before needing granular redraw and concluding that MVC wasn't the way to go.

~8k min. No build tools, no dependencies. Extremely fast [2], composable, isomporphic. JSONML [3] superset template syntax. it's plain js all the way down.

[1] https://github.com/leeoniya/domvm

[2] http://leeoniya.github.io/domvm/test/bench/dbmonster/

[3] http://www.jsonml.org/

I dont think this is the type of composition I am talking about. This composes pure views, like react, but it doesn't compose their state, same as react.

Check out the Cycle docs: http://cycle.js.org/getting-started.html

It's easy to use Redux in a composable way once you start removing imperative code in components and just make them describe what happened.

Redux-saga can glue this all together. See http://stackoverflow.com/a/34584313/82609

Thanks. I have redux-saga starred on Github but haven't looked into it at all.

I've had no trouble making components re-usable and flexible; if all externally visible parameters are passed in as props, there are no problems.

This is but one of many reasons why having all externally visible parameters be props is a good idea in React, so you should probably do it whether or not you want your components to be reusable.

Everyone has their preferences but personally I have never used a framework that got everything perfect. I'm not surprised that the author thinks cycle is superior since he wrote the library. In other news the forecast calls for more JS frameworks today with a high chance of more JS frameworks later this week continuing with intermittent churn for the rest of the JS season.

As someone who is mostly a spectator lagging months behind the JS framework du jour, it would be helpful if these discussions were a little less personal and a little more objective, even if cooperation isn't in the cards. I really don't have the time or patience to sort through all the WWE-style back and forth, and it is really painful to make a new project using every new thing just to see if it is any good.

For me the solution has been to pick a relatively popular library, work around the quirks, then just DONT UPGRADE the package. EVER. (Unless there is some real benefit to the end user or a security issue or something)

As a solo developer trying to bootstrap a startup I started out 8 months ago with React, I have had a reasonably good experience with React itself. For a pre 1.0 project it's surprisingly stable and once you figure out what you're doing I've been able to move relatively quickly.

The big holdup has been the supporting libraries. Some have been an absolute mess but the solution to that is that once I got it working, just don't touch it and don't buy into the promises that it's always going to be the next version that solves the issues. I didn't opt for Redux and went with Fluxxor instead which has worked reasonably well but I kept getting errors and ended up forking it to fix the problem. I'm not going to go back and use Redux for everything because someone told me it's better.

I am now on my 3rd build tool over this timeline. I am now on Webpack because people kept promising that the next one would be better. I struggled to finally get React-Hotloader to work and occasionally it works but most of the time I just get Invariant Violation errors and have to do a full reload. I had to jump through hoops to get this to work and enable CORS etc for virtually no benefit. It will almost certainly be my last build tool for a while.

The pattern with JS from my viewpoint has been to overhaul entire libraries because it's not quite right. It seems that what these developers don't realize is that when you solve one problem you often introduce another. Once you have a working solution there isn't really much incentive to change things. This guy laments that there is not a good way to do pure JS instead of JSX but you know what? JSX is fine. I already need a build tool to use ES6, and as long as you are consistent you shouldn't run into too many issues using the pure JS solution that comes with React if that's what you really want to do. JSX might be ugly but I would rather just deal with the ugliness and settle for good enough then keep creating extra work for myself in search of perfect.

My goal is to build an app. I don't have the time or inclination to try out libraries like cycle or elm every time someone brags about how perfect they are just because they might provide me with a little benefit in terms of ease of development. I am perfectly fine with sitting back and reaping the benefit of other peoples' WWE-style back and forth even if I have to wait a year or more for things to stabilize.

I've never used it, but I am surprised you haven't looked into Ember. It's a bigger cognitive load and might not be a good fit for small projects, but I feel like this recent blog post[1] was made for you.

[1] https://medium.com/@jonpitch/ember-get-shit-done-36383c2ccc5...

I hate to break it to you but WebPack is also riding the peak of a hype cycle right now.

It doesn't natively support the future ES6-module standard.

Once browsers start providing native module loading support, devs will likely migrate en masse to JSPM. JSPM is the (previously missing) package manager for front-end libraries. It supports transpiling (babel, traceur, typescript) out of the box and also handles bundling.

WebPack 2.0 does support ES6 module import statements. In fact, it does tree shaking now too, but only if you use import {x} from foo.

Oh, cool. I didn't realize webpack 2 was released with ES6 module support.

Import {x} from 'foo'

Looks like it's going to be the spec for ES6 modules anyway so it's probably a good thing that you have to it for tree shaking.

>I struggled to finally get React-Hotloader to work and occasionally it works but most of the time I just get Invariant Violation errors and have to do a full reload.

Have you considered reporting a bug?

I don't know that there's a way for them to be "objective". Like n0us said, no framework's perfect, and anybody who chooses something or builds something is going to tell you the thing they chose or built is the best, or at least better; if they didn't think that, they'd be using a different option. I've used React and Angular. They're both fine. They're just ways of doing the job. You can build stuff in them. The whole "pick a side and engage in a holy war" style of debate in programming is ridiculous, but it gets the clicks and pays the bills.

Although the author is biased, he is presenting valid criticism for fundamental flaws that truly make React inferior from a structural standpoint.

Additionally, he presents the framework/language Elm, a library he is not really involved in, as a superior alternative.

I agree that some points are actually valid (conceptually). However React permits to do useful compromises on purity for practicity.

In Elm you have to hack the system to give the focus to a single input or use an external lib... See https://github.com/evancz/elm-architecture-tutorial/issues/4...

The author even anticipated your parent comment's argument and used Elm for this very reason. He seems to make it reasonably clear where Elm's approach is different from that of Cycle.js and still both are preferable to React/Reduct.

Immutability, stateless function (or referential transparency), the ability to reason about state, the edge it gives to concurrency etc these are all valid, and objective arguments. It might not be the end of the discussion but at some point the churn is going to settle down and let a framework/lib/language mature in a rich and reliable ecosystem. I think the churn and js fatigue is a reason to have more of those conversation rather than less because we want to get there faster not later....

Having worked on a small/medium React application after stepping back once the work was complete it began to dawn on me that React wasn't the holy grail of web development. The number of packages needed in order to glue parts together, the managing of state at times is just confusing and on boarding new team members can be painful. Not to mention the constant battle with updating packages and API churn of these packages. But what React does have is an incredible community and a very large backing (Facebook). There is also some very intelligent people working on React (https://twitter.com/dan_abramov, https://twitter.com/schrockn, https://twitter.com/soprano to name a few)

The idea of Elm (http://elm-lang.org/) excites me greatly but then again what's to say that Elm will be dead in a years time? My question, is there a framework out there that mixes the better parts of React (virtual dom, large community), the idea of functional programming and a server side aspect to build the back end in one package?

If you're doing Scala/Play development, then I kinda feel like you should just use Scala.js. So you get a familiar language, providing the same sort of benefits as Elm, that almost definitely will be around for years to come. There are concerns with the size of the generated code, but on balance it doesn't appear significantly worse than most of the JS frameworks available.

I realize that's a suggestion that will only apply to a relatively small niche in comparison to many of the frameworks discussed, but since I'm a part of that niche... :)

But yeah, you probably should be using something better than ES5. So is it Typescript? Elm? Clojurescript? etc? I think Elm is out. And while the others are probably good, long-term solutions, why learn a new language if you can get more or less the same feature set with something that already integrates with your build-tool/stack? Seems like a no-brainer to me.

And then once you have that, do you really want a client-side "framework"? For some problems maybe... but I feel like if you solve the basic problem of language, that question becomes a lot less relevant.

Just seemed like an appropriate place to vent my own thoughts on the subject lately. I get there are plenty of people that don't care for or aren't excited about Scala for one reason or another, so I'm not attempting to persuade anyone it's the right choice for them.

Bear in mind I am asking this question as someone who has no experience in Scala/Play but is looking to learn some new languages/frameworks:

How do the Play framework and Scala.js work with each other? Can I easily write an application is Scala and then sprinkle Scala.js around to perform AJAX data fetching for example?

For someone who knows Scala the tutorial at http://www.scala-js.org/tutorial/basic/ seems pretty thorough.

But the short answer is yes.

There's also this: https://github.com/vmunier/play-with-scalajs-example

And then if you want something interactive but with low commitment, you can give the examples in Typesafe Activator a spin:

  $ brew install typesafe-activator
  $ activator ui
That'll open a browser window. Form there you can open tutorials, step through them while a code panel gets highlighted as you go, edit code in-browser, execute tests and run. All from a single app running in your browser with a 30 second install. It's gotta be the lowest friction intro/development environment ever conceived. Highly recommended if you've never seen it.

Who uses scala.js? I was not under the impression that it was "ready".

It's definitely ready! I can't speak to who's currently using it, but it's got a very impressive ecosystem around it, from when I looked into it months ago.

Let's talk about building an app with 50 independant ScalaJs modules then and how you manage/compose them in one or many of your apps without embedding multiple times the ScalaJs runtime.

Don't forget Scala is slow to compile and ScalaJs is even slower so if you have a monolithic js app it won't scale as a good developer experience.

I'm a backend Scala developer and I'd rather use Elm than ScalaJs until it's clear how to scale ScalaJs apps.

> how you manage/compose them in one or many of your apps without embedding multiple times the ScalaJs runtime

That doesn't make sense. You have code, maybe also dependencies. Scala.js compiles it and produces one JavaScript file with a single runtime and only the bits and pieces of your code and your dependencies that were actually used.

> Don't forget Scala is slow to compile and ScalaJs is even slower so if you have a monolithic js app it won't scale as a good developer experience.

ScalaJS incremental compilation is so fast that it's already done when you switch from the IDE to the browser.

The number of packages needed in order to glue parts together and the managing of state at times is just confusing.

Sounds like there's an opportunity to package a lot of those things together into a single Rails-like "opinionated" package.

Actually a few weeks ago there was a big movement in the React community about that. The problem is that the JS community is too big and people use different build systems and tests frameworks, let alone coding styles or project/files layout.

I think only Ember has been able to have a strong set of conventions, mostly thanks to ember-cli[1]. I consider it the Rails of JS.

That said, I am looking into nwb[2]. Looks fine for personal projects.

[1] http://ember-cli.com

[2] https://github.com/insin/nwb

let alone coding styles or project/files layout

Agreed, the lack of project structure is in my opinion the biggest issues when building React apps. An interesting discussion on project structure can be found here: https://github.com/mxstbr/react-boilerplate/issues/27

Yeah I think it's one of the least talked about conventions, and unfortunately there's a lot of debate because of how React is (CSS next to component or in its own place?, etc).

Coding styles is a solved problem. Use the feross/Standard tool or SemiStandard equivalent (ie if you prefer semicolons).

Structure arguments will continue until the past decade of brain damage caused by trying to shoehorn MVC into front-end frameworks wears off.

The future is self-contained, reusable web components. Organize the structure by feature. Provide a root file that acts as an exports facade that maps the internals to an easy-to-understand public API.

Correction: I'm not implying that separating of concerns is bad.

I'm saying that arbitrarily separating them into folders by-type at the base level is not a useful pattern when it comes to reusability.


It's not perfect, it feels a bit big sometimes, but everything I need something to build a feature quickly it's there in the framework or the build tool, and that's good enough for me.

I'm currently trying to train a new developer and slowly introduce him to the world of React/Redux and only now am I realizing how incredibly complicated it is.

I enjoyed learning them and am efficient using them but now I'm not so certain that it's the best choice for a team with developers of different skill level and experience. Once you throw in React-Router even my days in Angular 1.x seemed simpler.

Well, that's sort of the difference between composing libraries to build applications and using a framework like Angular. Angular abstracts away a lot of things. This is good and bad. It's easier to get into Angular and get started sooner. But ask an Angular dev to explain the digest cycle to you, or transclusion or when and why to do one-way or two-way binding, and the relative merits of calling $parent or using controllerAs syntax. It's a really confusing mess. And folks use it without understanding how it works.

With react, I can explain, quite simply, that it's simply a function: (state, props) => HTML . That is elegant as fuck. There no dirty checking, no two way binding or unintended side effects by cross-referenced observables.

React-Router is only necessary if you want to build a SPA. Then you learn how it works, or you use some other router (like Redux-Router). It's great. You actually understand how your code works.

It's a steeper learning curve up front, but you learn and you become a better developer as a result.

I could explain how Angular2 works in great detail. It mimics the hell out of OOP.

The component tree is a directed acyclic graph of single-inheritance relationships. Services are singletons that can be injected into any component to share state. Dirty checking follows the tree (ie the DAG) of inputs/outputs specified in the component metadata so there's at most O(log n) comparisons per update. To make dirty checking efficient favor immutability because it's quicker to superficially compare references than it is to deep check an entire data structure.

Anything that's inherently asynchronous is handled via Rxjs observables using either a one-to-one or one-to-many publisher/subscriber model.

As for Angularjs. Who the hell knows? Dirty checking, crawls the graph of relationships until the dirty checker gets tired. Services are kind of like singletons, I think. Factories try to mimic the borg/prototype pattern (because, reasons...) to provide singletons that share a reference to a common closure. Who the hell knows what providers do, maybe provide an instance that acts like a static helper class? Directives are magic, really complicated and painful to use magic that preprocess the HTML, who the hell knows when.

I concur. Friend has been learning React and from time to time asks about various things. Those questions made me realize that for the newcomers, especially people who are not well versed in JS, React could be incredibly challenging to learn.

That said, I imagine cycle.js would be even more complex to learn - with this recent race to "FPR all the things!".

Same experience I made. On the other hand I always think that making equally complex web apps with other popular frameworks is more difficult. At least if high performance and sustainable maintainability should be there.

Therefore for me the most important metrics for a web framework are popularity and ability to deal with complexity. Hoping though that I get enlightened by another framework one day...

I quite like what Angular 2 does with some of the ideas - Dependency Injection, number of solid modules such as Http and use of RxJS where it actually makes sense without forcing functional approach everywhere in general. However I wish they'd just go with JSX-kind of DOM generation instead of that horrendous combination of ng-ness and HTML.

This is so common among developers. We forget how the complexity happened bit by bit. But when we explain it to a newbie, it all comes back.

Want to re-evaluate your whole base of knowledge? Teach programming to adults who have never written a line of code before. Wow, the things I thought I really understood. :D

This is very interesting for me. I introduced React (and companions, like redux, react-router, CSS Modules, etc) to a team of 8 who had never used any of this before and they all loved it and picked it surprisingly easily.

We can't maintain something simple for a long time. Maybe that's human nature (or developers nature ), but the success of a framework is the start of its demise. Excited contributors will try to "improve" it and that always ends up adding complexity to what was a simple and elegant solution.

Maybe the problem originates in the tendency to rate open source projects using metrics like number of commits. A simple and elegant project that does not have recent activity is labeled as dead and people stop using it, even if it works well.

I think the problem originates in people using the system to solve their actual problems. Most problems aren't simple, and therefore demand non-simple answers. (Tangent: this is also why todo list examples for frameworks are so damn silly.)

Maybe part of the "JavaScript fatigue" is that, as each shiny new toy rolls in, the ensuing commentary immediately elevates it to The One Solution We've All Been Waiting For --- followed just as quickly by No This Is The Most Flawed Solution Ever They Got It All Wrong And Here's Why....

The reality is that many species can coexist in the same habitat. You don't have to pick just one. Cats don't have pincers, but does that have to mean lobsters are superior? Nope.

It's funny how we identify with our tools and some consider them even more important than the actual products being built. Maybe it's a manifestation of the "The grass is always greener on the other side of the fence" that makes teams jump from a solid and time tested toolchain to a new "cool" framework. The problem with this frequent loop is that a lot of time is wasted learning conventions/syntax/tooling and the lifetime of that knowledge is small.

I'm still using Knockout.js for everything, it's supported, fast (3.4 made it a lot faster), has the good stuff (components etc), plays well with others and excellent (superb by JS standards) backwards compatibility.

I just don't see an incentive to move yet, I didn't last year and the way things are going I might not for another year.

I have limited React experience and none with Cycle, but I am not surprised to find that a framework that solves the problems a particular developer wanted solved works better than other frameworks for solving those problems. The real test is in scenarios that were not foreseen.

This is generic, of course, and the article gives no real view of the capabilities of cycle as its own thing, but I feel sufficiently experienced to be skeptical of claims of blanket inferiority.

A little bit of a meta-comment, but I find this article very hard to read. There's no clear delineation between different arguments / sections of the article, meaning I can't skip to find a piece of content I might be the most interested in. Additionally, the hyper-thin content section gives the illusion of a wall-of-text. My eyes have to jump lines every few words, causing an interruption of sentence flow and structure. It's very distracting, and the presentation (especially considering the technically-heavy content) hurts the message.

Keep in mind that english is not the author's native language.

I'm not a native english speaker, but I felt the same. You would expect misuse of expressions or some sentences being strangely constructed / difficult to understand, but overall the structure of the article should be more or less clear.

No excuse, formatting is not language dependent.

I'd like for the observable community to finally settle on a minimal common interface (like Promises/A+ and later ES6 promises did) for observables. Maybe https://github.com/zenparsing/es-observable

Then maybe cycle.js could come with a more minimal implementation rather than having to bring in a library with a gigantic footprint and 100+ operators (https://github.com/Reactive-Extensions/RxJS/blob/master/doc/...)

Awesome, most.js was exactly what I was hoping for! Still, it would be best if all those operators were a separate library dependant on a single common interface (using ES7 bind operator for nice chainability maybe?)

That's how RxJS 5 is set up, fwiw.

Oh, cool. I think I'm finally sold on RxJS then. My only remaining beef with cycle.js is that components behave so differently from DOM nodes (which are not treated the same way as components), but I guess I can still give it a try.

I tried to use React.js but it felt like Java Swing all over again. While controlling state and triggering render when it changes seems like a novel idea quickly blows up in complexity.

I find it odd that after 5 years developing multiple products with npm, node.js, meteor.js, flask + uwsgi, angularjs & react that now I'm back to just using Laravel + jQuery to build my single page application with REST api. It's easier and cheaper to find skilled php developers and learning jQuery is not a problem.

It's the 2006 formula but it works so fucking well and so much easier. Scaling is going to take work regardless even on AWS so now I prefer reduced technical debt and maturity of tested and true technologies.

I know this will get me crucified by mid 20 something hackathon hackers but this is just based on my own experience rather than blog articles. Something I learned very painfully through neophilism rampant in the industry.

You are probably doing it wrong.


Can you give some details about how things blow up in complexity? I've not built a complex app in React yet, so I'm looking for things to watch out for.

sure it starts with decoupling data describing the application state from DOM itself the way I understand it. So you write JSX which is a novel idea in itself and claims to 'bring html to js not like angularjs that brings js to html with annotations' but then you end up fiddling, chasing down which hierarchy of class that gets quite big over time.

Unless you were in a large design agency it doesn't make sense to add the abstraction overhead for majority of today's single page apps can be pulled off with jquery libraries from unheap.com

In a typical jQuery/Backbone kind of app, you've got some data in something like Backbone models and you've got state stored in the DOM. Keeping those two in sync bring complexity in. The React model is simpler (in the non-intertwined sense... see Simple Made Easy[1]) in that you have data in one place, a function that transforms the data to UI and the browser DOM is managed automatically from that.

It's not perfect but it reduces complexity.

[1]: http://www.infoq.com/presentations/Simple-Made-Easy

> Components that expect “onlyChild”

> Some React components have an invariant: “Invariant Violation: onlyChild must be passed a children with exactly one child”. Which means this is an error:

I'm surprise the author called this out as a negative of React while saying the compile time type safety is a positive of Elm.

If I have something that expects one child, I expect one child, not an array that has 1 element.

Agreed, the benefits of type safety are often thrown around but this is sort of what type safety looks like. Yes, as the author says it makes things "annoying to develop". This is because the developer now has to read the docs and be aware of this invariant for the particular component they're using. They'll go, "Damn, guess I can't use a list here," and fix their code.

However, let's say later down the line a new engineer comes in and is tasked with a bug fix. If they're using Cycle.js and see an array, they might think, "Oh, I can easily solve this by adding another element to this one-element array." Without any invariants they'll run into subtler bugs and errors trying to figure out what went wrong.

But with the invariant, if they tried to jam an array there they would immediately get an error and know what's wrong.

This isn't something that will crop up in a simple one-day project like the author was creating with his coworker. It's instead a great example of how a little annoyance can make future maintainability way easier.

I disagree about the jsx, but I do agree about Redux. React is beautiful in its simplicity, but Redux kind of throws all that out the window and adds all the missing complexity back in. Granted, part of that is due to the relatively simple nature of React, but I do think there has to be (and likely eventually will be [I see your eye-rolling]) a better, more enjoyable way to handle state management.

I think this is more of a documentation issue. Redux itself is simple, it's just the barrage of functions you need to use to get anything going that get in the way IMHO. A little layer on top would make it pretty nice in that sense.

Redux effects and friends are simple too but suffer the same issue, they're so functional that they can be hard to reason about. You really need higher level abstractions to hide that stuff or it gets unwieldy fast.

I think it's the typical 80/20 – hard things are easy with React/Redux, easy things are sometimes hard.

I found it to be quite like the other way around. I thought React is a quite decent view library (with medium complexity, if you try to understand and use all the lifecycle methods and think about suitable keys for reconciliation), but I found Redux a bit too primitive for my taste and decided against using it. Reasons where that I don't think storing all state in a single object is a good design idea and that state for me is not only about serializable objects (e.g. I often need to keep promises and other stuff around). I understand that it enables some things like hot reloading and time travel debugging, but thats not the highest priority on my nice-to-have list.

After experimenting with React I'm now using angular2 for my project and apart from some bugs that are left I'm quite happy with it. Architecture-wise I put all state (serializable or not) in multiple-independent plain JS service objects which are injected into the view components through ng2 dependency injection. And they expose their state through observables, which together with things like async pipes makes reactivity really easy.

I might be misunderstanding you, but if you mean handling state at run-time, I feel like handling it in multiple places would be more complex, no? Otherwise, you can actually define state handlers (or as redux calls it, reducers) in multiple files as well, so that each subsection of state is being handled independently.


NG2 services are essentially just singletons that can be injected into any component.

You can specify a server as an application wide provider (ie attach during bootstrap) or a component-specific provider.

Once a service is injected into a component all you have to do is set subscribe a variable to the service's observable. It the variable is bound to the view, it should update automatically. Event handling can be setup to update the observable by calling .next().

NG2 uses Rxjs (Reactive Extensions for JS) which is just the observable structures plus a ton of functional extensions (ie equivalent to reducers) that can add all sorts of inline transforms. Ex flatMap, filter, debounce, etc.

The Rxjs observable API is almost identical to promises. Except you call .subscribe() instead of .then() and the subscription can be disposed of at any time (ie promises always run to completion).

Rxjs uses hot and cold observables. For cold, subscriptions each have their own independent state and disposing of the subscription will stop the observer from retrieving further updates. Hot observables publish updates to all observers and keep updating even when there are no subscribers. Basically, cold observables are like 'on demand' viewing whereas hot is like watching a 'live stream'.

Not sure if you've looked at Cycle Drivers, they are essentially services or plugins for side-effects. You manage them through sources and sinks and utilize them where every you like, as they run through dataflow components, very powerful and clean.

See http://cycle.js.org/drivers.html

How do you find Redux complex? I found I got the gist of Redux in a few minutes, and was very productive with it a couple hours. I find it much simpler than flux. What do you not like about it?

Glancing at the documentation, it seems to be essentially an implementation of the Memento Pattern, as described in the Gang of Four's book. I have to agree, it's fairly straightforward.

I have not used flux. It's not difficult to understand Redux, but the setup is not simple. Defining the constants, defining the actions, then defining the reducers. It's a lot of moving parts. Throw in the connection to react via react-redux, and it feels like you've had to repeat yourself in several places, not exactly, but enough to be annoying.

I actually find it to be the opposite. Developing with Redux, you can actually throw away most of React's API. In my app, React basically acts like a functionally pure rendering layer.

It definitely has a learning curve, but the very simple data flow makes it pretty straightforward, once you've learned what each layer does.

That's definitely the Redux dream I'm trying to achieve, but as I mentioned in a comment elsewhere, it feels like there is a lot of initial setup. And with each new container, the setup process just starts over. I haven't craved TypeScript in awhile, but for whatever reason, Redux has rekindled the desire (and I know it can be done, I just haven't gotten around to it).

Likely because the stateful portion of any system is going the be the complex part.

I've enjoyed React immensely, so I expected to dislike this article, but there are a lot of good points in there.

This part confused me: > I can confirm React/Redux is an inferior paradigm...

But all the examples don't show a "different paradigm", let alone a superior one. To me, they show the same paradigm, done better? The conclusion seems to support that interpretation as well.

The bulk of his argument seemed to focus on how he really prefers hyperscript to JSX, which is fair enough I guess...but no, really not a "different paradigm".

Especially since he talks a lot about how much he loves Elm, and Redux went out of their way to copy Elm. The Elm/Redux distinction is basically syntax.

What's wrong with vanilla React/Flux? I'm currently working on a greenfield project and I've more or less settled settled on that stack. I have immense respect for Abramov but I'm finding it hard to justify Redux when Flux works well.

vanilla flux has WAAAAAAAAAAAAAAAAAY more boilerplate than redux

I'd gladly trade more boilerplate for stability and confidence of non-breaking updates. You can also write higher-order components to DRY things up.

It's not the boilerplate that get's me. It's just easier to reason about the state using Redux (imho). The idea of 1 single global state which mutates and pushes down (instead of managing observables all over), makes it easier to see when/where something changes. The idea isn't new (check react-cursor for example).

That said, there's nothing wrong with vanilla flux. Just that I find redux much easier to understand and follow.

Also that!

Redux is literally ~100 lines of code (you can check out Dan Abramov's Egghead.io series about it in which he basically rebuilds Redux).

I'm among the many people who previously used vanilla flux and prefer what the Redux style brings to it.

I haven't really found redux to be all that unstable, though.

Redux has good tools. You can restore your state after hot-reloading your changed JavaScript code. You can do time-traveling to restore your app state in any point of time (using new code) but old state. IMO that's an incredible improvement for development.

And what do people think of something like http://mweststrate.github.io/mobservable/ ?

It seems like the author is defining "quality of paradigm" to mean little more than the terseness of syntax. I agree that Redux is pretty rough aesthetically. It's definitely verbose, and I agree that this is a problem. I just don't agree that this is really a complaint about the paradigm.

I didn't really get why he thinks Elm is better than React. Can someone shine a light here?

I never used Elm and a only dabbled with React a while ago but I remember having a very confusing feeling about React. When I read the introduction and basic ideas everything "clicked" and sounded obviously correct but when I went ahead to try to use it the library was much larger and complex than I would have expected. I suspect that the sizeable complexity might have to do with supporting stateful subcomponents that can be redrawn independently (as opposed to a system with a single tree that gets redrawn every time) or with their promise to support server-side HTML generation. Does anyone know if this is actually the case? How does Elm compare? Does it also allow stateful subcomponents?

I've been using Mithril lately. His criticisms of React don't seem to apply to Mithril. Mithril seems to fit just fine in a Flux architecture. I haven't looked at Redux specifically.

I won't disagree. But from a business point of view, it makes a lot of sense to use React. It's support from a huge organization like fb, and mass adoption by the community, make it a safe choice to use in the long term, from a business point of view. Not only will it continue to be supported by a well funded engineering organization, but the pool of developers with experience with it is large.

As for Redux, I'm more of a Alt.js kind of engineer. All that being said, Cycle and Elm are totally cool.

It's true that Angular and React are supported by huge corporations. It also means that they will tailor these libraries for their mega scale usecases.

The problems that Google and FB is trying to solve at their unique mega scale is rarely the issues that startups and medium sized companies are facing. Flux and Graphsql comes to mind.

For example micro-services are great for Amazon but may add more complexity to tech team that are less than 50 people.

The benefit, even for small applications is reusability.

I have already published a <ng-markdown> component to GitHub that can be installed via JSPM and imported as an ES6-module.

The new module and web component standard are going to completely change the nature of how web applications will be built in the future.

Unfortunately, it'll be a few years until both standards are natively supported across all browsers.

Until then, web component frameworks like React, Ember, and Angular2 are the best alternative.

If you don't like frameworks, you can use polymer to as a web component polyfill but I've heard it adds a lot of overhead for what it provides and has some quirks of its own.

Yep - if you chose to develop something by paradigm alone we'd all be using PureScript: but there's so much more that's necessary to make something that needs to be around for 5+ years. Having FB dog-fooding and putting so much resources behind it is comforting and gives an acceptable trade-off of paradigm vs practical-ness.

Until Elm/Cycle/whatever's next have been around for along time and become established then to pick a framework to base a serious project on you're in the "two kinds of languages: the ones people complain about and the ones nobody uses" category.

That's so true. Kudos.

Being backed by a huge organization did not stop Angular from basically throwing away their stack with 2.0.

Although, to be fair, unlike Google with Angular, FB (more often Instagram) is actually dogfooding React and using it on their own stack. And with react-native they've invested a lot more in React tech than Google has in Angular.

Isn't react the actual result of FB's development, whilst angular (1 granted) was at least partially built prior to bring picked up by Google?

> it continue to be supported by a well funded engineering organization

People thought that with Cassandra too. Its not a safe bet to trust in a single well funded engineering organization.

Cassandra really only survived because Netflix, Datastax, Apache, etc. picked up the torch when FB dropped it.

That said, its still safer than the OP's suggestion.

I feel the same about what to learn to get a job (I'm a college senior). I like the ideas behind Cycle better (and in fact I am using Cycle in my senior thesis), but job-wise I cannot ignore React/Redux/React Native. Fortunately I don't dislike those; I just like Cycle better.


No, the "PATENTS" file cannot revoke the "LICENSE" file.

React's license is BSD. The PATENTS file additionally ensures that Facebook grants you a license for any patents they might have on technology that's in React. This grant—not the copyright license—expires if you sue Facebook, which is pretty standard for a patent grant.

Note also this clause:

> Notwithstanding the foregoing, if Facebook or any of its subsidiaries or corporate affiliates files a lawsuit alleging patent infringement against you in the first instance, and you respond by filing a patent infringement counterclaim in that lawsuit against that party that is unrelated to the Software, the license granted hereunder will not terminate under section (i) of this paragraph due to such counterclaim.

Please don't claim that the BSD license is revoked if you sue Facebook, and please read more carefully before you make claims of that nature... because not doing so leads to FUD, and also endless confused and uninteresting threads, as has happened in so many previous React threads.

Additionally, the thread OP linked to was outdated—from before they change to clearer verbiage.


I think if you're in a lawsuit war with Facebook, whether you lose license to use React or not is probably the least of your worries...

I just started working with Redux fairly recently, and I definitely felt that handling async effects in Redux wasn't as elegant as most other parts of the Redux architecture. Glad to find out that Dan feels the same way, according to the tweets linked to in this article [1].

Has there been any efforts to make use of js-csp [2] to handle async operations in Redux, like how ClojureScript apps make use of core.async channels?

Cycle.js definitely looks promising, but I have a vague suspicion that its approach of handling effects strictly through the output of the main function, although elegant, might make interop with the rest of the JS ecosystem a lot more painful, since many JS libraries don't have such clean separation of concerns. I believe JS interop is also one of the most commonly cited pain points for working with Elm as well, which uses a similar approach.

[1] https://twitter.com/dan_abramov/status/689639582120415232

[2] https://github.com/ubolonton/js-csp

The conclusion of this article is great because the author says "we need to continue seeking improvements." This is true of anything. Nothing is ever perfect.

My problem was the way in which the author got to this conclusion. Addressing React as "inferior" made the article feel like an attack on React when I think the author was really just trying to point out there are better ways to do things.

Of course React can do things better. Like I said, nothing is ever perfect and we are always building on the mistakes and learnings of the past. However, there are good reasons why so many people use it and it is an awesome option compared to some of the things we have used and done in the past. Eventually something will come along and do things better, but thats just the way the world works.

When a man spends a lifetime building a skyscraper with toothpicks he will always believe that toothpick is better than the brick, such is the contradictory nature of man.

You will also meet people who believe the entire universe is made out of apples and oranges and that comparing the two is pointless. These people will never realize that there are things in the universe that are inherently superior to other things.

So which is the brick and which is the toothpick? React or cycle or elm? Or am I looking at apples and oranges? Ask the man who has built skyscrapers out of all three.

Will such a man please stand up?

The best way to respond to these articles is to create things on these frameworks in question and form an opinion. Not everyone wants to solve the same issues at all times, how can one single experience tell you something is not good for you? it can't. Judge for yourself, use these tools before you decide from another person. In some cases (I'm not kidding) you're better off just using lodash and a package bundler. I'd say stop thinking in Uni-directional flow for all problems.

> In Cycle.js you can omit the props object. Since props are always an object and children are always an array, it’s obvious which parameter is what

Ack, I really do not like this. Detecting the meaning of each parameter based on its type is too much magic for me. If you're using positional parameters, they should be positional parameters. Otherwise I'm always having to guess how much magic is actually supported, and what each function call actually means.

I was skeptical at first, but this is really cool:

> In Cycle.js you can omit the props object. Since props are always an object and children are always an array, it’s obvious which parameter is what:

That's a lot cleaner than JSX. Kudos.

FYI, that's nothing to do with Cycle, that's just hyperscript. Works great with React if you feel the urge: https://github.com/mlmorg/react-hyperscript

The syntax is slightly different though:

    h('ul', [
      h('li', 'Foo'),
      h('li', 'Bar'),
Otherwise the same advantages as the author listed when using Cycle, eg, props and children are both optional, etc.

Yea. That's kinda like what Elm does for its views.

    ul [] [
      li [] text "Foo"],
      li [] text "Bar"]
Took a while to "get" it, but now I really like it.

(`ul` and `li` are functions that take two lists - the first is a list of attributes like class or ID or whatnot, and the second is the inner content... text or other elements.)

you forgot some braces:

    ul [] [
      li [] [text "Foo"],
      li [] [text "Bar"]

Hah! I did. Thanks!

I feel like I've been hopping from bandwagon to bandwagon. First Angular, then React (liked React more), and now I'm like, "ehhhh, some of this React stuff is fairly tedious."

I feel like I'm still waiting for the Holy Grail of JS frameworks/libraries.

Well, you aren't the only one. Welcome to front-end hell. :)

The 'holy grail' of frameworks will come in the form of new web standards.

- ES module loader - native web components - native observables

That's the gist of what all of the latest generation of frameworks aim to provide.

The next generation will use these and focus primarily on reusing front-end application logic across platforms. Ie Mobile, IoT, Desktop, etc. This is already happening to some extent.

In terms of paradigm, I still, to this day, find the Knockout.js MVVM paradigm best for most scenarios.

They don't get much hype but to me it's just a very mature and feature complete library with many "plugin" points to plug your own custom behaviour when you need to.

I did use React and I do find it unnecessarily confusing. In terms of performance gains, it doesn't really do a whole lot (for me). You still have to put a lot of though into structuring your rendering pipeline for maximum performance, and at the end of the day whether you spit out the DOM using react's "Virtual DOM" or some other custom templating engine doesn't seem to really make much of a difference.

React gets negative points for creating a parallel DOM structure and taking complete control of the portion of the DOM tree where it renders its components.

> 7 hours > 5 hours

both of these seem like an extremely long time to do something fairly simple in the native language for minimal gains and often huge tradeoffs (performance, memory usage, lackluster apis, etc)

The distinction here seems to be whether to group all your async code into actions, or let FRP producers pepper your code?

Big shoutout to Cycle.js, it's small, simple, and wonderful. Composing reactive streams is great.

The two biggest problems with React:

1. Updates are O(N), where N is the size of your virtual dom tree.

2. You have to manually keep track of dependencies within your code, in order to trigger updates.

React doesn't have to be O(N). You can short circuit rendering with shouldComponentUpdate checks.

shouldComponentUpdate only prunes the size of the vdom tree, updates are still O(n_virtual_dom). I've always thought this was an advantage compared to alternative approaches I know about since pruning the size of the vdom tends to be fairly easy compared to, say, optimizing a KVO chain.

#1 is true out-of-the-box, but there are many ways to fix that.

#2 is flat out not true unless you decide to ignore all of the documentation and have your render function depend on something other than the state and properties of your component.

I heard over 30 and you are out.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact