Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I vividly remember 2016. I was doing backend programming at the time, but no one I knew were using Angular.js at that time for new codebases.

React emerged in 2013, by 2014 the hype was at full swing, and by 2015 React "won" the framework battle.

It's been 5+ years since then, and React JavaScript world was remarkably stable. Fashion changes were largely superficial: React.createClass vs ES classes, Heavy use of Decorators vs not using them, and now Hooks. These were mostly cosmetic choices, and if your team picked the wrong side they could migrate over relatively painlessly or straight up ignore the issues for years.

On the other side of spectrum we have Ember that maintained backward compatibility and ease of upgrades since ~2013, Angular 2+ is doing the same for many years, too.

The whole "JavaScript fatigue" meme has to go.



Yeah; I think your timeline is off. I don't remember React being the very clear choice until probably 2017. It was still up in the air in 2016, and certainly moreso in 2015.

> by 2015 React "won" the framework battle.

Things have calmed down now. Its better, and has been for a couple years (not 5+ years). But, this isn't a battle. Its not a war. Just because things are calm now, doesn't mean they won't go crazy again.

The core of the issue has nothing to do with technology, or the frameworks, or programming languages. It has everything to do with how you, I, and Dave, who's reading this right now, respond when these new technologies come out. Just. Say. No. Play with them. Build toy projects. Give feedback. But for the love of God, at the end of the day, you Say No. No, we will not be integrating this. Looks cool though, we'll circle back in a year and see what progress you've made.


Either way the article is way off:

> Let us quickly travel back in time to 2016 ... If you are using a JavaScript framework or want to use a framework, Angular.js is probably something you would choose

Angula.JS was in the "failed experiment" category by 2016. The announcement that Angular2 was a rewrite (in 2014) was proof of that.

So in 2016 Angular was still really new and React had eaten AngularJS's market share.


I completely disagree, at least when it comes to my surroundings.

In 2016, the vast majority of recruitment offers I received were Angular, or jQuery/javascript. And while HN (thankfully) was all about React and whatnot, this situation continued for a good few years. Angular was the safe choice which I guess the PM's wouldn't get fired for. I remember many, many conversations with various recruiters where I told them I refused to do Angular projects, but I'd love to work on a React or even 'vanilla' JS project.

I'd say that after React became 'standard' on HN (around the time Vue popped up I suppose?), it took at least 2 years before I started getting emails and calls from people looking for React work.

Currently hoping this will happen with Elixir but not getting my hopes up :). Still, not having this sword of damocles hanging over my head that 'maybe I should learn Angular' is real nice.


"I don't remember React being the very clear choice until probably 2017."

Maybe you werent paying attention then.


CSS Modules didn't become the default way to go until sometime in 2016. Before that point people were still stumbling over how to manage their CSS in a component-oriented fashion, and it was only once that happened did React "win".


CS Modules are still not the "default", this space is still up in the air. There's CSS-in-JS (like styled-components or Emotion), Sass, plain CSS, etc.


They're at least compatible then.

More important to my point, back in 2015/early 2016 and before, you more likely than not had to somehow manually include the CSS for a given component library into your page. Right about the same time CSS Modules got popular, the CSS from libraries started getting included automatically in the compiled CSS file (whether by way of CSS Modules or something else that at least doesn't conflict with it).

I remember this part of the timeline pretty distinctly because late 2015 is when we started a new project in React, and struggled with how to reliably deal with CSS for several months.


Even utility CSS like Tailwind is gaining popularity...


It wasn't in many places even until 2018 at least. HN isn't the real world.


You are overly optimistic with the timeline. No, React had not "won" by 2015, not even by 2016[0]. Also the burn of more than half a decade is very real, both on developers and in codebases.

[0]http://2016.stateofjs.com/2016/frontend/. From that link:

> What's more, there's just so many options: Do you use React or Angular 2? Do you really need Webpack? And what's this month's recommended way of dealing with CSS?

> Like you, I spent far too many hours reading about all this, and at the end I still wasn't sure. So I decided to create a survey to see what everybody else thought. It seems like I must've hit a nerve, because I got over 9000 answers in just over two weeks!


From that survey, is you look at positive (would like to learn + would use again) vs. negative responses (not interested + would not use again), it looks like React is crushing everything outright. 85% positive / 15% negative. Amongst the other frameworks, the only one without at least 50% negative response is Vue at 43% positive / 35% negative, with a heart "never heard of it" segment as well.


Who cares what developers 'like to learn/use' when in practice they often don't get to, or get lucky and their preferred approach/tech is considered 'safe' a few years later?


You make it sound like we're all using React and that's all there is to it. That's not quite true, and it's just one of the choices you have to make. So you've decided on React, but what about state management, transpilation, do you use GraphQL? What am I doing for styles, should I write them in Javascript too now? Oh no! Webpack isn't for me! Can I use modules yet? Ah bugger, we need SSR, suppose I should have managed state the "Right Way (v28.6)", doh!


I even got fatigued reading your list of choices and you even missed critical choice such as flavor of SSR.


Excuse me, it isn't a real frontend without a service worker and offline capabilities.


Just use Next! I mean Nuxt! I mean really just give up and go for Phoenix LiveView or TurboLinks or Blazor...


Rewrites only make sense if you get a multi-fold improvement. In the history of computing, that's rare. So they rarely make sense.

Well, JavaScript was really horrible when it came out. It was just about the worst major programming language ever made. It sort of reminds me of an interpreter I threw together for a programming language I invented when I was in high school, when I really didn't get any aspect of programming language design, and I based it on a misunderstanding of Lisp.

Given its central role, lots of people used JavaScript, and lots of smart people tried to fix it. Every few years, it'd get a lot better. It actually made sense to rewrite everything -- you got that multi-fold improvement in productivity going 1995 JS to 2000 JS, 2005 JS to 2010 JS, and so on. I mean, with each iteration, it was still obnoxiously bad, but it was that much less bad.

It looked like an exponential growth curve for a while, but you always knew it was an S-curve -- you hit an inflection point when you reach the level of competently-designed programming languages.

At some point in the past five years, JavaScript stopped being really bad. I mean, it's no Python, but it's at least within spitting range. Heck, it's better than Java. I won't even lose 2x productivity writing in JavaScript over best-of-breed languages, at least core language (ecosystem aside -- there is no numpy/scipy/pylab -- but that will come too).

With that, rewrites every five years no longer make sense. Unless there's some fundamental progress in computing, I expect JavaScript code I write today may still be used in 20 years. That's not something I would have said in 2010 or 2000.


How about using Typescript? That still seems like a huge improvement, especially because you can implement it incrementally (aka for parts of code where type checking is vitally important).

I'm using it now at my work and I'm surprised how much info I'm getting compared to whatever JS is throwing at me.


TypeScript? Erm... Not for me.

There were many such systems in the past. CoffeeScript was a big improvement over 2010 JavaScript. Before that was GWT, which was sooo much nicer than 2006-era JavaScript. I could list a bunch of others. If you used any of them, you're now stuck with a legacy system(+), and you'll find fewer and fewer people able to read/write your code, and otherwise.

I'm also not a big fan of static typing. And if you do static typing, you should at least do it properly, which is not what TypeScript does.

Types should be things like "This is an integer between 0 and 100," "Meters/second," or similar. We've known this for a long time. Ada is now 40 years old and was mandated for military work since if you added feet and inches without a conversion, that was a problem, and that resulted in more robust systems (TypeScript would make them both of type "number" and never catch the error). If you tried to have 120% of your fuel tank full, you'd violate an assertion as well. Those were turned on in dev and in your test suite (but generally turned off in your deployment system, which was running on a 33MHz CPU if you were lucky).

C++ templates let you define things like "This is a list of lengths, in meters." Duck types languages like Python won't do this statically, but it's easy enough to do dynamically; while you won't catch errors at compile-time, at run-time, you'll get a clear exception.

(+) Standard disclaimers apply.


Dependently typed language can check at compile time if you violate a ranged integer value among many other things.

I'm curious though why you are not a fan of static typing? I feel like if you have a language with inference it's pretty good. I mean you could imagine python with type inference and you could essentially write anything in it you can today (baring stuff like heterogenous data structures) without specifying the type manually.


(1) I like generic code which I can use as I see fit later. In Scheme, I can write:

(lambda (x) (* x (+ 3 x)))

A half-decade later, someone can take that code, pass a pair of specially-crafted objects to it to introspect what it does, and take a symbolic derivative, pretty-print that derivative with LaTeX, combine it with a few other pieces, and compile it into native code (and yes, that does happen).

But a lot of my code is generic in a way where types get in the way.

(2) If I do have typing, the type should usually be specified manually, but it should have semantic meaning, not be based on inferring whatever types my programming language happens to have built-in. What's important isn't that something is an integer, but that it's a count-of-apples. I should be able to compare a count-of-apples to a count-of-oranges without first converting them to a count-of-fruit.

This is especially important for numerical code, and especially in education. A lot of Scratch tutorials have little kids add a velocity to a position, without first multiplying it by a time. That leads to deep-rooted misconceptions.

I don't mind type inference if it's designed to give me feedback. I've seen a few systems (designed for students) which do things like take JavaScript:

let x=5;

let y="hello";

let z=x+y;

And flag that in the IDE. That's kinda nice. And obviously, many systems do optimization at runtime based on inferred types. That's not a problem either.

So there's a fuzzy layer in between. But the discussion was about TypeScript, not that fuzzy layer.


I don't really see how the first example is incompatible with static types. Most often type inference infers the most general type possible. That means you can do exactly the same things with that lambda in a statically types language as in a dynamic language.

The second example with count of apples and oranges is bad. Those are unitless and a thus Just an natural should be fine for them. Numerical code can get messy but that's exactly were the power of static typing is the best. You can have dimensions and units in a type system and you get dimensional homogeneity correctness for free.


I agree that well-designed type systems can be helpful, and in an ideal case, I'd have a mix. It's just that TypeScript is not that. The gap between the types of type systems you're describing and TypeScript is the Grand Canyon.

re: type inference

Inferential type systems fall into a fuzzy zone between statically and dynamically typed. For example, many JITs for dynamically typed languages do type inference, and generate compiled code optimized to the types actually being used. That's a very obviously good idea. And many linters look at inferred types as well to do compile-time checks. That's also an obviously good idea. But I wouldn't call a JavaScript JIT a statically-typed system (or Python code that's been through Pylint).

re: Apples versus oranges

They're not unitless. In the first case, the units are apples. In the second case, they're oranges. You shouldn't compare or add those types. If I do have a type system, that's something I should be able to specify.

Not to mention implicit conversions, if I want them (12 inches + 1 foot = 24 inches).


Well yeah typescripts typing sucks but that's not my point. Type inference falls squarely in the static typing camp. It has nothing to do with dynamic typing.

Take a look at the Haskell units library. That can do the things you illustrate.


Typescript doesn't strike me as a multi-fold improvement. Dynamic vs static typing is an age-old debate, and in general, advocates can be found arguing that moving your code in either direction results in benefits. So, regardless of your stance on it, it seems unlikely to be unambiguously beneficial. Many large programs exist written in dynamic languages that do just fine.


It seems like it's trending toward static, at least recently. I think the big driver for this is the popularization of statically typed languages that aren't C++ and Java. A lot of people had painful experiences with C++ and Java and attributed that pain to static typing. It's now more clear that static typing is a net benefit, but it must be implemented reasonably and it doesn't solve other language design issues. Also, C++ and Java have each evolved some rudimentary type inference, which improves ergonomics (although I think excessive type inference a la Haskell actually makes it harder to debug issues--the sweet spot seems to be function-scoped type inference).


Hard to say. It seems as cyclic as anything else. Hard to tease apart real benefit from the usual fad/hype cycles.

Ruby, Python, Erlang/Elixir, Lisp/Clojure, etc, all doing just fine without it. (Some, with some lightweight annotative-oriented typing for a subset of projects.)

The best counterargument to static typing I can articulate is that in general, the only way to be sure software works is to run it. And so, ultimately you need to backstop your software with testing, QA, and observability infrastructure to actually execute it and validate it. At that point, the question is what marginal gains remain from catching a subset of those problems at complile time, also incorporating a potential a false sense of security which may lead to less actual execution validation, and more user-facing issues. The other potential tradeoff of static typing is if the software design and architecture changes for better or worse, or if the velocity of shipping changes changes. I believe there isn't yet any hard evidence of which way this tilts in either case.

There's also a lot of innovation in the area of validation-by-execution as well, and so I think that will result in continual debate: state-of-the-art static typing may benefit compared to yesterday's testing/fuzzing tools, but may not compared to state-of-the-art testing/fuzzing tools, for example.


Python is trending toward types via support for type annotations. My extensive experience with Python and Go leads me to the conclusion that it’s very difficult to write even moderately complex and maintainable Python code at scale. This doesn’t mean that no one can make money with Python—far from it—only that they would make even more money via Go (iterate faster and spend less time fixing bugs). Of course this can’t necessarily be extended to other languages. C++ and Rust would not be as productive up front than Python and C++ would probably not save you any time fixing bugs. A lisp might be faster to develop in than Go and Python without incurring too many type errors. There are too many variables to make sweeping statements, but all else equal, in my experience, static typing is better than dynamic typing. But again, there are many other variables that can cause a dynamically typed language to outperform a statically typed language for iteration velocity or bug reduction.


One of the greatest boons of static typing is formal documentation of data structures and interfaces. Catching errors early is a bonus :)


I'm not disagreeing per se, but at least in the Elixir community I get the impression that using Dialyzer (the wonderfully cryptic TS-ish gradual typing solution) and typespecs is increasingly advised and there's a thirst for a better solution. But static typing comes up a lot.

We're doing fine without, but it's definitely a sore point and I'm one of those developers who has become more and more fond of static typing.


The trend toward static typing is a fad, like NoSQL in the early 2010s. Who knows what the next fad will be. Perhaps correctness proofs will make a comeback.


Yea, this is why I posted it. To me it seems:

- Small codebase. Fine, use both.

- Medium codebase. Fine, use both.

- Large codebase. You're definitely going to have some typing bugs with dynamically typed languages.

- Humongous codebase. You're definitely going to have many typing bugs with dynamically typed languages.


I'll say that we have a small-medium code base and we see lots and lots of dynamic typing errors in production every day. I would also say "even though we have lots of people who are experienced Python developers", but I think it's actually because we have so many developers who have only developed seriously in dynamically typed languages and don't "think in types" if you will.


Can’t you write the Python functions to force check the input parameter for its type? And error out if not.

This should enable you to catch most errors immediately during development.


No, this doesn’t help at all. You only hit these errors if you run those paths in your tests, but those paths would already error downstream. Those paths that weren’t tested may still contain errors that go to production, and again you just hit your new type error instead of the downstream type error.

What you need is something that can help you test more paths, and static type checking checks all paths. Further, they can check all paths without writing any tests (you should still have tests, but you need fewer with a static type system to keep your bug rate the same). Moreover, static type checkers catch errors almost immediately, so you get feedback about your errors sooner rather and more frequently, so you spend less time investing in code that will have to be rewritten. Lastly, they put rails on the code—it’s harder to write bad code including gratuitously magical or abstract code, so your coworkers aren’t writing as much bas code that you have to interface with. If you find static type systems to be frustrating, you’re probably the problematic coworker. :)


I don’t disagree with you. Python seems to encourage poor development practices. Basically, anything goes. This can be problematic if you use other people’s libraries, and if their libraries are not fully vetted.

This is not a Python problem, per se. It is a developer problem. It is a human problem.

However, with your own code and libraries, you can enforce your own rigor. Keep your functions smaller, test all the inputs, and validate all the outputs. Although you may end up with smaller production code, but more unit tests.

The unit tests are good, as they give you evidence that you did cover those corner cases.

However, the good thing, is that if the functions are smaller, and well unit tested, then it becomes rare that you have to modify it at a later date. And especially if you think through all the different angles, and try to future proof it. Now you have the ability to do functional composition. Just keep chaining the outputs of one function into another.


Yes, but easier to just write tests.


And easier still just to use static types.


Often not, if the overhead of adding them outweighs their utility for the project.


well, sure. certainly one of the costs of a dynamic language is the possibility of typing bugs, and those will likely grow linearly with the size of the code base.

the question is if those programs were written in statically typed languages, how the world would differ, in-full. for example, they may have been built faster or sloer. or they may have better or worse test coverage, affecting severe defect count overall. or you may have had to hire a different team, with tradeoffs. hard to say.


I would avoid doing state management in Typescript. It's still too early in my opinion.

Use as many hooks and context as possible and keep your redux store as simple as you possibly can because if you end up with a deprecated state management library (redux-thunk, sagas, easy-peasy) replacing that is like pulling gum out of hair.

If you add up the time spent working around typescript errors when dealing with state, it's possible for it to be more time than you need to rewrite the entire app.

For backend work then yes, I'd say doing a singleton or an abstract class in typescript makes more sense in hardening your API code and even making it more readable too.


I'm a Redux maintainer, and I'm _strongly_ in favor of using TypeScript for any meaningful app development [0] [1].

Also, I don't know why you're referring to thunks and sagas as "deprecated". Thunks are the recommended default approach for async logic in Redux [2], and we include them out of the box in our Redux Toolkit package [3]. While most apps don't need sagas, they're a great power tool to have in your toolbox. Neither of those is in any way "deprecated".

[0] https://blog.isquaredsoftware.com/2019/11/blogged-answers-le...

[1] https://redux.js.org/style-guide/style-guide#use-static-typi...

[2] https://redux.js.org/style-guide/style-guide#use-thunks-for-...

[3] https://blog.isquaredsoftware.com/2020/02/blogged-answers-wh...


Sorry I meant as in an older version of a library that an app has been built on and hasn't been updated or maintained for a few months.

I should have put that better, the libraries themselves are not deprecated, their dependencies can be.

While this negligence problem would be on the fault of the dev team and management for not doing regular package updates it is an all too common issue in many companies.

What I am saying is that bad typescript is harder to fix than bad javascript because type errors compound the problems of convoluted code.


In my opinion, if you're going to add a compilation stage to your bundling anyway, you can get far more mileage out of other options (such as Fable) than the tiny improvement TypeScript is.

The additional compilation complexity is not worth the small benefits of TypeScript, in my opinion. An even better language, though? I'm in.


Never heard of Fable, will check it out! :D


Typescript greatest features are optional types and the extensive type inference. On small projects this can work well, but on larger ones I can see overly rigid style guides requiring typing everything explicitly in triplicate becoming cumbersome in an Enterprisey way. Curious what people's experiences are.


Typescript, for me, makes JS jump from 'good enough' to 'might use it even if I have other options'.

I still prefer using other languages when I can (back-end), but hypothetically, if I had to choose between Ruby and Typescript I'd actually go for the latter. And I like Ruby!


Typescript is leagues ahead of Python. Types and async/await are the big ones, but destructuring, no lambda weirdness, optional chaining, nullish coalescing, proxies, JSON support, and generally debugging tools are all better.


I'm not well-versed in TypeScript, and I have plenty of frustrations in Python so it's not that I don't believe you, but I do have a few questions:

* Python has async/await. It's not as pleasant as goroutines, but it exists and is presumably about as pleasant as async/await in TS, at least assuming you're using or not using the type system in both cases.

* Python has tuple/list/iterable destructuring. What is the specific limitation here? Maybe key/value destructuring?

* What's python's lambda weirdness? The single expression limitation? I agree that's tedious, albeit you can do a lot with a single expression (but not handling exceptions).

* JSON support. What's wrong with Python's JSON support? I mean, the type system can't model recursive types yet and that's super annoying, but the JSON stdlib seems fine. JSON maps pretty neatly onto Python dict/list/str/int/float/None/etc types.

* What are proxies and why are they desirable? Genuinely curious.


Python has some async, but it never felt as core and easy.

Tbh, it’s been years since I’ve done much Python. But the last time I did it was just really clear that TS had leapt ahead. Ecosystem may be part of it.

Proxies are essentially meta programming tools, tbh not fully sure Python doesn’t have similar but on looking they don’t seem as intuitive.


As previously mentioned, I'm a Python critic, but it has changed a lot since you last used it. Async (for better or worse) has gained a lot of traction as have type annotations (although the type checker is a huge pain--can't model JSON or any other recursive type, can't express a callback that takes kwargs, getting it to acknowledge type stubs on upstream libraries is a forbidden art, it's pretty slow, etc).

No doubt that TS is better, however. It has amazing engines, an MS-backed developer experience, coherent type system, not the worst package management ecosystem, etc. If I could switch us off of Python to any language, I would choose Go but I wouldn't be angry if we landed on TS.


Proxies are a feature in ECMAscript that TypeScript inherits - it lets you substitute one object for another so you can intercept and override object properties.


Having used both Python and Typescript recently, I largely prefer the consistency of Typescript. [Hey mom, I like cherries better than strawberries]. Having said that, I'd love to have named function arguments in Typescript. Props workaround is, well, a workaround.


100%. Normally these articles are thinly veiled attacks on something that has changed in the author's coding ecosystem that has angered them. When I saw hooks in the first few paragraphs I assumed it was going to be a "hooks are bad, mkay" article. It isn't, but still some what vague on actionable points or ideas.

Ultimately no one likes rewriting code and is typically under-estimated since developers mentally trivialize previous work rather than a greenfield affair.


Yeah I have to say I agree. I think there was valid reasons for some of the framework churn early on (basically no proper standard way to do client side GUI). When the MVC-oriented stuff started to stabilise we all discovered that functional reactive programming UI was a good thing and that drove stuff like React and Angular 2.

But there simply hasn't been a paradigm shift in UI after that (and I doubt there will anytime soon, it's not often a whole new UI paradigm that changes stuff the way MVC and FRP have done is popularised).

Stuff like Vue and Svelte are simply attempts at optimising or improving the reactive approach, but is basically still fundamentally the same idea. Someone versed in React would easily move over.


What do you mean, everyone is now updating their codebases to remove redux, HoF and switch to hooks.


No, people are realizing that they were just using redux as a caching layer and the boilerplate associated with it wasn't worth it when there are better approaches to caching local data now.


Out of curiosity what are the better approaches to caching local data? The only thing I'm aware of is something like Apollo client but .. that only works for graphql.


react-query, swr


I disagree. Redux has a lot of icky boilerplate, but the Flux pattern, and variations of it, are useful. You're either using Redux, something like Redux (context hooks, possibly), or you are passing single variables through 3 or more layers of spaghetti.


There's truth to both these statements.

If the only thing you're doing with Redux is just fetching and caching data, and nothing further, there are other tools that are likely going to be more ergonomic for that (Apollo, react-query, SWR).

However, if you're actually _manipulating_ that data after it's been fetched, or working with more complex client-side state, the Flux architecture really becomes useful. As the Redux docs FAQ entry on "When should I use Redux?" says [0]:

> In general, use Redux when you have reasonable amounts of data changing over time, you need a single source of truth, and you find that approaches like keeping everything in a top-level React component's state are no longer sufficient.

(We also have additional guidance on when it makes sense to put any given piece of state into Redux [1], and I'm adding more guidance on this sort of topic as I work on rewriting our docs.)

Beyond that, our new Redux Toolkit package [2] has been specifically designed to eliminate most or all of that "boilerplate" concern, and provides a set of utilities that simplify most common Redux use cases. We now recommend it as the default approach for writing Redux logic, and I'm currently working on a new "Quick Start" docs section [3] that will teach it as the right way to use Redux for beginners (alongside the existing tutorial sequence that teaches how Redux works from the ground up).

Related to this, while I've been very reluctant to try to build any type of official Redux-based query/caching solution, we _did_ recently release a new `createAsyncThunk` API [4] that simplifies the process of dispatching actions while fetching and a `createEntityAdapter` API that handles some normalization [5], and I _am_ considering trying to add some more involved abstraction to RTK in the near future [6].

[0] https://redux.js.org/faq/general#when-should-i-use-redux

[1] https://redux.js.org/faq/organizing-state#do-i-have-to-put-a...

[2] https://redux-toolkit.js.org

[3] https://deploy-preview-3740--redux-docs.netlify.app/tutorial...

[4] https://redux-toolkit.js.org/api/createAsyncThunk

[5] https://redux-toolkit.js.org/api/createEntityAdapter

[6] https://github.com/reduxjs/redux-toolkit/issues/603


What do you believe people are replacing it with? Hooks?


Hooks isn't a replacement for Redux though. It enables you to build state management in an easier way, but Redux is not just holding state, it describes the change of state


I have to chime in as someone who created an Angular.js app in 2017. I suppose it happens. Not that I actually wanted to, I was just working with a dumbass who overruled me. I don't really have anything it say, I just have a really strong negative association with this specific topic, I guess...


You are not the only one. It is just a question of personality, some people feel comfortable in Angular world, most people are like you and me.


It's probably not that angular is dumb - using angularjs 1.x in 2017 is dumb. And I do concur as someone who also wrote angularjs app at that time and eventually left the company over it.


Angular(1) wasn't simple but knowing basic stuff made it possible to do complicated things quickly. Angular lost a lot of momentum when they decided Angular had to look like JEE and become a framework trying to justify its existence with complexity.

React had the right idea, just make view management simple, don't force some bullshit IoC container on Javascript and that's it. If you want IoC that's your problem.

Ultimately the problem is that nothing replaces React natively in web API. A tool such as React shouldn't be useful anymore and Web Components isn't as ubiquitous as it was envisioned to be. In fact, I've never worked in any business that used Web Components.

But the biggest issues are on the node.js side and all the complex pipelines put in place in order to fix front-end development. In fine, the tools that will be successful are the ones that will still be actively maintained 5 years from now, and most of the libs/projects will not.


I see it a little differently, Angular 1 lost momentum because it was a bad framework. It was clearly written by people that did not have a lot of experience productionalizing code. Further they choose new and convoluted naming for concepts that already had names. The came up with a creative new way to introduce globals thru rootscope and performance was abysmal. Their component model was leaky at best and the whole framework encouraged writing monolithic controllers that where in the same vain of Backbone.js. There where actually good frameworks at that time such as Dojo they just did not get the mindshare that Angular got and a lot of that was due to it being incubated at Google. The second part of the issue is there where not many people doing hardcore Javascript programming and so there was not a depth of deep CS knowledge in the front end space. It took more and more of them reluctantly converting over, getting one look at Angular and going look guys this is bad because of X,Y and Z. Angular 1 actually set the state of the art back compared to some of the other offerings at the time. The absolute tell, was when the team had to admit it, admit they where going to scrap it for a total rewrite that was to become Angular 2 and on.

The reason React has done so well, is that core team members had deeper CS experience, understood other paradigms for UI development and understood that the best state of the art for UI right now, is a render loop. If you converted it to C, squinted at it long enough you would see the very old, very tried and very true Windows render loop in it. They took a proven pattern, bolted it to the virtual DOM and brought it to the web. They did not perform miracles, they stuck to what has been proven to work. Well the virtual DOM was a pretty clever hack, but the rest is UI dev 101. The problem was most the JS developers at the time, never had that back experience of desktop UI development and a good deal of them had come to development by way of learning HTML, CSS and then bits and pieces of JS as they needed to.


I don't think hooks are a superficial change. If react stayed with class based components, I'd agree with you.


I agree for frameworks, but building tools and package management are still nightmares for me


Agreed, but I wouldn't put 2015 as the year React "won". It did "win" the SPA frameworks war, but back then the default for webdev was still non-SPA and React was competing with jquery/"no framework" and the rest of not-quite-spa frameworks like backbone, ember, etc. Nowadays React is the standard, I dare say even for SSR sites!

The javascript framework fatigue meme was born during the early days of ember, backbone, angular 1, knockoutjs and meteor. Sometime between 2016 and 2017 was when it should have been put to rest.


But how long was Angular in vogue before React? If it was also ~5 years then a shift in frameworks every 5 years of calm + 2 years of chaos still isn't ideal.


People were still writing CoffeeScript in 2015.




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

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

Search: