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

Early react team member here. The popular react/webpack/npm stack is probably what the OP is talking about. It was popularized because the Instagram web team used webpack and npm in 2013 so we recommended it alongside react in the early days. I was TLM of the team when we made these decisions.

There are three main points I want to add to the conversation.

1. UIs actually have a lot of complexity. The number of states they can be in is often higher than what you see in other disciplines of software engineering. They also have to contend with managing data fetching over unreliable networks, including balancing bundle size. Additionally they are notoriously hard to test because “does this feel right to a user” is hard to encode programmatically.

2. The grass isn’t greener on the other side. I see a lot of people complaining about the needless complexity of the frontend stack but I don’t think they’ve worked in a modern backend engineering or data engineering project. Modern backend eng is a morass of kubernetes configuration, needless microservices and overuse of async queues, for example. Feels a lot like frontend in terms of accidental complexity. So I’d argue that this is less of a frontend problem and more of an industry wide thing (cynically, it might be a ZIRP thing)

3. With that said there certainly is needless accidental complexity in frontend and I am convinced content marketing is 100% to blame. An easy way to hire engineers is to create an open source project and write a blog post convincing people to use it. This is good for the company and good for the careers of the engineers who worked on it, but can cause people to needlessly complicate their tech stack if they can’t cut through the noise.



For me the reason for the explosion in complexity in both frontend and backend comes down to package managers on all platforms getting way better with transitive dependencies and lowering the cost of adding those dependencies. Developers used to be wary of bringing in another dependency just in case it created some conflict, but ecosystems that near-perfectly encapsulate transitive dependencies have gradually done away with that healthy wariness, with a combinatorial explosion in packages as a consequence.

Create-react-app installs 1500 packages to show a hello world page, and it is quite sane in its choice of dependencies. For me this is a symptom of the whole npm ecosystem being diseased with dependicitis.


Ironically, I think more dependencies are actually better, because it means they are smaller. "Do one thing well".

The problem is large dependencies depending on other large dependencies.

Dependencies should advertise their transitive dependency tree size including LOC per dep.

Also, the fact that every dep has it's own non-standard build process, language, dir structure, and ESM/CJS legacy support, makes things not ideal.


> Ironically, I think more dependencies are actually better, because it means they are smaller. "Do one thing well".

I could believe this if I thought that having 1500 dependencies led to less code overall, but the size of my node_modules folder shows that assumption to be flawed.

The other problem with this argument is that each dependency you add is another set of developers that you are depending on. It's another group of people who could suddenly pull a left pad or worse, and it's another group of people who you have to trust to have written secure code. The fewer dependencies I have, the smaller my chances of being exploited because of a people problem.


> Modern backend eng is a morass of kubernetes configuration, needless microservices and overuse of async queues, for example

That's certainly the trend. At my org, we "partnered" with AWS to help us figure out what the tech stack should look like. Sure enough, everything should be in an SQS queue, triggered off S3 running in AWS Step that's triggered through SNS notifications. All this requires countless lambdas which means deployments can last hours.

It's a mess to debug (meaning you can't), track logs, track status, etc.. Does all that "work"? It can, sometimes. Does it scale? For sure, theoretically, if you can get it all running.

In my team we use a trick to just run everything in AWS Batch containers, it's much easier, deploys quickly, and we can run the whole stack locally and debug it.


I worked at a company that did the same, and got the same answer. I hated that technical setup. Lambdas everywhere, Queues everywhere, microservices everywhere Exactly as you can said it was a huge pain to debug, and on top of that searching for code became a huge pain as it became split across so many different git repos, teams, and docs. And when you throw IAM on top of it all..... I am not a fan.


Makes sense that AWS would recommend these stacks (they are probably compliant with their Well Architected Framework), though the idea is to recommend something that can scale de facto infinitely with minimal SMEs required to run it all.

I agree that aiming for the simplest service your team can maintain is the best approach, scaling up as needed.


If you don’t need scale then keep things simple. :D


Few things.

About #1 there's Win32 API, MFC, WinForms, GTK, Qt, Swing and all do UI and thousands of applications are built with far more state and complex UIs than a normal SaaS, price comparison portal or a booking website ever could imagine - but none of those technologies are ascomplex, as bloated and as fragile as modern frontend stack has become.

Second - Backend complexity, Kubernetes isn't Backend precisely, async Queues are unavoidable but these Microservices are basically an anti pattern driven by greed to land the next Job and hence insistence on using different programming languages per team/indivual etc. Now a cottage industry in it's own right with it's own self proclaimed scholars whereas it is just and exactly the domain of distributed system already.

If that constraint of per team programming language of choice is removed or languages interoperate with zero configuration, 98% of the companies need just well maintained internal libraries.


Don't forget about resume driven development, though that ties in with marketing.


And companies that specifically are looking for <INSERT_FRAMEWORK> developers


This is usually responsible for bad code. Which, to be fair, is often associated with complexity. They are different, though.


Disagree on the first reason - I don't think actual application code and logic has anything to do with frontend overcomplexity.

My issue, and the reason I moved away from JS altogether and to Flutter/dart, is the massive amounts of redundant and complex tooling, choices, and concepts.

Webpack, npm/yarn, Typescript (TSConfig), package.json/node_modules, Babel, Prettier/ESLint, React, Remix, Next, Svelte, ESBuild, ES6/ES5/ES2020/ESNext, Tamagui.

Yes I'm mixing categories in the list above, but the point I'm trying to make is that with something like Flutter/Dart, there's only Flutter/Dart.

Even if there's some really cool new JS library that handles all of my application-centric concerns (namely, layout animations and good handling of shared types across n different apps/packages/services), I'll never use a JS library again because it will simply never be enough. I'm not going to use these band-aids anymore.


"It was popularized because the Instagram web team used it…" Twenty-five-year front end dev here, I don't recall anyone asking or caring what Instagram was using. Like, obviously projects of that scale make influential suggestions, but when Instagram says "we like This" and AirBnB says "we like That" then you have a couple strong condidates to evaluate.

IMO, the answer is more general: the modern web front-end evolved from lots of different directions. Instead of having one prescribed Correct way (a la AppKit, UIKit, Android Frontend Frameworks, etc.). If Netscape somehow still existed and maintained their peak of influence, things would be different.


/me remembers MFC/QT/BCGsoft and C++ codebase and gently smiles on thought that maybe the issue are everywhere else except the UI complexity.

We are where we are, but it is interesting that GUI libraries from 20 years back are still running circles around latest and the greatest UI web front-end, even if it is also client rendered.

Maybe, just maybe, we should search for an issue somewhere else?


As much as I hate modern frontend code, I question this narrative. What 20 year old GUI library is running circles around... anything?


Django, bootstrap and a sprinkling of jQuery works really well and results in simple code that can be maintained by a single dev. Bootstrap is only 11 years old. jQuery is 15 years old. Django is 18 years old.

jQuery is used by 94% of the websites that use JavaScript.

https://w3techs.com/technologies/overview/javascript_library


None of those are gui toolkits, though. At best, you are pointing to html working rather well at it. Though, that is more force of will from developers, as html was specifically not a front end toolkit at the outset.


You're comparing apples and oranges.


There’s another discussion going on about how the older layers of Windows you dig into, the more useful the UI gets, perhaps that’s the narrative they’re thinking of: https://news.ycombinator.com/item?id=34216619

I’m inclined to agree, older UI toolkits could make plenty productive UIs. But they aren’t good at following yearly evolving design fads, and webpages tend to lean heavily toward marketing and appearances over being more utilitarian.


Older toolkits were great at single team creations. This, interestingly, did mean the person making it knew exactly how to use test it.

I question whether the toolkits were actually better, or we just had fewer things to use test? Certainly fewer form factors. Granted, the decision to try and have a single code base for many different resolutions and such is, of course, questionable.

Edit: directly to the point, is it the old toolkits that made better tools? Are those same toolkits used today? Pointing at older tools does not show that the toolkits were better.


Is there a 10+ year old framework that does responsive UIs well?


What's the point of having a responsive UI?


Is there a younger one? :)


Yes, the web. Responsive by design.


I thought the challenge was for one that does it well? :D


Cocoa (macOS) for example


And what modern applications written with it are running circles? Legit question.


Almost all of the apps bundled with macOS are written in Cocoa (some are written in Cocoa Touch, which is itself a nearly 15-year-old framework). And a great deal of excellent third-party apps -- off the top of my head, Transmit, Pixelmator, Day One, the Omni Group apps.


The bundled apps feels like an odd claim. I don't think of many of those that feel modern. That said, I'm probably not thinking of the right ones.

Will try to take a peek at the rest of this list. I don't, oddly, use that many native Mac applications.


> I don't think of many of those that feel modern.

This is a bit interesting to me, which bundled apps don't feel modern to you? Mail, Notes, Pages, Safari... they all seem modern enough to me.


Mail has always felt like garbage to me. Notes, I will have to give a try again. Though, really, the entire "office suites" that everyone makes always feels off to me. I will full cede that that is just preference.

Safari feels off, as well. But I'm pretty firmly in camp firefox.

When I think bundled apps, I think of their notepad equivalent. The finder. The calculator. And... that is about it. I remember trying to make a script once, and that script editor left me very very lost.


There's always the option of a native client rather than a web-based client. A good example from days gone by is Evernote. If you've only started using it recently you might not know this, but the client used to be really good.


I haven't used QT or BCGSoft, but I for one have very negative memories of MFC. Sure the performance was much better than anything you get on the web, but the UIs were far less complex, didn't handle window resizing well/at all, handled text overflow poorly, and had much less aggressive design requirements than we have today. There was also a ton of imperative glue code and lots of hard-to-read generated code.


Less complex UI, interesting: https://bcgsoft.com/galleries.htm (psst, a secret, BCG is just a library on top of MFC)

Please DO open Word 97 (and this is 26 years old UI) and compare it with the best done web UI you are aware of, regardless of framework, as long it is not QT compiled into webasm (as this is the only thing on web that comes close).

Now why is that, I don't know. But I can tell you what I can see as a user. Web frameworks/developers/name_your_poison are doing a really, really bad job regarding UI.


My understanding is that none of the core Microsoft apps like Office were built on MFC. In MFC projects I worked on, generally the simple stuff was built with MFC and anything more complex was built with the win32 API.


Actually MFC uses windows api, but this does not change anything, it is still 1997 API. And we are in year 2023 with worse UI, i would expect it to be in reverse.

"generally the simple stuff", no:

https://docs.microsoft.com/en-us/cpp/mfc/media/mfc_heirarchy...

https://docs.microsoft.com/en-us/cpp/mfc/media/mfc_heirarchy...

https://docs.microsoft.com/en-us/cpp/mfc/media/mfc_heirarchy...

MFC had its set of problems which were related to things like passing messages between windows, but all those are on another level.


Agreed. Perhaps a bit radical, but we should get rid of GUI altogether and enforce that new applications should be command-line driven.


Further on the zirp idea, a lot of the explosion can be seen to correlate really well with team sizes. This gets into a feedback loop where you need bigger teams, which in turn means you will benefit more from segmented code. Which means you need more teams.

Not shockingly, the answer isn't a simple use fewer people. Rather, the amount of complexity in a codebase will vary based on budget and organization size. That is, there is no correct answer intrinsic to the code.


What is ZIRP?


Zero interest rate policies :)

Sometimes companies have too much money and they overhire.


I think you typo'd

Zero interest rate policies

https://www.investopedia.com/articles/investing/031815/what-...


Autocorrect got me! Thanks


zero interest rate policy, which basically means central banks do stuff to keep interbank interest rates very low (close to zero in the US, and it was even negative in the EU)

https://www.ecb.europa.eu/stats/policy_and_exchange_rates/ke...


>1. UIs actually have a lot of complexity. The number of states they can be in is often higher than what you see in other disciplines of software engineering. They also have to contend with managing data fetching over unreliable networks, including balancing bundle size. Additionally they are notoriously hard to test because “does this feel right to a user” is hard to encode programmatically.

Ok, reasonable, but other frontend Ui toolkits (eg. Vue, Svelte before Sveltekit, etc.) seem to be able to handle this without going "enterprise" levels of complication.

>2. The grass isn’t greener on the other side. I see a lot of people complaining about the needless complexity of the frontend stack but I don’t think they’ve worked in a modern backend engineering or data engineering project. Modern backend eng is a morass of kubernetes configuration, needless microservices and overuse of async queues, for example. Feels a lot like frontend in terms of accidental complexity. So I’d argue that this is less of a frontend problem and more of an industry wide thing (cynically, it might be a ZIRP thing)

This isn't a counterpoint, it is just pointing out that, well everything is getting more complicated. (more on that in a sec)

>3. With that said there certainly is needless accidental complexity in frontend and I am convinced content marketing is 100% to blame. An easy way to hire engineers is to create an open source project and write a blog post convincing people to use it. This is good for the company and good for the careers of the engineers who worked on it, but can cause people to needlessly complicate their tech stack if they can’t cut through the noise.

Ok, this is more to the point and gets to the real crux of the issue, but I don't think it goes all the way.

Every framework that has ever been adopted widely has been later complicated more and more to make it "enterprise-y".

Look at some early JavaScript (used to make webpage counters and fancy menus) and look at some modern Typescript, which is almost indistinguishable from enterprise Java and used as a basis for SaaS startups.

As soon as "professionals" get involved, it starts getting complicated. Every framework is susceptible to this if there is any amount of adoption.

Look at my beloved original Svelte. Now go look at the absolute shit-show that is the latest Sveltekit! (granted it is still better than the alternatives!)

To your second item above, look at how relativity easy it was to monitor or restart some monolithic projects back in the day with some simple scripts, email, and cron jobs, now it is, as you say, a "morass of kubernetes configuration, needless microservices and overuse of async queues". Literally make-work for the sake of itself in many cases!

Why?

It worked before, why is this necessary? It is the "enterprization" of everything and I agree with your third point that a big component of this is content marketing.

But at the end of the day it is more about the concept of "feeling professional". I mean, if you can teach someone how to program in JS in a couple of afternoons, how can you seriously justify $150k salaries and 3 levels of middle and project management to oversee such a thing?

The original canonical edition of this was JAVA. It was amazing seeing it go from where it started to the, almost satirical, levels of "enterprization" today. The modern version of this is JavaScript.

In both cases complication was added to make it more "serious" not necessarily to make it any better.


Every decision is a trade-off. If you call TypeScript complicated, what do you call maintaining a 1000+ component-based web app without types? Please try to understand that every decision is a trade-off. Also, all the major frameworks default to non-TypeScript documentation, so nothing is getting more complicated.


>Every decision is a trade-off.

Sure, the problem is that people are making the trade-off without justifying the decision.


> Ok, reasonable, but other frontend Ui toolkits (eg. Vue, Svelte before Sveltekit, etc.) seem to be able to handle this without going "enterprise" levels of complication.

I've used Vue (2.0) and React extensively. I find them to be pretty equal in terms of complexity on reasonably large projects.


For all intents are purposes they are roughly the same. Same ideology, same goal, same developer workflow. Vue has a bit more syntactic sugar which takes away most of the complexity of React (unnecessary rerenders, useEffect hook that has its own book and still no one understands it) at the cost of somewhat leaky abstractions. Vue 3 is a huge step ahead by the way.


Everything will get complicated on large projects. The problem, especially the problem pointed out by GP, is that there is a lot of over-complication in smaller projects ... which is most projects!


I'm sure you know this already but to clarify - Svelte isn't going anywhere and you can still very much use it without SvelteKit

Curious though, what are the problems you see with SvelteKit? It can always be improved!


By "ZIRP", did you mean "Zero interest-rate policy", "Zurich Integrative Rodent Physiology" or "Zimbabwe Idai Recovery Project" (top 3 results on DuckDuckGo)?


Async queues are far from meaningless. They are the basis of distributed, resumanble/retryable computation.

If you can't see the advantage of keeping your processors fed with work as close to 100% of the time as humanly possible, I got nothing for ya. Hell, AWS is basically popular because you can have novice programmers toss up synchronously programmed lambdas, and scale out the underlying infrastructure with Amazon magic, which in a non-AWS system translates to "define queue and message format which will be servicing producer/consumer workers, deploy and start dumping messages in/popping messages out of said queue; scale to taste.

It takes a while to wrap your head around async, but once you get there, you're building with one of the most powerful computing primitives I've yet to come across.

It's just unfortunate that the language and requisite mental model around it is, in my experience, a bit difficult to intuitively reach.


I didn’t say they were meaningless, just that they are often overused and can make systems needlessly more complex.

How many microservices architectures with dependent webs of async queues emulating distributed transaction semantics could be replaced by one big rdbms? I think a lot!


My favorite is when a new project thinks it needs this on day one. I'm willing to place money that most new projects will struggle to saturate a single computer. Much less a distributed infrastructure. (yes, I'm well aware there are some cases. But even most fang projects are doing relatively little work, all told.)


Chime famously (but maybe not externally) ran almost all infra off two co-located beefy servers all the way up to their millionth customer. Maybe that is dumb, but we never had any downtime or slowness that was a result of work we did. The APIs we would rely on sometimes though did.


Another reason there is so much complexity is that the computer speed allows it. If you are constrained by processing power you will chose a more simple architecture... until you start optimizing. A lot on unnecessary complexity is premature optimizations. That "web scale" service you are building with "serverless" and other cloud services will likely run fine on a 1$/moth VPS - but who would like to manage such a small budget :P


It's just so ironic to see this monstrous amount of complexity that is only made tolerable by the massively overpowered hardware beneath it, and which, reduces the throughput of said hardware enough that said complexity becomes necessary.


You aren't wrong, but I suspect there was more unnecessary complexity in early computers then you'd allow. Is why don't ridiculous demo scene stuff is still created today. :)




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

Search: