Hacker News new | past | comments | ask | show | jobs | submit login
Angular 2/4 Is Too Little Too Late (medium.com/chriscordle)
168 points by janpio on June 30, 2017 | hide | past | favorite | 201 comments



Re-post of what I wrote about this yesterday on Reddit:

I think Alan Kay was right: computing, at this point, is pop culture. Articles like this are are kind of like identity politics for programmers.

I don't say that that to disparage the author, because stuff like this is nothing new. Programmers have divided themselves into warring tribes for almost as long have there have been programmers. You used to see C programmers saying that Pascal is for idiots, and Pascal programmers saying that C is for neckbeards. Or similar arguments between C++ and Visual Basic camps or C vs asembler. And there are dozens (probably hundreds or more, actually) of other examples.

So it's not a new phenomenon, and I don't expect it to go away. The way I look at it, it's usually more productive to mostly ignore the pop-culturists and just pick tools that allow you to get things done quickly and happily. I've used Angular 2/4, React, and Vue. I like them all, and I'd be happy to work on a project using any of them. Aurelia looks equally enjoyable.

At this point, I don't think it's especially likely that a project will fail because you chose Angular over React, or vice versa. Pick what works best for you and your team, and don't worry about what the chattering bloggers say you should be using. :)


> I've used Angular 2/4, React, and Vue. I like them all, and I'd be happy to work on a project using any of them. Aurelia looks equally enjoyable.

I've used AngularJS, Angular2/4, and a bit of Backbone and Ember. I agree about React, Vue, and Aurelia and despite what hiring managers may think, I don't see competent engineers having much of an issue switching from one to the others.


I agree, and expanded on it in my reply to Analemma_.

Hiring has become too framework specific - if someone has built an application using a component oriented framework, I don't think they'd have much trouble moving between them.

I'd even cast a wider net when looking for good candidates while hiring - if I came across a great developer who knew JavaScript well and had also worked on WPF apps in the past...I'd probably be inclined to make them an offer, even if they hadn't worked with React or Angular yet. Maybe it's like Moneyball applied to the developer labor market. There are lots of people who would do a great job, but are undervalued because most hiring is fairly buzzword-oriented at most companies.

Frameworks and tools come and go. I think that the real value comes in understanding the underlying concepts and being able to apply them in new situations using new tools.


I'm currently working at a place that is basically tech agnostic when it comes to getting and it's pretty good in my experience.


> I don't see competent engineers having much of an issue switching from one to the others.

I went from been a "dyed in the wool" desktop/enterprise developer to a backend web developer in less than a year and a full stack in two, once you accept the patterns are different, programming is mostly just programming.

Here we are in 2017 and if you squint web app development looks a lot more similar to that stuff than it did back in 2009, I picked a fairly good time to move over I think, I missed a lot of the early bullshit around browser incompatibilities (I just caught the tailend of the shitfest that was older IE versions) and the tooling has improved hugely over that time.

TypeScript with node and some of the front end tooling is actually pretty pleasant day to day.


I thought this article was a reasonable assessment of the frameworks discussed and how we got here, without the maniacal hand-waving usually associated with identity programming.

I might not agree with it all, and I do think our community is frequently overly-dogmatic. But, I also don't think it's fair or productive to dismiss out of hand any critique of any tech as simple pop-culturalism or tribalism.


You're absolutely right that it's neither fair nor productive to dismiss any crituque out of hand.

I just found this article to be on dogmatic side of the spectrum. It doesn't seem that the author has enough experience with Angular to back up the negative assertions made about it.

I know it's only anecdotal, but I've seen teams that are simultaneously using both Angular and React happily and productively. When I've talked to people working on those teams, they don't really feel that one is drastically better or more fun to use, and they've found that speed of development and codebase maintainability ar comparable between the two.


>I've seen teams that are simultaneously using both Angular and React happily and productively

Yeah, it really is just a matter of opinion and thinking styles. I'm not sure why we're so bent on this idea that we should all do everything the same way. Part of it is self-preservation, I suppose. "I've got 20 years in Java and you're telling me it sucks (and, by extension I suck too)? You and I now have a problem."

But, we keep doing this with any new tech, and never seem to get that it'll all change and matters a lot less than we think. What people raved about 5 or even 3 years ago is now passe'. Call it evolution, and that's probably a good thing. But seems we could have learned to skip the part where we beat each other over the head while awaiting The Next Big Thing.

Funny thing is that no matter which framework you like, the worst thing you can do is not choose any framework. People can't even wrap their heads around the fact that you haven't declared a side.


We also have this idea now that spending an afternoon with some tech is enough experience to share with others. Initial learning curve and "am I immediately as productive as I wish I was?" have somehow become key metrics.


True. It cuts both ways though (I guess like most things).

That is, once a person has invested in that learning curve and spent significant time working in a tech, tunnel vision tends to set in. It becomes the only tool, which that person fiercely defends. They've now got too much invested to just let it go.

It's actually not unreasonable from a raw self-preservation/self-interest perspective, but I do think it contributes to a lot of the emotion-filled tribalism we see. In other words, the intensity comes as much from interest in maintaining self-relevance and personal financial security as from the viability of the actual tech.


It's even dumber than contemporary identity politics, because at least there you (usually) can't choose your identity and so there's a defensible case for firing back at people who try to make your life miserable because of it. But language/platform/framework fanboyism is just pure sunk cost fallacy: you spent a lot of time learning X, but if X was the "wrong" choice, then was all that time wasted? To avoid that outcome, people invest tons of emotional energy defending X.


I think part of the problem is that much of the job market is language/platform/framework oriented. So there's some value in defending the tools you know and use, because your value on the labor market depends on the market valuing your experience.

It seems like this is a bad approach to hiring, and I push back against it whenever I'm in the hiring decision loop any way. In the past, when the company I was at was looking for someone who would be working mainly with .NET, I wouldn't hesitate to being a strong advocate for a great candidate who has really only worked with Java. In my experience, such a candidate would take a week or two to really get up to speed and sort out the differences between the two ecosystems.

I'd have been just as strong an advocate for good candidates whose main experience was Python, or Ruby, or Node, or Haskell, or anything. I don't think I ever saw any of those, though. The company was using a recruitment agency to bring in candidates, and so we mostly ended up seeing people who fit a pretty specific archetype. And I don't think that led to us seeing the best candidates who might have been interested in us. Not that we didn't find some great people; we most certainly did. But we also found an awesome one via a post on an HN "Who's hiring" thread.


>there you (usually) can't choose your identity

The whole premise of identity politics is that you are the sole arbiter of your identity. It's an extension of the post-modern idea that since there is no possible way to favor a given interpretation of the state of the world over another, the only humane course of action is to let the people most immediately concerned by the interpretation set the standard. As such, the individual is given full dominion over his identity.

So no, it's equivalent in this respect.

(N.B.: the post-modernist could reply to my comment with something equivalent to 'that's just like your opinion, man', thereby illustrating why this reasoning gets us nowhere useful)


It depends on what the parent was referring to by "identity politics."

Some people use that term to mean politics according to demographic factors they cannot directly control, such as their race. So, if it was what was intended, then I don't think your (actually quite excellent) critique of post-modernism is relevant to what they were talking about.

Unless of course, you're arguing that it's the underlying philosphy even if the participants in it don't know it or think that way consciously.


> But language/platform/framework fanboyism is just pure sunk cost fallacy: you spent a lot of time learning X, but if X was the "wrong" choice, then was all that time wasted?

A lot of these articles give me this vibe. So what if a competing technology is "bad". What does the author get out of saying "X technology is the best and Y is fail"? Are these guys now thought leaders?

Also I tend to see these more often in front-end land. Not sure why. Possibly because the cost of switching technologies is so low that you need to convince people constantly that X is the best so they stick around.


I have a hypothesis about this: The lower your skill is at software development (or some subset of it), the more likely you are to be strongly opinionated about these kinds of arguments.

If you are highly skilled, you're far less likely to be married to any one bit of technology, even if you have prior preferences. You're also likely to have been through a few fad cycles before, so you probably learned to tune out the holy wars and focus on being productive. And if some stack X is really a giant turd, you should be able to figure that out quickly and avoid it, so you don't have a reason to write about how much it sucks.

On the other hand, if you know next to nothing, you're going to be more likely to read "Don't ever use X!" stories because you don't know what to use and are looking for advice. And you may be more dependent on whatever things you do use, because you don't yet know many other things, and you may be more likely to believe that it's better for your career to establish yourself as an expert in whatever you know.

I think the "front-end land" sees more of these now because front-end land is a new and bizzare place that only came into being a few years ago; people generally don't understand it as well as they do other things.


>A lot of these articles give me this vibe. So what if a competing technology is "bad". What does the author get out of saying "X technology is the best and Y is fail"? Are these guys now thought leaders?

I think it has something to do with signaling expertise, often for purposes of self-branding.


Fully agree with you.

There is a bunch of tech that I bash all the time, but if that is what makes the customer happy, then that is what I would use.

These posts seem like people self assuring they have made the right decision to use whatever technology stack.


Hey, thanks.

So many times I've read a post on HN or Reddit that I thought was spot-on, and then looked up and saw that you wrote it. Nice to see that the agreement goes in the other direction - or did on this occasion, at least. :)


> I don't say that that to disparage the author, because stuff like this is nothing new. Programmers have divided themselves into warring tribes for almost as long have there have been programmers. You used to see C programmers saying that Pascal is for idiots, and Pascal programmers saying that C is for neckbeards. Or similar arguments between C++ and Visual Basic camps or C vs asembler. And there are dozens (probably hundreds or more, actually) of other examples.

I don't interpret this article like this. I understand the observation that people have different opinions, but with JS frameworks, there's so many developers who sunk their teeth into a framework to be productive just to lose their edge 6 months later.

It's substantive for a developer, a team of developers, a whole community to invest their time into a framework that gets thrown out every 2 years.

It's painful to constantly pursue a moving target with JavaScript changing. Meanwhile, web frameworks like Django and Rails remained stable for over a decade.

> At this point, I don't think it's especially likely that a project will fail because you chose Angular over React, or vice versa.

That sentiment feels rather just-worldish in light that becoming productive at a framework (not just doing small tweaks) is a chore in itself. I recognize that people have their own opinions and philosophies of the framework they pick, but the article also factors in the timeline of these frameworks.

When I read through that article, I felt sharp remembrance of being on the roller coaster of continually rebuilding my skills from scratch with the new framework where the action is at.

> Pick what works best for you and your team, and don't worry about what the chattering bloggers say you should be using. :)

While I do recognize there is also a cargo-cult fanaticism that comes with JS frameworks, the amount of upstream contributions and extensions these frameworks receive back is considerable. The effects are also felt on QA websites like StackOverflow and so on.

I don't see the same behavior for every framework in software development. Like for instance, SDL2/allegro/SFML, I don't feel attachment and the API's are somewhat less of a moving target.

Potentially, because it's safe to say you can just pin NPM packages and your old Backbone code will build. But will people hire you for that Angular 2.0 position if you're not top tier in that framework? They could pass you up for someone who's already ready for to take up the job. There's economic ramification for workers on what framework they pick.


Yeah this is an old theme for sure, but Google has screwed up with angular so epicly, it's just surprising from the company that invented so much of the web that they would miss the mark so badly. I think that's why the angular/react discussion is a bit more wild than the old ones of yesteryear.

It's really more interesting from a perspective of institutional blindness/incompetence/arrogance than any real technical discussion.


The transition to Angular 2+ felt like a slow-motion train wreck at first.

To their credit, though, I find the Angular development experience to be quite good now. I like that there's interest in the Angular community around generating code that can be aggressively optimized by the Closure compiler.I like to ship as little code as possible to browser as possible, as lots of people are using older computers, tablets, and phones where parsing an unnecessarily large code bundle causes a noticeable delay.

Thus far, I've had a lot more success at reducing bundle size when using Angular than when using React. But I still end up using React often, because I enjoy it and I like the size of its ecosystem.


Yes, not a new thing. Car owners do the same thing. And brand clothes. And bike brand owners. And...

Mabe just a part of human nature to defend brand buy-in.


> Mabe just a part of human nature to defend brand buy-in.

Yup, this is because people invest their identities in the brands they consume/use.


You must be one of those vim users.


Even worse.... IntelliJ, Visual Studio, and sometimes even Atom.

I imagine that probably makes me seem like a glutton for punishment who loves development environments that require the power of a 90s supercomputer just to display a flashing cursor. :)

I do enjoy Emacs for Clojure development work, though.


This reads as react fanboyism to me. I used React/Redux on a project and was unable to bring people up in my aging team. Now we are fully Angular 2+. It is much better for my newly grown team of 15. The action creator approach of Redux isn't very readable or maintainable. The module system in Angular is better for us.

You can use webpack with Angular. RxJs is a great addition that will eventually be removed when Observables become implemented in JS. The declarative style of templates are different than JSX, but are not hard to deal with in practice. Native script allows for mobile dev, although I don't personally use it.

Before I switched to Angular, I preferred React. Now that I use this framework approach, I am much happier and have more faith that my code base will be consistent. I read somewhere that google used Angular for adsense so I think it is good enough for production use for us.


I guess when you say "aging" team then I imagine your team members mostly spent their time in the OOP world, and Angular is definitely a better fit in this case.

React and Redux promotes a more functional style (even though React components are classes...), and a lot of OOP people I personally met were not so comfortable with it.

Personally I love the functional concepts that it taught me, and I would never want to use a framework like Angular again. I'd rather make the leap and look into a real functional language for the frontend, like Elm, ClojureScript, PureScript,...


Honest question: why are React developers so fixated on functional programming? Why are objects - bundles of state and action that represent entities in the problem domain - automatically painted as an antipattern?


Two points:

1. It's not. React has had classes and states from the very begining. In fact, purely functional only views came in React 0.14.

2. That said, it really does make coding, debugging, and reasoning about views so much easier. When I have a bug in my React/Redux app, I can look at the Redux state, and figure out the cause of the bug right then and there. I'm not looking for some variable that accidentally got changed five steps ago.

My bug is either in:

(a) How I went from application state n-1 to n, or

(b) How my current application state is rendered in my views

Both of these are very fixable.

...of course, I do also have stateful React views in my app, and code with side-effects, because being "pure" all the time isn't always practical. If the bug is in those places, I'm in for a much longer debug.


Because they're not old enough to remember what '80s GUI code looked like when the "Global god object + functions" pattern was last popular?

That's a snarky reply, but there is a kernel of truth. OO was practically invented for GUIs (Smalltalk). Throwing it out entirely on principle just makes large programs harder to understand, IMHO.


True, I'm not old enough with my 33 years to remember that ;) But I do have quite a few years of experience in OOP and GUI programming (not just web stuff).


>Because they're not old enough to remember what '80s GUI code looked like when the "Global god object + functions" pattern was last popular?

Funnily enough, React + Redux is "Global god state + functions", with a bit of dispatch sprinkled in. Not too far away really.

I definitely see the benefits of having a functional approach to defining UIs. My code is _somewhat_ clear, clearer than what it would have been with say, WinForms or something of the like. Going purely functional everywhere is just devs cargo culting.


I had no real clue about functional programming prior to React. I always did OOP before.

Once I got in touch with React, I got interested in FP. Then I read the "Mostly Adequate Guide to Functional Programming" [1] and it was kind of an revelation for me.

I still do OOP, and I'm far, far away from being an FP expert, but I think if I'd take the effort to learn a real FP language then I probably wouldn't want to go back to OOP, and that's something I fear :) I've read a few blog posts from people who stated that learning FP kind of made them "unemployable", because they suddenly saw all the problems and annoyances that OOP brings with it (unfortunately I can't find the link anymore).

This quote regarding OOP by Joe Armstrong, the creator of Erlang, is quite fitting: "You wanted a banana, but what you got was a gorilla holding the banana, and the entire jungle."

[1]: https://drboolean.gitbooks.io/mostly-adequate-guide/


The "Mostly Adequate Guide" is a tremendous intro to functional programming for any frontend/JS developer. I challenge anyone who knows a bit of JS and is not convinced of functional programming's advantages to read the guide.

My only regret after becoming comfortable with functional programming in JS (and eventually, even more robust techniques in Haskell, OCaml, and Scala) is not pushing harder for a functional approach in work projects that could have really benefited from the functional paradigm.


> "You wanted a banana, but what you got was a gorilla holding the banana, and the entire jungle."

When you say that, what exactly do you mean by it?


Joe Armstrong said that in the context of code re-usability in OOP. At first it took me a while to understand what he actually meant with that, because OOP is about making code re-usable, after all. But then I read an article that explained this quote in great length and other potential pitfalls of OOP, and then it all started to make sense.

I would write all of this in my own words, but it would become really long and I don't have the time at the moment. I tried to find the original article I read, but I'm unable to, but here is a similar article I just found: https://medium.com/@cscalfani/goodbye-object-oriented-progra...

I'd understand if the inflammatory writing style and the memes are not yours, but I skimmed through it and I think it does explain some of the problems well. I'm sure there are better written articles on this subject, but I have to leave now unfortunately.


Looking at that article, it seems nearly every complaint is about inheritance. But it is quite possible to use objects with composition. In fact, I think 'composition over inheritance' has been a commmonplace since the late 1990s.



I definitely also read that one back then (I keep stumbling upon this website every now and then, it contains some really interesting articles), but I remember that it was too vague for me to understand his point about why OOP sucks. I searched further until I found the article I mentioned, it was much longer and more detailed than this one, and not by Joe himself.


I understand it as: OO hides the distinction between a standalone value and a service connected to a bunch of hidden state.


Being able to unit test every single part of our stack through composition of pure functions makes for a nicely decoupled architecture.

We have a strictly defined state object that is used throughout our entire application. Because we made a contract with redux, every transaction is readable and transparent.

Writing tests for our UI layer has never been easier with React. While we do have local state inside some react components, when we use redux to pass state to our react components, they become extremely easy to test, because they turn into pure functions.

When using something like jQuery, you wouldn't just look at each frame of your state to determine how the UI would look, you would also have to look at the transitional states between A and B. Transitional states are much more difficult to understand because of the contextual implications.

Our UI layer is completely separate from our business logic and we get it automatically. Without any code modification we were able to target our large application into a CLI app just by adding a new UI layer.


I don't think bundling of state and action is inherently an antipattern (even in functional programming there is an implicit coupling between the shape of the app state and functions that operate on the app state), but in a system with countless individual units of tightly coupled state and actions interacting with eachother, it's all too easy to fall into the real antipattern of overusing in-place state mutations and neglecting deliberate management of state transitions across the entire system. Functional approaches to frontend development tend to encourage patterns like the single immutable app state tree and writing state transitions as pure functions, which helps minimize this source of complexity.


Are you sure about that? Main React use-case is class extending React.Component with its own state, so it's certainly very OOP. You can use functions, but even in that case they are not considered pure (and there's a good reason not to use functional components at all, unless some higher-order-component manages updating).

There's certainly Redux movement, because it solves few important problems almost for free. But React isn't bound to Redux in any way.


Follow up honest question. If they are so fixated in functional programming why not use ClojureScript? Trying to use react with immutability in JS looks like pure pain.

I'm a swift / go guy mainly but I've been looking at this space for a while and the only sane approach to me looks like ClojureScript with reagent / reframe or something along those lines.


I agree that is the logical consequence. Elm even more so than ClojureScript, imo.


Absolutely agree, I forgot to mention elm.


Because obviously "function(this, arg1, arg2)" is better than "method(arg0, arg1, [this])"


More often than not, yes, I find it is.

But in a nontrivial number of cases it isn't, and then I use methods.


I actually really liked Redux, but given the size of my team, I would choose Angular every time now. It's just more complete.


You might like NGRX, then. It's basically Redux for Angular 2.

http://onehungrymind.com/build-better-angular-2-application-...


Will this ever end? How deep must the stack go? God, I give it 10 seconds for someone to pop out of the woodwork and say "Why don't you just use NGRX v3 'cute name'? Here's a link to my 10 star GitHub"


> even though React components are classes...

Since 0.14, React components can be functions, too: https://hackernoon.com/react-stateless-functional-components...


> You can use webpack with Angular.

That is a bit of an understatement. Using the angular CLI the default is setting up a project with webpack with a single command. Webpack is wrapped in the "ng ..." commands for building and running. With "ng eject" the webpack config file is exposed and webpack is in the driver seat. It is not just "can" but it is really easy these days.

There may be reasons not to like Angular but articles focusing on AngularJS 1.x are not shining the light on relevant weaknesses.

Angular may be too late if one buys into the view that the growth in the JavaScript ecosystem has peaked or is peaking soon. My personal view is that the growth has been stunted by severe UX problems before ES6/Typescript and we are just at the beginning of an explosive growth phase with no end in sight.


React + MobX is my goto when it comes to teams like that. Much easier to get up to speed with than Redux and often a more familiar programming model for people.


I've used Redux, but have never used MobX. How's MobX compared to Redux in terms of debugging experience ? I've looked at a couple MobX examples, and felt like the obserable stuff, while help reduce boilerplate code, could hide too many things which could make debugging a bit difficult.


I've had some problems with mobx. Works great on smaller projects, but can be hard to debug when something goes wrong.

Observable objects are tough to read in the debugger.

The main gotcha I found [1] was dereferencing property of an observable didn't trigger rendering. Didn't feel very intuitive to me.

Also, occasionally, I would insert a row into an observable array and nothing would happen, and I could never figure out why.

Using redux now, it's more explicit and full of boilerplate and ceremony, but I understand all the code, and there is far less magic.

[1] https://mobx.js.org/refguide/observer-component.html


>dereferencing property of an observable didn't trigger rendering

For real!? This seems like either a critical bug or huge design mistake on the part of the MobX author.

I also cannot understand why you cannot make a Set an observable. It's such a fundamental part of programming!


I'll take a look at that. Never knew about MobX. In general, loyalty to one framework only boxes off our minds to what could be a better way of accomplishing our goals. It's a great world out there that we have so many options.


plus one for Mobx. It really is very simple compared to redux. I do have many apps using redux, but for newer ones i now prefer mobx.


> You can use webpack with Angular.

In fact, Angular CLI uses Webpack by default.


> The action creator approach of Redux isn't very readable or maintainable.

Can you elaborate on this? I've been working on an Angular 2+ application that I think could benefit from a redux like state container a la ngrx/store. I'm curious if some of the issues you outline might also be applicable here.


> You can use webpack with Angular.

Ionic, the mobile framework based on Angular mentioned in the article, actually does by default in it's `@ionic/app-scripts` that are used to build these applications.


AdWords, AdSense and internal Google CRM are written in Dart - namely AngularDart:

https://webdev.dartlang.org/angular according to: http://news.dartlang.org/2017/06/a-stronger-dart-for-everyon...


>This reads as react fanboyism to me

Why isn't your comment Angular fanboyism?

Full disclosure: I prefer neither.


It reads like React fanboyism to me too. Very one sided, and seems light on actual knowledge of Angular.

Full disclosure: I am not a web dev at all so my opinion is more valid.


Couldn't have said it better myself.


>> Benchmarks for React consistently show its superior performance over Angular 2/4: https://auth0.com/blog/more-benchmarks-virtual-dom-vs-angula....

Intellectually dishonest. The article linked to was from January 2016, around the time the first beta of Angular 2 was released. That code has all sort of debugging code in it, and the architecture changed quite a bit between then and the release in September 2016. (To say nothing of the fact that those benchmarks don't cover Angular 4, despite the preface in the article) With AOT in Angular 4, a site running in production is quite fast compared to JIT.


Here's a litmus test for if you should use Angular or React: how do you feel about the fact that React has ~4 major routing libraries?

I've written a book on both Angular 2+ and a book on React. I've talked w/ hundreds of developers on both sides and I can tell you that people with different constraints (and backgrounds) will have a different response.

The author of this article cites "more ReactJS libraries on npm" to imply that React is the better choice. Some people love a la carte infrastructure and the power that comes from choosing each element in your stack.

Some people love to have those decisions made for them, because they just want to build their app.

It's often cited that React is "simpler" than Angular, and if you look at just the core that's true. But by the time you pick a data architecture, styling choice, router, etc. you're back at the same level of complexity.

Actually in React, you've spent a lot of time researching which components you want (and if they'll even fit together). The pro here is that you get just the stack you want! The competitive evolution of these libraries means that you _can_ have 4 routers and pick the best. But also, if you'd just picked Angular, you just use their router and move on.

Here's another litmus test: Do you want 'string' templates or JSX? (Now, I know it's technically possible to do either in both frameworks, but it's almost never done in practice.)

Almost everything that seems "more complex" in Angular is a result of string-based templates. DI, AOT, the *ngIf and `let` syntax, is all because you're doing templates in strings instead of code. How do you feel about that? Would you rather write templates in JavaScript/JSX? Then use React. Do you have designers doing HTML on your team? Then use Angular.

(Also the other opens by citing webpack, npm, and third-party libraries as a React-specific benefit, but that makes no sense because angular-cli uses Webpack, it's on npm, etc.)


Our litmus test was that we invested years into Angular 1.2/1.4, and when 2 came out it was so radically different that we would have had to have effectively learned a new framework. At that point we switched to React.

Everything you're talking about is great in a vacuum, but stable APIs and backwards compatibility is more important to organizations in the real world.

I can't trust Angular as a framework anymore, as past actions are indicators of future behavior.


> it was so radically different that we would have had to have effectively learned a new framework. At that point we switched to React.

Yet the end result was still the same. Another lesson in branding for Angular.


I still can't believe they looked at their framework reaching escape velocity and gradually becoming the thing to learn and decided to turn around and announce a backwards-incompatible framework with no migration path that took away two-way binding, the marquee feature that sold everyone on it. Of course they backpedaled on some of that but the damage was done.


> how do you feel about the fact that React has ~4 major routing libraries?

I think it's worth mentioning that the API for the largest one of these (react-router) has had breaking changes with every single release, and takes a totally new approach to routing each time. So the question is more, 'How do you feel about changing your approach to routing every time you write a new app?'

Or maybe I'm just too old and bitter for React haha


Old versions of libraries don't disappear when new versions are released.

You can npm install react-router@^3.0.0 and keep using what you know.


Sure, if you're ok with having wildly fragmented documentation for all the different versions of the one component making it difficult to troubleshoot any problems you're having with your version, which becomes increasingly more out of date.


There may be 4 different routing libraries, but the complex decision-making with React happens up-front, which may involve (at most) a day evaluating the options and making a decision.

My biggest problem with Angular is the sheer surface area of the API and the dependencies between the different modules. Angular as a framework has 10+ different components, all of which are deeply integrated. All of this is wrapped up in Zone.js which produces some of the least helpful stack traces in history.

A React app may be a composition of 4-5 key libraries (state management, routing, authentication and potentially a form helper) but each individual library has a much smaller API surface area and the decoupling makes it easier to debug.

I recently rebooted a project that was built in Angular in React after over a week of trying and failing to debug a wide range of subtle issues in our implementation of universal rendering which absolutely broke AoT compilation. I won't deny that there's a high possibility that our code was the problem - it's just that there were no useful stack traces showing where to look and digging through the different libraries was a mission and a half.

There's a lot to be said for composing a few independent libs with small APIs, rather than having a gigantic framework whose documentation is only skin deep.


> The pro here is that you get just the stack you want!

I don't disagree with the facts-on-the-ground of your post, but I think you're drawing a mighty false equivalency and this line highlights it. The pro here, for a React-based stack is that you are forced to understand the tools involved well enough to make meaningful decisions (if you're a competent developer). By the time I was done evaluating routing libraries, I was confident in my ability to write my own, effectively--and so I didn't have to because I was able to adopt the library of my choice's mental model immediately. If you "just want to build your app", your app is gonna blow up (not might, will, given a long enough timeframe) and you're not going to be equipped to fix it.

Passive consumption is unwise for programmers. We've seen it bite people forever (be it the "all things come from Microsoft" era of .NET that they're just shaking now or the "Spring does it for us" era of Java or most of Rails pre-3.0).


The history of technology is using the progress of others as a foundations on which to build something new. Once it works, it's a given, a building block. No one can understand it all the way down and we need to be careful about saying what 'real developers' do or don't do.


It's not a given at all. All of your abstractions break. These high-level abstractions break much, much more often than lower-level abstractions (because they try to encompass more, it's a surface-area thing). There are abstractions that are so fundamental to doing your job that you must, must must must, understand them at an implementation detail and then use them to improve productivity.

The stump-dumb-simple routing layer of your JavaScript handwavey crap is one that You Really Just Gotta Know; it's literally central to everything you do in a SPA. And yet the overwhelming majority of AngularJS folks I have ever met--and, to their discredit, way too many keypuncher ReactJS folks, but a significantly smaller proportion--have no idea what to do if their web framework spits the bit. And my contention is that having to make choices means the likelihood of a baseline understanding of what chose choices mean is way higher.

There are plenty of capable developers who work on and choose to use AngularJS. I've worked with great ones. But, like the other environments I mentioned before, it sure seems like they brought that capability to AngularJS rather than had that capability fostered by AngularJS in a pedagogical manner. And that's troubling to me, because these folks are going to be writing software that you and I depend on, too. I'm not hanging people for not being able to work meaningfully with the JavaScript runtime or understand how the browser works internally (though these are handy to know, most of my knowledge of JavaScript comes indirectly from embedding first SpiderMonkey and then V8 in a game engine once) or how their OS handles process segmentation to sandbox off their web runtime environment (not a super complicated topic but, sure, out of scope) or how their OS handles memory (this one, ditto) or or or--I'm saying you gotta understand the thing your hands are on all the time and that tools that attempt to swaddle you in a nice comforting "you don't need to worry about that" are gonna put you in a real rough place when that doesn't hold.


So, I've had to maintain (upgrade) a Node/V8 extension, an Angular1 and an Angular2+ but never stopped to understand routing. (We talked about it briefly around that ng1 app.) And I have no idea how Node extensions hook into V8 under the covers.

There were no abstraction breaks. C++ compiled, the thing works, the same goes for ng2 with TS. Ng1 is just plain ugly, but works fine.

I like React/JSX, FRP, I hate the size of the bundles Angular spits out, the byzantine boilerplate required to put something on screen and to make components interact, but it works, and it comes as a full package, and it keeps getting better.

The design principles of Ng are sound. Ng1 was overcomplicated. Ng2 is okay-ish.

I think ng lacks the "documentation" that the React ecosystem must provide due to its separatedness/modularity.

But my main point is, that basically good developers will compare those routing plugins/libs, and those same devs can solve problems when ng2 spits at them. And newbie frontend devs jump on the React is small and simple hype train and take the first tutorial and then get lost in that jungle. (And I'm not saying this can't happen with ng1/2, but neither codebase is about teaching programmers, so that's a very fringe aspect of this topic.)


(Managed to cut a lot of snark I think. Less light-hearted now but also less annoying.)

If you "just want to build your app", your app is gonna blow up (not might, will, given a long enough timeframe)

I feel pretty safe building stuff using technology (Java EE) that I only know the surface. (i.e. API) of.

I think that we should choose solid, well though out libraries that we wouldn't have to fix by yourselves.

and you're not going to be equipped to fix it.

This seems to be more of a problem in JS land where tecnologies seems to get born, hit peak popularity and die within a few months.

In such a case I guess it makes a lot of sense to choose stuff that I could rewrite myself.


Never treating anything as a black box and learning the implementation details of every single bit of the framework I'm using sounds like a good educational exercise, I guess, but not a great way to deliver a useful application in a reasonable amount of time.


Being able to do that (and it doesn't take that long because you should be leveraging your prior experience to quickly build that picture) is literally the core value prop for engaging my services, so it seems to kind of matter to a lot of folks.


Sure, for any one component that's probably true. But there's a lot more than routing going on in a typical SPA, and you'll never really need to dig into most of them most of the time. My preference is to dig into components when I actually need to, rather than digging into every single detail "just in case" it might matter later.


This argument is as old as programming. High level language programmers don't understand everything as good as us assembly programmers, etc.

I don't think it's relevant for evaluating tools.

It is only relevant when hiring as you would like to find developers that is competent enough to grasp low level stuff at least at a rudimentary level.

In this case some side interest in routing frameworks might be indicativ regardless if they prefer to work with angular.


> The author of this article cites "more ReactJS libraries on npm" to imply that React is the better choice. Some people love a la carte infrastructure and the power that comes from choosing each element in your stack.

Come on, that is not an honest reading. The author uses those numbers to demonstrate the health and maturity of the respective ecosystems. The power of choice is a bonus for those who choose to leverage it.


I don't think you're getting the point being made here. More choice also means more headaches like "do these two things work together?" which is not a problem in angular-land where you need very few dependencies that are not part of the core application.


No, you don't understand. The GP said the author cited those numbers for that reason, but the author did not.


Angular 2+ user here: - Components have nice API and are pleasant to use - Dependency injection containers out of the box are good for those who value inversion of control in their codebases - Change detection is good and fast. Gone are the times of leaky abstraction of the digest loop - Tooling has caught up: Angular CLI for rapid start, server-side rendering works just fine. You are using npm, webpack, typescript (brings es2016 features to you), modern testing frameworks and what not - Redux works nicely with Angular2+ as well, it's not exclusive to React - You can wrap pretty much any 3rd party browser widget into Angular component within maybe one hour of work

I guess when your open source library passes a million downloads per month, you are not worrying too much about marketing anymore. So i'm not quite sure why it's so important for the author to declare one and only one winner in the race. Both React and Angular users are benefiting from the competition


> Gone are the times of leaky abstraction of the digest loop

But now you have zone and it's leaky. See this stackoverflow question for example: https://stackoverflow.com/questions/43097291/firebase-datasn...

Edit: wrong link


You about summed up my experience too.

> So i'm not quite sure why it's so important for the author to declare one and only one winner in the race

Attention seeking I guess


I agree with the article's main point. In the market share fight between React and Angular, React has won — and for good reason, I think.

Angular 4 is an improvement over Angular 1.x, but Angular's main problem is still needless complexity, both in syntax and concepts added by the framework, and a totalitarian approach, in the sense that Angular seems to want to replace vanilla JavaScript/DOM/Browser API's with it's own slightly different and unnecessary versions. What you learn developing in Angular is therefore specific to Angular and not transferable to other domains. Personally I find that depressing and demotivating.

Angular 4's HTML templating syntax is terrible. I get the feeling the deliberately set out to make it as complex and inconsistent as possible — it's hard to phantom how else they ended up with such a mess.

Angular seems to have been inspired by the worst of Java EE from days of yore, it's riddled with needless complexity and ceremony. No one should have to work with that with the nice alternatives we have today.


It's bizarre that you would complain about Angular replacing vanilla JS/DOM/Browser APIS and then say React is better. React literally replaces HTML and the DOM with its own XML dialect and virtual DOM.

This means that, until recently, you couldn't use CSS Grid in React components, because every single CSS property that you want to pass through JSX needs to be explicitly whitelisted[1]. No other front-end framework has gone as far as React in trying to replace the vanilla web platform with its own technology and idioms.

[1] https://github.com/facebook/react/pull/9185

Angular's new template and component syntax have a learning curve. But they retain a far closer mapping to what's actually alive in the browser's DOM. A component instance actually wraps a native element, instead of being a function that emits a tree of objects that eventually get turned into DOM elements by some opaque virtual DOM process. When you grok what the syntax means, it's actually a rather elegant way of expressing binding to the HTML element properties and attributes and between component instances.

There are arguments for and against both approaches, but I don't see anyone on the React side of things even trying to understand them. Instead, they dismiss Angular's approach based on five minutes spent scanning syntax examples, and adopt a cult-like mindset that React is the silver-bullet for software development, and that alternative approaches are wrong and evil, and that anyone who uses them or likes them is stupid and/pr incompetent. It's a very arrogant and unpleasant attitude.


>> React literally replaces HTML and the DOM with its own XML dialect and virtual DOM.

This is one thing I don't like about React. If my intention is to create an HTML template, I would like to use HTML to do that, not through another layer of indirection (JSX).

>> No other front-end framework has gone as far as React in trying to replace the vanilla web platform with its own technology and idioms.

I think Angular does something similar with zonejs while trying to patch every javascript async function. I just don't like this approach at all. Because of this, while using Angular, I have to keep in the back of my head that the setTimeout function that I'm calling is not the native setTimeout function. Most of the time I don't have to worry about it, but it still bothers me.


You'll be pleased to know that we're making Zones optional pretty soon here. This would mean taking control of change detection yourself, of course, but there's plenty of valid use cases where that's a reasonable idea.


> In the market share fight between React and Angular, React has won — and for good reason, I think.

I think HN members often forget that there is a whole world of software development outside of the big tech giants and startups. Often the tooling and frameworks used there is very different.


Here I will say that Angular 1 still wins over Angular versions made after transition to typescript.

The biggest win for Angular 1 was push for code reusability throught enforced modularity. This matters a lot for both "big co." and "outsourcing sweatshop" type collectives.

To defeat React, Angular guys will need to defeat Angular 1.x first


"In the market share fight between React and Angular, React has won...."

All the data I've seen indicate that both Angulars, combined, account for twice as many production code bases as React. I wonder where you got the idea that "React has won"?


... and non-SPA, full-page-load-driven, jQuery-based web apps dwarf BOTH by an order of magnitude, even in 2017. You're just not going to receive many blog clicks or discussion forum upvotes by pointing that out.

"Won" usually means, "the thing that people most want to read or talk about at the moment".


Actually, the same data indicates that jQuery is around 45% market share as the primary front-end JS tool. That's almost exactly the market share of both Angulars and React combined.

And yes, this represents a steep drop-off in the number of jQuery-centric applications in the past couple of years.

Edit: I thought I had bookmarked the Web site where I saw these numbers, but I couldn't find it before running out the door this morning. Suffice it to say, the JS landscape is changing rapidly, and assumptions that were safe even 12 months ago are not valid today. jQuery is fading quite rapidly, and though it won't disappear any time soon, and, increasingly, it is no longer seen as a good choice for large apps with tons of business logic.


I'd be interested in types of applications those numbers are using as the pool for its comparisons.

What I'm saying is not that jQuery is the end-all-be-all. It isn't, and trying to build a highly dynamic web application with tons of client-side logic around jQuery is indeed a recipe for spaghetti.

What I AM saying is that most web applications (especially in the enterprise business world), simply AREN'T all that dynamic. They are primarily driven by full page loads rather than AJAX, and server-side logic rather than client-side code.

On HN, the terms "web application" and "SPA" are practically synonymous. But outside of a few social media titans, and the startup community, that's hardly true.


I used to make close to 90k a year at the hight of Web 2.0 mass hysteria with nothing more than few animation and dynamic loading tricks.

Life has gotten toughter since then


Hyperbole


>>time-travel debugging, hot module reloading, and simple and easy undo/redo capabilities

These things are prime selling points of Redux and it's interesting that they are simply unimportant bells and whistles not worth the massive increase in complexity and cognitive load that Redux brings to ReactJS applications. Use Redux and you have to write a lot more code, really for no good purpose when in most cases you can just store a (HERESY!) global variable and get straight on with the job without twisting your mind around actions and all the other Redux guff.

Redux is an anti pattern.

This article also breathlessly praises webpack, which is a massively complex and configuration heavy JavaScript tool and one of the prime culprits responsible for the JavaScript build tool ecosystem being so damn complex. Webpack needs to go the way if it's predecessors and he replaced with something simple.


I have always felt that the Redux projects I've seen are extremely bureaucratic. I don't know if they are outliers, if they are just 'Redux done wrong', but typically I find that every piece of behaviour is split out across multiple layers, generally in different files, to the point it is very difficult to reason what a particular button or event will actually _do_.

I notice also that in these projects, every pull request takes many files. Whereas in an Angular 1 project there would be an update to a template and a controller, now each PR comprise updates to a reducer, a container, a component, a saga, a 'lifecycle component', an action creator, and a props schema.

As for Webpack, I don't understand the popularity. I find configuring it awkward, not least because it relies on third-party plugins of highly variable quality. Most plugins are very poorly documented, and those that aren't invariably seem to have big fat DEPRECATED notices. It seems that any plugin that makes enough assumptions to be useful is inevitably chucked in favour of something that is totally configurable but by default equally useless. YMMV.

At least with Gulp, I could step through a build process and write a little bridging code when two plugins stepped on each others toes. Webpack doesn't give me any such chances.


Redux is a cat that thinks it's a lion.

It's not managing the combined state of a massive 1000-system enterprise mess, it's just pushing some shit out through a browser.


what is "lifecycle component"?


Redux DevTools is immensely useful. Being able to see all of your state for your application and clearly know exactly which action caused some invalid state is great. It also enables QA to export the actions which caused some invalid state rather than needing to laboriously and perhaps inaccurately describe a series of steps.

Redux itself can cause people to write quite a bit of boilerplate, however it massively improves testability, and if you use the correct abstractions and debugging techniques around it definitely decreases cognitive load. The problem is that it's possible for people to misunderstand how it should be used and shoot themselves in the foot.

I agree that Webpack is complex, however it is much more manageable than a series of folders containing obtuse Grunt/Gulp tasks, ad-hoc scripts and wrapper plugins.


I think it says it all the Redux comes with its own set of tools to see WTF is going on inside it.

None of it is necessary. Your code base will thank you as will the gods of software simplicity when you rip out all the Redux and Redux tooling and write this.app.globals.myvar='selected'

Honestly, think about all the time you spend writing not React code but Redux code - it's crazy and totally wasted time and effort.


  this.app.globals.myvar='selected'
How do you find out which part of your code set your global mutable state object (e.g. `this.app.globals[propertyName] = stateType` or `$globals.myvar = 'selected'` or `window.app.globals['myvar'] = 'selectedd'`)? What if two or more bits of logic try to set this variable at the same time and it ends up with a value that you didn't expect? How will you control that `myvar` can only be set to particular values dependent on other state? How will a QA engineer demonstrate to you that it was this state change which broke your application?

Your 'solution' is a bad practice, and Redux is a huge improvement over it.


> How do you find out which part of your code set your global mutable state object

Generally, it's easy. My state variable represents a single concept in my problem domain, so there's usually only a single source of truth that would ever update it.

> What if two or more bits of logic try to set this variable at the same time

Generally, this will only happen if the variable is actually a derived property, rather than a primary one. I handle this by making my primary properties observables, and my derived properties read-only computeds. Taking this approach, I don't think I've ever had the quandary you describe, and I've built everything from very thick SPAs to very thin and nimble content sites.

> How will you control that `myvar` can only be set to particular values dependent on other state?

It seems to me a matter of simple discipline.

> How will a QA engineer demonstrate to you that it was this state change which broke your application?

She might write a failing test case, or use the debugging tools I've added to the console. She certainly wouldn't mess about with something as proprietary as Redux devtools, because at that point I'll be unable to move to better JS technologies without getting cross-team buy in. At most companies, that basically means it just won't happen.


Your solution is for everybody in your team to maintain a high level of discipline and for QA engineers to use homegrown debugging tools you've added into the console.

You have effectively advocated for both NIH syndrome and a social solution to a technical problem (effectively "it is possible to write error-prone and difficult to debug code so we should ask everybody in the team to be more disciplined" vs. "lets make it impossible to express error-prone logic, and lets make it easy to observe our state"). I think Yaron Minsky's "Make illegal states unrepresentable" is appropriate here.


From where I'm sitting, your reply looks a lot like an insult. I hope I'm just reading it badly, but as is, I don't think we're going to have a productive discussion.


Where is he insulting you? It reads as a pretty even-handed extrapolation from your assertions. Maybe a little incredulity, but your assertions are a little incredible.


Maybe they are incredible.

I suppose the reason I don't 'get' Redux is probably that I don't 'get' the problem it claims to solve. Redux developers seem to say their issue with prior frameworks was that it was difficult to understand where state changes came from. But that's just not an issue I've had in the apps I've built.

Maybe the apps I call 'thick client' really aren't? Then again, I've done a fair few gigs in this game, on lots of kinds of projects, so I'd expect by now to have the perspective to say which was which.

That experience also makes me a little stubborn. I've had a few exchanges like this, where people have reacted with incredulity. They remind me a little of the arguments I had convincing people to abandon 'semantic' CSS, or grouping templates and view logic into components. I think history was on my side, at least in those cases, so I no longer feel abashed to walk against the crowd.


> Redux developers seem to say their issue with prior frameworks was that it was difficult to understand where state changes came from.

Prior to React/Redux we used two-way data binding with first kendo then Knockout.js in a non trivial SPA. It was a nightmare to figure out where certain change events came from. It became a big ball of (un)observable spaghetti. Now you will tell me that our problem was that we let it come this far, and I totally agree with you, but the whole app was started years ago by inexperienced web developers (they were C/C++ devs), then it grew historically into an unmaintainable monster. This was long before I joined the company, and my team is now like the 4th generation working on and refactoring that code.

Redux makes it laughably easy to figure out where state changes come from. Not only that, but time travel debugging is a thing. For the parts that are mostly React/Redux, we made a little debug UI for QA so that they can serialize the last n states, send it to a database and automatically link it to issues. It's still more or less a proof of concept and not as useful as it could be, because not everything is stored in Redux yet, but it did show us that once we are where we want to be it will be an incredibly useful tool to reproduce bugs. Besides that writing unit tests for React/Redux is also easy, compared to other libs/frameworks.

May I ask with what kind of technologies you've been working with so far? Because reading your comments gives me the impression you live in a perfect world, with highly experienced and disciplined team mates, with no problems what so ever. If so congrats, you've won the lottery I guess.


What Simon describes here is why stuff like event log datastores (Kafka, mostly) and CQRS-patterned systems are becoming so powerful, too. If you can just say here is every event that has gone through the system modeled as unambiguous transforms on immutable state, replaying--for both DR and debugging--is a trivial and super helpful exercise.


"thick" client is really meaningless term, when it can mean anything between "5k+ LoC" and "100k+ LoC". I'd argue redux is best used for projects closer to that upper bound.

But I don't have real experience with it. I just extrapolate from general overusage of strong (but inappropriate for smaller projects) tools in JS world and subsequent annoying whining about "JS fatigue".


I fail to see how is any framework code is easier to debug than vanilla js.

React is pain to debug unless internal React error catching logic fires

With vanilla js, things are as simple as putting breakpoints in code and running it in Chrome's standard debugger


I'd love to see the code of your vanilla js SPA :) Or does the server render the HTML, and JS just adds a little bit of interactions? Because then you are right, you may not necessarily need React (but it can also render on the server)


It's such a dead simple solution that it's never been a problem. Certainly doesn't warrant replacing with all the code and complexity of Redux, which introduces its own demand for testing and QA, and I would argue offsets its own value due to its complexity.

In software development simple = understandable and reliable.


But I just demonstrated that it's not understandable or reliable. You are proposing a solution where any badly written code can affect your global state in a way that you can't control for, and in a way that you will not be able to search for.

Eventually you are going to get bugs, and you are going to have a hard time tracking them down for the reasons I've described.

It might be okay if you work on small projects without many team members, but in larger projects it's extremely annoying to have these kinds of issues.


> Eventually you are going to get bugs,

I read:"Sometimes you are going to get event bus." Indeed sometimes simple event bus (pub-sub etc.) could be sufficient for replace Redux. EventEmitter is already a dispatcher. And then you can easily listen to each event in your app, like in Redux.

I think the key to the scalable apps is good architecture (and correct design patterns), not framework.

And Redux is good as education tool. It encourages people to use one global event bus("dispatch" function), it educates about principles of functional programming. It shows people advantages of event sourcing and CQRS. I think the most value of Redux is that people got educated.

But I don't think Redux (at least Redux alone, without Redux-saga or other solutions) is good tool for use in production code. It's too low level. Too many moving parts. No clear way "what should go where". And JS sucks when comes to immutable code (either Object.assign / ... mess or necessity of using third part library like Immutable.js)

Additionally people don't know how to use it properly. Redux codebases are usually much worse than Redux really demands (e.g. people use ugly switch/case despite the fact in Redux docs there are instructions how to get rid of them: http://redux.js.org/docs/recipes/ReducingBoilerplate.html#ge...


I wonder if it's maybe the architecture of my application that means I don't need to store much state, and I only store state that doesn't seem to subject my app to the issues you describe.

When I hear about these apps with a heavy reliance on client side state I wonder what the heck they are doing... if you've got so much complex data/logic does it really belong in client state? I'd see it as a problem and try to architect it out, or store it somewhere.


It's absolutely possible to do something that has the issues I'm describing and never see any bugs because you are disciplined and careful. However, as a contractor, I have worked with plenty of teams where due to horrible deadlines and sloppy practices all of the problems I've described have occurred. Basically: once you climb over the learning curve, Redux helps you here.


Whether it's in PHP, Python or JS, this type of anti-pattern is considered as such for good reason. I don't know how many days (months?) of my life have been wasted debugging "why is this variable changing, and from where?!?". Accompanied of course by much cursing the developer to the n-th generation who thought it would be a good idea to use a global variable.


> rip out all the Redux and Redux tooling and write this.app.globals.myvar='selected'

It's obvious you have no idea what you are talking about.


It's lazy to make an ad hominem attack. I write big feature rich react apps without Redux and never hit any situation where I sit around going "damn I need time travel and hot loading and and extra thousand lines of Redux code to remember state."


This thread is exactly why "js developer" gets stereotyped.

Try looking at egghead.io tutorials; Dan Abramov has a series showing the implementation of redux and it really is quite tiny. It solves one problem and solves it well: ensuring that components get notified when state changes.


I'm sorry, I read your comments, and I could write a 5000 word essay, trying to show you that your perception of Redux is totally wrong, but I'm not going to bother, because I'm sure this won't change your mind in the slightest.

> extra thousand lines of Redux code to remember state

Sorry for yet another ad hominem attack, but this just shows that you are doing something wrong. Yes, Redux requires some amount boilerplate code, but if you need thousands of additional lines of code for state management, then you are lacking code abstraction skills.


> Yes, Redux requires some amount boilerplate code

I think you're underplaying this. The Redux apps I've seen thread data through a great many layers - action creators, actions, reducers, sagas, schemas - and I think it's fair to say that compared to other projects, Redux apps have very long 'chains of operation' (I want to avoid value-laden terms like 'structure' or 'bureaucracy').

Is it worth it? I'm not sure. The Redux apps I've seen have used this 'highly formalized' approach to handle quite simple interfaces. Maybe I'd have different feelings if I was writing something bigger?

It's not that I hate Redux, or think it out and out 'sucks'; but I've worked on a lot of projects and first Redux ones I've worked on seem unusually difficult to reason about, and a few of my colleagues share my feelings. We feel like it is hard to reason exactly what an event or command exactly 'does', and that the diffusion of behaviour across files plays a part in that.


Ok, maybe I underplayed it a bit, and I certainly also had a different opinion when I started to get into Redux.

It is true that if you do Redux "by the book", as taught in the official documentation, then it is indeed quite verbose and confusing in the beginning. But once it makes "click" and you start to understand what the point of all these moving parts is, then it's possible to come up with thin abstractions on top of it to reduce the boilerplate. It would have been great if there was a common "standard" way how to do this, but on the other hand, having the flexibility and power to do things how you want, to make it fit your team and project, is quite nice.

For example, we never liked those huge switch statements in reducers. We just use plain objects, where the key corresponds to the action name, and the value is the reducer function. Not really a big deal, but it just shows that you have the freedom to lay out your Redux app however you see fit.

We also saw no real value in strictly splitting up actions, action creators and reducers among multiple files. We simply put actions, action creators and reducers that belong together in a single file.

And then there is the possibility to use middle wares, which can greatly help in debugging and tracing down actions.

So far everyone in my team is very happy with Redux (and React of course).


> We also saw no real value in strictly splitting up actions, action creators and reducers among multiple files. We simply put actions, action creators and reducers that belong together in a single file.

I think that's a much more pragmatic approach for smaller applications.


I knew this would trigger a remark ;) I'm absolutely aware of the importance of separation of concerns. And our SPA is not small.

I just became less dogmatic about it. We all have been taught how important it is to separate HTML/CSS/JS, but then came React along and put HTML into JS, many people were outraged, including me. I thought I'd never use that crap that violates basic principles of software design, but here I am and I'm loving it. In the context of UI it makes sense to me. Same with Redux.

Could you please give me an example in which cases you think it could become problematic to have actions, action creators and reducers in a single file? In an application that is not small?


Can we not agree redux requires too much boiler plate code but putting everything in the global scope is a bad practice for a variety of reasons.


Reactjs is dead simple until you introduce Redux.

I think applications can be architected that don't need it.


Isolation of state and transactional, external mutation of sate demonstrate correctness in exchange for (minor) boilerplate that, frankly, only looks complicated (and never should look complex, it's trivial) until you've actually read the code.

You can build an application without functional state management. Of course you can. But, frankly, you can't demonstrate conclusively that you know it's correct or where incorrectness stems from. Which strikes me as something of a problem, and one that does violence to the verb "architect".


>> Redux DevTools is immensely useful

If you use @ngrx/store, they can be used with Angular2+ as well.

https://github.com/ngrx/store-devtools


I don't know enough about React to say whether or not I like Redux, but I've written enough Angular code to know that Angular's lack of a good state manager is a problem. A lot of Angular apps end up storing an object in $rootScope that's treated like a global state, and that leads to weird side effects and bugs if you're not careful. Something like Vuex would be be a great addition to Angular.


Maybe I'm doing it wrong but when I (rarely) need state between components I just plop it into a global variable, of which there only ends up being s handful, and it's never been a problem. When I tried to use Redux first it burned my brain trying to grasp its architecture and how to write the various bits of code it needed, all replaceable with this.app.globals.foo=42


> ... $rootScope ...

Didn't you write AngularJS code then?

As the article riffs about at length, Angular (Angular 2+) and AngularJS (Angular 1) are fundamentally different.



In Angular 1 I have always used Services for storing state and sharing it between components. In the latest versions of Angular we have started using angular-redux.


Undo / redo is a nice to have? If you are building spa web front ends the right way these are essential. Using modals with OK/Cancel buttons to confirm actions is not ok in a web app. It should work more like you are editing a document in a structured way hence undo becomes a requirement. Trying to undo in a web app where state is stored inside components becomes a nightmare. Redux makes this a heck of a lot easier.


The prevailing opinion on HN seems to be that React is great, and monolithic frameworks are bad bad bad - especially Angular.

On a recent project I started for a client, we did a full evaluation of React + Redux vs Angular 2/4 and NGRX.

Angular's first-class support for TypeScript, and RxJS is incredible when leveraged properly. Integrate this with NGRX for Redux style state management, and you get a compelling solution that is miles ahead of the React/Redux combo if you can get over the template syntax (instead of JSX) and the opinionated flavour of Angular.

It's difficult to offer an alternative opinion in the HN echo chamber, but we're having excellent results using Angular CLI + Angular 4 + RxJS + NGRX. It's worth the steeper learning curve, IMHO.


To add to that, most new React/Redux projects are settling on the same technology decisions as the Angular team. TypeScript/Flow, RxJS for async/effect handling (or Sagas). React vs Angular is pretty negligible at this point. They are both component focused frameworks and that's the important paradigm and shared quality amongst all these frameworks.

Anyone who understands the architecture of one should be able to learn the other relatively quickly. I haven't personally used Angular 2/4, but it looks like a really solid and opinionated solution. Some people don't want to spend 3 days researching thunks vs sagas vs observables, so I'm glad something like Angular exists.


I am using Angular4 and am pretty happy about it. Especially I am happy of the fact that Angular is opinionated framework thus it is easier to work in teams on one project because there is usually just one way (angular way) of doing things instead of 100 different ways in React.

Also, author is praising features like rx, time travel, webpack but does he know that all these are baked in angular as well? ngRx is very solid maintained project that actually works with all time-travel debuggers. And webpack is built-in in every angular project.


I agree with this. It's a mistake to characterise this solely as Angular vs. React though. It's really about these things,

- Declarative UI as a pure function of state

- One way data flow

- Frameworks that use plain language features and functions, rather than template-like DSLs

No need for framework holy wars, but objective speaking these sorts of approaches are objectively the right future for UI development imo.


Angular is mostly a declarative UI. I don't usually put logic in my templates. I do, however, like how react leans towards using language features instead of abstractions.

Angular does one way data flow. It also allows for two way binding. The choice is the developer's.

So your argument boils down to using language feature over the template DSL. I think it's more important to consider state management, code reuse, and inter component communication (perhaps also a part of state management if using something like Redux).


I'm a mostly-backend dev that's been pressed into service on the frontend recently and I've worked on React and on Angular.

In my experience, I like the React way of defining components and functionality a lot better. The errors that Angular spits out from the HTML-templates are difficult to parse. There's also an unfortunate combination of a fractured community and incomplete first party documentation that makes Angular hard to ramp up on.

That said, Angular has a huge advantage that has made developing in it a lot faster for me. It's got everything right there. Angular doesn't have unique functionality, but it starts you off with a standard set of design patterns that stand you in good stead. React is just a frontend and when you're new to the space you don't know what else you need. Frequently, the productivity gain of not having to think about how to solve a problem is greater than solving the problem the "right" way.

Realistically, most teams solve this problem by having a senior team member who can pick technologies and design patterns. I haven't had that luxury on this last project, so I appreciate the Angular ecosystem. Javascript is great, but it's still very wild-west like.


How to get upvotes on hackernews: write yet another clickbait medium article on how bad angular is.

I don't think the OP has ever used Angular CLI or followed Angular development. If he had then he would have not written this article since a majority of his claims about Angular are wrong.


I moved to Vue from Angular 1 instead of React when I started a new project last year.

I regret nothing.


I'm in the same boat. Still, because I didn't learn React I don't feel qualified to say vue is better. I'm just happy enough with vue that I currently feel no motivation to learn React. That gives me concerns I'm working in "Blub" though. I'd love for someone who's used both to highlight differences.


I keep hearing good things about Vue. Do you know how it compares to Angular 2? More framework than library? State management built in?


The Vue guide has a comparison just for you. (might or might not be too biased, I don't know ng2) [0]

Vue deals only with the view layer. So I would't directly compare it to Angular. But the authors do give you Vuex, for Redux-style state management, and Vue-Router which does exactly that.

Alternatively:

- use a second Vue instance as an event bus. Bonus points as the Vue devtools list all the events fired. Makes it easy to debug.

- due to it's reactive nature, Vue let's you implement a single source of truth quite easily. [1]

- Using dynamic components, you might not even need a router [2]

Personally, I've tried to use the single source of truth pattern but quickly resorted to Vuex. It just resonates with me.

[0] https://vuejs.org/v2/guide/comparison.html#Angular-Formerly-...

[1] https://vuejs.org/v2/guide/state-management.html#Simple-Stat...

[2] https://vuejs.org/v2/guide/components.html#Dynamic-Component...


Most interesting pieces of vue are separate plugins. Ie vue-router for routing. I believe there's a state manager, but I haven't reached a level of complexity where I've needed to use it (I've got maybe 40 .vue components in an app which acts as a hub for IIoT units) Vue is just the V in angular's MVC, so there's definitely less to it. Using it with es6, webpack, .vue files, and vue-router has been a great experience.

That said, the other half of my job involves .net/c/assembly/tcp, so I always worry I'm a step behind on web dev because I'm not devoted to it full time.


React won and those of us stuck on Angular 1 are mostly fucked. From that perspective, you'd have to be absolutely fucking insane to even consider Angular 2 after how badly the Angular team fucked up Angular 1 and all its users, leaving them in the dust. It's not about tech. Tech is irrelevant. I cannot trust this team to stand behind their software. Maybe that's because they build really shitty software. Fool me once and all that ... but IMO, you'd have to be a fool to use Angular 2+ after this fiasco.


I purposely chose to build on angular 1 instead of angular 2 when I started a project about a year ago. I'm actually glad I did, because every question you have has an answer already on the internet. I think it's actually good to stay behind the times in a lot of ways, let everybody else work out the bugs, then jump on board once it's all working well. Of course if I started now I would go with Vue, which I think is what angular 2 should have been - faster and simpler.


Is your problem more with the lack of proper migration to Angular 2 or with the differences between 1 and 2?


My problem is that I don't trust the Angular team not to abandon Angular 2 like they did with 1. Angular 2 should have been named something else to avoid all this confusion around Angular 1's abandonment.


What happened to ng forward and co.?


It's hard to take this post seriously when this guy has barely 5 years in the industry.

If you're building a large enterprise app with lots of engineers not familiar with either framework, Angular 2/4 wins hands down.


Angular 4 is a few months old. It's not mature and the ecosystem is immature. Even the official Angular Material2 project is still in beta. You contrast this with React's ecosystem of UI components that have been built up over years...it's no contest. You can build better looking, better performing UIs with much less effort and they work great, even in IE11 and Edge.


How many years experience does somebody need before you will take them seriously?


I can't help but feel like all of these posts are a bit overly dramatized.

As much as people complain about Angular, I think it's completely fine for the majority of use cases at large scale. So is React. So is Vue. Even Angular 1 is fine. In practice I've never run into most of the issues people preach about. Two way data binding isn't the devil. One way data flow isn't a panacea.

My developer happiness has always been contingent on the quality of my coworkers, and not on the framework itself (all of which, I feel, are great in their own ways.)


Occasionally I have thoughts like these. And I often write them down. But rarely (never) publish because I am always hit by the idea that no matter how bad a certain framework/project is (especially open source), unless it's actively malicious, there are real people who are actually putting time and effort building and maintaining these projects.

There is absolutely no reason to dismiss all their efforts.

I can provide a critique and state my preferences for a certain framework over another without demeaning the project I don't find preferable.

The O/S


I stopped reading at

> mature ecosystem of tooling and libraries

That tells me the author is either blind or so lost in his world that he thinks this is actually true.

This fanboyism around languages and frameworks is apparently ever-growing. Haven't we learned by now that everything is about trade-offs and there is no One True Way?



Though I do think Angular 2/4 is inferior to React/Redux combo this article is very biased and not good for a constructive discussion and comparison of those frameworks.


I strongly disagree with the claim that "React Is Much Simpler." React on its own may be simpler, but by the time you add libraries for routing, HTTP, dependency injection, date/currency formatting, animations, and all the other stuff that Angular provides out of the box, the complexity starts to look pretty similar.

Furthermore, because you have to rely on third-party libraries for all the features that React doesn't provide, you have to worry about separately keeping them all up-to-date. What if there's a critical bug fix in the latest version of your HTTP library, but it's only compatible with the latest version of React, which isn't compatible with the router version you're using? In my experience it takes a lot more time to keep dependencies up-to-date and working together with React than with Angular.


There are already browser standards for HTTP and date/currency formatting. At most you need a polyfill if you want to support really old browsers. CSS transitions also take care of most use cases for animations. A library for dependency injection is just over-complicating things. You don't really need it.

The only thing in that list that I have ever felt a need to use a library for is routing.


I doubt we will ever do React.

All the SPA projects at our company are Angular based and I don't see any plans to change it.


My experience with Angular is that it was sort of the gateway drug of SPA architecture.

Back in 2010-11 I first tried out Angular to experiment with the SPA concept. This was hard to reason with back in those days, as most client DOM was still server-generated (at least for initial requests). It was really a big paradigm shift for a lot of developers, myself included. I found that Angular's foundations (directives, services, controllers, etc.) helped to constrain my thinking in ways that made the SPA concept more clear. The angular ecosystem in those days was really a haven of SPA-oriented thinking that couldn't really be found elsewhere on the web.

Fast forward to now, SPA architecture is essentially the norm. Almost every web-enabled device now has a full javascript runtime. Additionally, it has actually become an anti-pattern in some cases to force server-generated DOM on the client, as each clients' JS runtime is usually better suited for interacting with its specific DOM quirks and handling device features.

Now that SPA has become a more mainstream way of thinking, developers have begun to seek out ways of implementing this architecture with fewer constraints (and arguably bloat) than Angular could bring to the table. Frameworks like RiotJS are starting to explode in popularity because developers still want some fundamental SPA-style framework, but also want to maintain the ability to interact with the DOM in a more direct and vanilla way. When working with Angular, I found myself constantly trying to find (or god forbid write) the angular-compatible directive wrapper for whatever 3rd party javascript component I wanted to add to my project. Being able to simply include something like moment.js directly in my project and use it exactly as their documentation indicates has been a massive productivity gain for me and my team.

I took a few cracks at Angular 2, but there was something that always felt off about the component system and how more complex pages were composed. Their attempts to bring typescript into the fold only served to confound things even further for me. I know this is a hugely-subjective thing, but it was basically the end of the road for my Angular experience. It took me 5-6 weeks to get my team truly productive on Angular 1.x. I was able to bring them up to speed on RiotJS in a single afternoon (the router being the hardest bit).


This article includes a statement I've seen several time before: "flux is more of a design pattern then a library or framework". This statement drives me to unspeakable levels of fury. What does that mean? It's like saying "Alvins ball is more a boulder in Yosemite than a mid century school of literary criticism". They're two totally different things!

Someone who understands the statement, could you help me? Does it mean that there is a design pattern so light that some particular library which implants it would be trivial to recreate?

Any answer, I beg you, please clearly distinguish between the very different concepts of design patterns and named code projects which implement them.


Having just seen a whole bunch of React shops when interviewing for a front end position, a _lot_ struggle with React but also really enjoy it. Definitely don't see a significant difference in the end from Angular, they're really similar frameworks.

I think the ones that really have invested in making React work in their org but move a _bit_ faster, but Angular making strong decisions and providing really good patterns out of the gate is extremely valuable.

Both are great frameworks, so adopt works best for your company, your team, and your product!


From the article:

> We can be almost certain that React & React Native are a competitive advantage. We can see evidence in how Facebook simultaneously launched Snapchat-like “Stories” across four applications (WhatsApp, Messenger, Facebook, and Instagram) in its product suite.

> It’s not hard to infer that React was a key reason why Facebook was able to do this so rapidly.

Is there any actual evidence that React / React Native was used to build the Stories feature for any of these apps?


No. And it's a fair point. I might be reaching a bit. But I do think Facebook sees real productivity gains from using React Native in production and those gains benefit their velocity as a whole.


At the peak of JavaScript fatigue in 2013

I don't think JavaScript fatigue peaked in 2013. FTA:

it is quite easy to maintain a large, flexible, well-engineered SPA with React, Vue, or other lightweight JS libraries, even at enterprise companies with large teams.

Vue's initial release was just over three years ago. Other technologies used by enterprise companies has usually proven itself for a decade or two. Articles like this don't help with JavaScript fatigue.


Front end technology has advanced rapidly in the last 5 years. You can't compare the back end as much. Although there's innovation there too from new languages and functional paradigms.


This article ignores the power of Microsoft backing Angular in ASP.NET as a first class citizen with typescript. Most companies don't care about what stack they use, and if their Microsoft partnership agreement offers free Angular + TypeScript training? Most companies will go with Angular if they don't have specific performance needs.


I'll just be the sad puppy sitting in the corner writing everything in vanilla es2016/17. I never had any problems and everything works. The amount of code I write is no more than the angular code I write at work. Never used react but it looks like a jumbled mess. Vanilla JS is pretty sweet and has everything I could ever need.


I'd agree that angular 2 was a letdown. Seems like most people are like me and like typescript, the cli, and a better router, but those could have been incrementally added instead of starting from scratch.

It still boggles my mind thinking about the massive amount of effort google's large team spent on ng2, library authors spend porting ng-bootstrap, plus every app that will be rewritten, plus the interim confusion of having 2 versions of libraries, documentation pages, etc. For improvements in some areas, more complexity in others. And I think to the point of the article, it feels far behind react in a lot of advanced development features as it is still trying to get a solid footing. Just saving a file and waiting a few seconds for a full page reload is much worse than the gulp then webpack browserupdate system I setup for ng1 apps, and the cli is not _that_ much better than a custom gulp task I setup to generate new components and services in ng1.

My theory is the primary motivation for ng2 came from the angular team not wanting to maintain a js and dart version of the library, so they wanted to move it to a single codebase that could compile from nativescript/typescript to both, and it was an easy sell to all the people who identify in the angular tribe.

Some specific things I don't like in ng2:

- Too many ways to do forms. Template driven vs reactive, with some things like mdAutocomplete I could only get working w/ reactive. You can do [ngModel] + name attribute, [ngModel]="name", [(ngModel)], formControl, formControlName. Little things like adding `Validators.required` isn't picked up by the view, so you have to specify required there too to get the little (*) asterisk in the view for mdInput

- Testing got much harder to do, with mocking every dependency. Just when ng1 made frontend unit testing pretty painless to do, it feels like a step back.

- The DI system in general feels like waaay too much complexity for the much smaller benefits it brings now that `import`s are available. I was reading the docs to try to figure out an equivalent to a factory function and I realized even if I could figure it out, another developer or myself in 6 months would not understand it. Mocking imports for testing would be good enough, I think.

- Unless you plan to be an "ng2 developer", dipping into the 100+ ;) rxJS observable methods is a good way to confuse your teammates or future self. Have fun remembering what mergeMapTo vs switchMap vs forkJoin do. Observables are cool, but imo another case of too much complexity and too many ways to do things for the benefits. I haven't seen good guidelines of at which point in your app do you transition from observables (returned from http request) to plain objects - should you pass observables down through components for things that can change, or rely on the component seeing its input property changed? Should I implement a snapshot property on my objects that can change, similar to how they do routes? It is silly to me an http request response is modeled as an unending sequence of events, instead of a promise. The only benefits I see like being able to specify `retry(3)` could be implemented as an option in your api service that wraps http, and would probably be more consistent that way.

- A lot of small things are gone, like a capitalize pipe, ngFor iterating over objects. A little slower when getting started on an app when you have to add them yourself. They got rid of things like http interceptors and route resolves, and are adding them back in now after people complain. Even stuff like adding a query param to a url required a bad java-like api and multiple lines of code. They improved that since, but why start w/ a step back from ng1?

- Speak of route resolves, they have gone from a simple 1 liner in the route definition to being a 10 line standalone service, which you have to import and add to your providers array.

- Hasn't been an issue for a while, but having your global ng-cli which housed the webpack and typescript config(?) go out of sync w/ your local version, and your angular/core version, was a really confusing and painful upgrade.

- I like typescript, but it does have strange errors where it seems to have an older version of a file cached and you need to restart the server to fix it. Seems to happen more when importing a class that isn't @Injectable()?

- It is slower. My livereloading browsersync ng1 apps were faster and more fun to work on.

- It is a huge pain to rename things or reorganize your files. VSCode was rename symbol which is nice, but to stay consistent when renaming a component you need to rename: each of the 4 files+directory, all the imports, the `selector` and all tag references to it across the app, the `.my-component` css classes. I do a lot less refactoring of component names or directory structure in ng2 than a glob import style ng1 app, where you don't need to manually requiring everything.

Hmm, maybe should write a blog post about this.


> It is slower. My livereloading browsersync ng1 apps were faster and more fun to work on.

Wasn't performance meant to be the whole raison d'etre of the rewrite?


What I'd like to see is really mostly for them to just keep maintaining Angular 1.x. I don't care about "microlibraries;" I want a sane set of components that work well together, even if they're not all necessarily the absolute best in class.


I'm hoping Polymer 2 will gain more traction. Anyone out there hoping for the same thing?


I am. React is nice for consumer product development, but I think Web Components and Polymer will be much more effective for line-of-business and back office applications.


It is gaining traction - almost 8k users on slack channel stedily growing - new components are getting released on webcomponents.org every day.


I somehow find the dependency management system of Polymer 2 (loading script tags in a component), is going back to the old school ways/days. There is no dependency isolation, modules are loaded to the Global... v.s. ES6 imports via webpack, for example. Granted, module imports are not browser ready yet. Guess we'll just have to live with it for now.

Happy for someone to point out a better way for Polymer 2 dependency management that feels... less dirty.


> Two way data-binding was a feature in 2013 and Facebook said it was a bug. It turns out they were right. Ember, Angular, Vue, and others would later adopt the one-way model.

No, they weren't. It's just a different way to manage state. And VueJS employs two-way binding so I'm not sure what was the intent here.

> Redux brought predictable, functional, maintainable state management to JavaScript.

Stopped reading here. Too sensationalist.


>And VueJS employs two-way binding

Two way binding is an anti-pattern in Vue. https://vuejs.org/v2/guide/components.html#One-Way-Data-Flow

You actually get console warnings if you try to affect state in that manner.


That's about parent and child components, not about the state of a particular component. VueJS keeps two way data-binding between the template and the component; react does not and needs to handle events from jsx (or whatever one is using as template) explicitly.

And making child controllers directly alter the state of their parents is generally thought as an anti-pattern in angular 1 too, as far as I understand.


Thanks for the clarification but I'm still a little confused.

>VueJS keeps two way data-binding between the template and the component

In what sense? If you need to update your data on the JS side from the DOM you have to use events. There's v-model, but this is just syntax sugar for binding an event on input to update the value prop.


> In what sense? If you need to update your data on the JS side from the DOM you have to use events. There's v-model, but this is just syntax sugar for binding an event on input to update the value prop.

Which is why calling two-way data binding in js a "bug" is so weird (for lack of a better word). In angular, two-way data binding is, ultimately, also syntactic sugar over DOM events.

For that matter, everything every frontend framework provides is syntactic sugar over vanilla javascript.


All I'm saying is that Vue doesn't do two way binding. v-model translates directly into a DOM event, ie

<input v-model="someProp">

is equivalent to

<input v-bind:value="someProp" v-on:input="someProp = $event.target.value">

Which, as far as I understand, is exactly how React handles it and is deemed one way binding. ¯\_(ツ)_/¯


We seem to be about to start going in circles so I'm cutting here with one last remark: For what it's worth, in Angular one can also make the events explicit, and yet in there it is called two way binding.


Vue has one-way binding. Children can't force a parent to change state, only suggest through events.


Chocolate vs Vanilla argument here

    while(true){
      if(dislikeAllCurrentFrameworks?()){
        inventNewFramework()
      }
    }


This is why I like Aurelia, its much lighter in terms of speed and amount of code, while still being a fully flared framework like Angular. Sure theres React/Redux Vue/Vuex but why do that setup when you can literally go au new hit enter about 4 times and your app is ready to code and build.


Article is basically why use React over Angular.

One thing though - Facebook succeeded because of the sheer amount of money plowed into the team. Our team is succeeding with Angular at the moment and feel pretty strong that it solves our front end rather splendidly.

Disclaimer - I do like React, it has its place.


[flagged]


whatever you say grandpa


You ungrateful little shit. Don't come cryin' to me when it all blows up in your face. waves cane




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: