Hacker News new | past | comments | ask | show | jobs | submit login

I've worked in a few roughly-the-same-size (~50 engineers) web development shops. It's always the same. Doesn't matter if it's React, Angular, Class based components, Functional components with hooks, Just Some HTML, PHP, Rails views, etc.

The frontend just collects the cruft of a product organization changing course very frequently. There are always a dozen half-finished fix-the-world ideas conflicting with each other, half-finished move-to-new-framework initiatives.

I just mean to say that when I hear "it's because React" or "it's because rails views", any other of the infinite variations of this, I kind of just tune out. Some part of your organizations chaos is going to reflect in code, and honestly I'd rather it be in a big ball of frontend than in the data models, infrastructure, etc.




> Some part of your organizations chaos is going to reflect in code, and honestly I'd rather it be in a big ball of frontend than in the data models, infrastructure, etc.

I disagree. I like my frontend to be as dumb as possible. It gets data and reacts to it as simple as possible. Seen too many frontends with a lot of data logic and it becomes extremely brittle, harder to test.

These are the ones where the frontend devs are getting data from the API and creating new structures, transforming it, conditionals everywhere, etc.

It requires way more discipline to ensure that frontend devs aren't recreating the wheel and writing duplicate code as the app and components evolve, and it's worse for larger codebases of course.

They need to build some new component and go - ok I got the data from the API and now I need to do the thing that's already been done by another frontend dev for another component because we've allowed the frontend to be responsible for transforming the data. But if they aren't aware of this, then you get a lot of dupe code.

Just have your backend API provide the contract. Setup resources/transformers as needed on the backend instead of littering the frontend with that logic.


I primarily agree with you, but his primary point is mainly regarding the tendency for projects at large organizations to have a substantial number of unfished attempts to rework existing applications, which often results in serious headaches for whoever owns the code.

What I mean is that even if you've followed a specific set of programming principals, code practices and design patterns consistently across the life time of the application, there will still have been initiatives to change how things are done. Maybe they want to use a "better" authentication library, or add a material framework that has capabilities they need. The exact initiative, and how valid the request or decision is doesn't matter. These initiatives may occur one at a time, or be competing with each other for priority while being incompatible without anyone noticing. But some of them will fail to be completed, and someone has to back out the changes that shouldn't go to prod. Inevitably something will get left behind. Over 5-10 years this can have a shockingly large impact on the code base in ways engineers frequently notice but don't understand how the code got to the state its in.

This frequently means dead code, unused dependencies, comments that don't make any sense, properties on objects that are never displayed or referenced by business logic, and multiple classes/services which accept the same inputs and produce the same outputs but do the job just differently enough you can't be sure it's the same. That, and over abstractions (any piece of code which branches based on the context of "who's asking").

And frankly few things any me more than someone who felt the need to implement their own logging implementation, especially in C# (yes I know we're talking about React, but people do the same stupid crap in that case as well). Reinventing the wheel has to be done on occasion, but you need to ask yourself if it has to be you that makes it happen,and whether it already has been.


That's why I like GraphQL, you get exactly the data you request, no transformation necessary.


This is why I dislike graphql especially with react. It’s gets set up as a half assed ORM (but without joins!) and then all but the most senior of engineers end up using it as your application state which slows the whole app to crawl forcing a big rewrite.

Using an orm and building a proper data model in your code using a store like redis takes very little additional time (especially with sequelize!) and it has the benefit that your junior and mid level engineers understand where the underlying data is stored.


Yes I've also seen a bunch of these apps with extremely chatty graphql calls because it's so convenient!

One component just needs 2 pieces of data = graphql call. Another needs more data and they're doing another similar call. And so on. You got query flexibility but now you are drowning in additional network requests because it's so easy for your team to just "query for what they want".

To me, if your application doesn't need to have the flexibility in querying, then it isn't worth it. Is your dataset so large you don't wish to overfetch data (you can do that without graphql anyway)? Do you need ad-hoc querying in your UIs?

Think about your data, how you will need to expose it and expose it.


Seems you're not familiar with recent advances. GraphQL servers have the ability to collate requests together and only redo a query when data changes instead of "whenever they want" because the client and server know exactly what data is used for which component.

This video describes how this is done in Relay but it can exist in other servers too: https://www.youtube.com/watch?v=KT3XKDBZW7M


That doesn't prevent your frontend and components from making a ton of extra network requests because graphql makes it easy for frontend devs to do fire a new query for their component.

Simple example:

1. header component - dev queries user for first name to do a welcome message.

2. sidebar component - another dev does a query for first/last/avatar/profile/etc.

Your app sends 2 network calls. Certainly it doesn't have to, but I've seen this chattiness get implemented.

So you avoided overfetching of data like official REST APIs but now you have more network calls.


Yes, it does. As I explained, GraphQL servers can see which requests should be collated and deduplicated and puts them all into one request. For example, Relay:

> Relay combines the advantages of both of these approaches by allowing components to specify what data they require, but to coalesce those requirements into a single query that fetches the data for an entire subtree of components. In other words, it determines statically (i.e. before your application runs; at the time you write your code) the requirements for an entire view!

> This is achieved with the help of GraphQL. Functional components use one or more GraphQL fragments to describe their data requirements. These fragments are then nested within other fragments, and ultimately within queries. And when such a query is fetched, Relay will make a single network request for it and all of its nested fragments. In other words, the Relay runtime is then able to make a single network request for all of the data required by a view!

https://relay.dev/docs/principles-and-architecture/thinking-...


Ok but I'm talking about your client application sending multiple network calls at different times. How does the server prevent that? It doesn't.

In order to prevent the frontend from doing that, I have to be sure to enforce usage of another layer. Devs need to use fragments and relay and not just fire off their own ad-hoc graphql queries.

Which is interesting, and thanks for sharing. I would move toward implementing this on any graphql project, especially an inherited, network chatty graphql project.

But I still prefer keeping the frontend really dumb and just sending the data it needs, that has been identified.

Most of the time a REST or REST like API endpoint is sufficient, and it doesn't matter if you overfetch some data, you avoid extra graphql layers (now enforcing fragments/relay, extra resolvers, potential performance issues, multiple schemas and access concerns).

I like GraphQL but it seems like a lot of overhead for little gain for many projects. One project has 3 different graphql schemas. Can't be exposing the whole tree to every user type.

I can see why frontend devs would like it though (need this data, probably already available), but a REST or REST-like API is more enjoyable for me unless I'm building a framework or on top of a framework or a client that needs ultimate ad-hoc query ability where it really shines to me.


By that logic even a REST endpoint server can't stop people from making network calls at different times. How would you even stop that, simply make people wait until a set time before collating and sending out the data?


I don't see frontends using REST servers doing what I see with GraphQL.

UI using REST server tends to centralize the API client, call the endpoint(s), and make that available to all components.

UI using GraphQL often has frontend devs doing their components, running their ad-hoc queries for "just what they need". More network calls.

So overfetching like with REST tends to lead to less network calls unless you are extra diligent on a GraphQL project.


Not sure I understand because I use GraphQL with an ORM, Prisma with Postgres and Pothos which converts the Prisma schema into GraphQL types. It even has the ability to use Redis as a store. So we get all the features of an ORM and also typesafe queries.


Right my point is that

1. It incentivized using it as the data model which is both inefficient and lossy in regards to transactions.

2. what’s the purpose of graphql in this context? You have to use an ORM anyway with which you can do all delegations to servers etc your heart desires and with typescript you can ensure proper column types regardless. You can trivially autogenerate objects or any kind of descriptor from a database as well.

Seems to me people decided graphql was a perfect solution to nicely hit multiple data stores with the now added caveat that we have a worse query language that lacks joins to boot.

I’ve still yet to see an actual technical argument for why we should add another (less efficient) layer between the actual data stores and the ORM/Application DataModel.

Is it resolver logic between stores?


GraphQL is for the client to efficiently query data, it is not supposed to be used as a SQL replacement on the server side. If people are using it for a server side query language, that is not what its benefit is.


IIRC in the Gatsby framework it has a built-in GraphQL parser for server-side developers to query data from Gatsby plugins, which can be things like data stores, other APIs, or even a mixture and blended together.


In a way, that's using the server as a client for other servers, ie it would be the same as a server sending a REST request to another server asking for data. What I mean is nowhere should there be GraphQL between a server and a database, because that doesn't make any sense, just use an ORM.


How can the client most efficiently query data from a sql database without joins? Surely there are cases this would be needed to speedup grabbing of data?


Any ORM will handle getting data with joins just fine when it constructs the SQL. Or you can write your own SQL with joins to pass along to the query.

If you mean GraphQL doesn't have joins, I'm not sure in what use case that would matter when you're declaratively asking the server for some data, not hand constructing SQL. What would you need joins in? You mean like this example [0]?

[0] https://stackoverflow.com/questions/51805890/how-to-do-a-sim...


Right so, again, what exactly is the purpose of graphql?

It seems to be a replacement for an ORM that then needs an ORM. So it’s a replacement for passing JSON objects around except it’s just doing that with a dash of esotericism.

What can graphql do that an ORM can’t?


You're mixing up server side and client side. The point of GraphQL is to make a client request only what data it needs rather than making X different REST calls then combining and filtering them in the client side. That's it, that's the entire purpose. (If you then ask, why not have REST calls that give specific pieces of information, ie have sorts and filters within the query parameters, and be able to take a table and ask for specific columns in that table, then congratulations, you've reinvented GraphQL.)

You can then implement a server which, given a GraphQL query, turns it into the data that's expected. The client doesn't care how you implement that. You can write raw SQL, use an ORM, whatever. Since people don't want to reinvent the wheel they use libraries like Apollo Server, but again you can do it all by hand if you really want to.

Have you actually used GraphQL? This is all explained within the first 15 minutes of any GraphQL tutorial.


> If you then ask, why not have REST calls that give specific pieces of information, ie have sorts and filters within the query parameters, and be able to take a table and ask for specific columns in that table, then congratulations, you've reinvented GraphQL.

Obligatory note: this really is just supposed to be REST. GraphQL seems to be the final expression of throwing in the towel on REST's original capabilities.

As such it's not clear of it's a step forward (REST as it should be) or a step back (let's just use a crippled SQL and ship)


So if front-end devs get everything they need client side, what’s the point of having backend devs?

https://imgflip.com/i/6u4obk


SPAs and REST APIs moved a lot of the complexity around data to the client side. GraphQL moved it back to the server side. I think that's a reasonable decision, as the client - compared to the server - runs in a much more unpredictable environment. Of course some backend devs complain about more work, especially work that could be moved to the client side at first. Making things the proper way is hard, yes.


The pitch I remember back when it first was released was that GraphQL was meant for development, when the API was still changing a lot, and was supposed to be replaced with dedicated API calls before going to production. During development frontend devs has something flexible they could use without pestering the backend constantly, then the dedicated non-GraphQL production version would be stable and could be significantly more optimized than the GraphQL version.


The backend still needs to implement the endpoints for the frontend? Not sure what you mean, if anything the backend work increases because everything is done on the backend now.

And did you really link me to a meme you made specifically for this conversation?


True and I like GraphQL but in many cases your UI needs data in a way that isn't available on your existing endpoints. Ex: summary data / aggregations for reports or analytics. Or simple things like fullName on a user entity, a displayAddress, a display greeting based on their user group, you get the idea. You can do all of this on the frontend but it just becomes messier.

This is what I'm referring to.

So you still need to write some new graphql resolvers on the backend and update your graphql schema. Not much different from writing some new REST api endpoints or expanding an existing endpoint.

But if you use GraphQL then I agree on the benefit and approach still of having as much of your data logic on the backend. And with GraphQL you have a schema that is readily available, auto-documented and available for frontend devs to use for current and future components.

Which is better than having that logic on the frontend IMO.


Graphql fans will attempt to convince you the way you’re querying data is wrong. You can do triggers if needed but graphql to me seems like a solution to internal enterprise data wrangling ootb. I don’t see the benefit of using it over an orm when you add in multiple databases, a working data store, etc


Yeah I'm not entirely sold on GraphQL but I think it shines in some cases.

Ex: you are building on top of third party ecommerce software.

You need to add more data to the Cart entity because you have a custom module/plugin/etc. You write a graphql resolver, extend the schema and the Cart type. You can use the existing built-in endpoint to query your new data.

So it's nice to be able to extend a framework and data access in that manner.

In general though, I do prefer REST APIs and then writing custom endpoints if I need data for a specific UI, like for visualizations.


Parent is mixing up GraphQL and ORMs which serve two completely different purposes and doesn't seem to have actually used GraphQL. GraphQL is purely a way for a client to request some data instead of REST. How the backend serves that request is not any concern to the frontend, the backend can use an ORM or it can use raw SQL, or whatever else it wants.


Yes I think you are right; I wasn't following the ORM part either. I mean, you can return whatever you want so long as matches the schema. Hard code it, raw sql, whatever.

I wrote some custom resolvers yesterday to extend graphql on a Cart entity and it works well for that.

I used some existing repositories the backend already had but was not yet available on the GraphQL side.

All the resolvers can lead to extra performance issues of course, but I suppose you can adjust your schema as needed and tune it with more efficient queries or code (ex: move some properties to nested and resolve with a single tuned query)


GraphQL was designed to solve a singular problem, slow mobile internet speeds. Now that mobile internet (5G) is faster then some wired home connections I'm worried that GraphQL will die off. It's a solution that no longer has a problem. Though it is a cool tech.


I love GQL, but making things optional by default in the schema was the stupidest decision they could've made.

Also the issue with GQL is that FE devs love to copy+paste giant queries that just get everything because it's "convenient", or build up a query while building/testing something and then go on to use that query, including fields that don't eventually get used in the final work.

What GQL->consumer ecosystem really needs is something that can check if a field is ever actually accessed in the code or not, something TS/compilation-wise would work. That way the query can be narrowed down to what's actually used in code.


Graphql does not address the problem he's describing. When he says "transformation" his meaning is similar to transformation in an ETL process. What he means is the application loads data, the user takes an action, and the front end code handles updating the objects locally, then sends messages to the backend telling it what the new data state should be.

This is very dangerous behavior for any application. You don't want the front end to determine how much the shopping cart costs or to just tell the backend they've paid, therefore add the items to the orders list. Even if there isn't blatantly obvious security concerns, you should still never let your front end blindly determine data state changes. All such business logic belongs in the backend as much as possible.

What he's talking about is when business logic is split between the front and backend, which makes everything much harder to test on top of increasing the likelihood of duplicate code or even code which does the same thing but looks different enough to not be caught as duplication (which means changing business logic requires finding all the places it was implemented and changing them all, and if you miss any its unlikely anyone else will realize it until it hits prod).

The UI should always just be a shell that sends requests to a backend which determines which updates to make. There are exceptions like when a user makes form based changes to an object, but the only business logic in that case is "let the user decide what the value should be and persist that choice as is". If any additional changes may need to occur as a result of their change, your backend should make them. Even if you just need to determine if a change shouldn't be allowed because of related data, send a request to your backend requesting the answer and any relevant data necessary for display purposes, not the data necessary to make that determination.

There are exceptions to what I've said, but even in those cases, the backend should still verify whether the front end's result is correct. While the front end was working, a change could have gone through in the backend which invalidates that change. This is why things like concurrency/version tokens can be very important.

In any case, Graphql may have capabilities that look like they help keep business logic in the backend, but it doesn't stop programmers from putting business logic in the front end anyway. No matter how you try to look at it, spreading business logic out across your applications various layers always has unintended consequences for maintainability and even scalability.


> What he means is the application loads data, the user takes an action, and the front end code handles updating the objects locally, then sends messages to the backend telling it what the new data state should be.

But you don't have to do it like this at all. I don't understand what this has to do with GraphQL, you can make the frontend never update local state and only fetch from the server if you want. That's an implementation detail not related to GraphQL, REST, or any other API format.

> No matter how you try to look at it, spreading business logic out across your applications various layers always has unintended consequences for maintainability and even scalability.

I agree with you here, but for:

> In any case, Graphql may have capabilities that look like they help keep business logic in the backend, but it doesn't stop programmers from putting business logic in the front end anyway.

Again an implementation detail, if you're the tech lead, just tell your devs (or architect the app in such a way as to) not to put business logic into the frontend.


I wasn't referring to trusting the client's logic and state changes and then sending it back in an update and storing it. But certainly some devs do that.

As a simple example, you may send an entity to be updated and then the frontend makes a decision to say, you changed this value, then alter this other value so that the update request has the values we want (ie: one property may need to be blanked if another property has a certain value). Your frontend has logic it shouldn't and you should be enforcing your data on the backend anyway.

However, I was referring more to a situation where a frontend dev has an API request that it can work with but needs in another format or structure. And then logic is added to that data based on the user inputs or to simply do client side aggregations. Maybe it takes the user's chosen store location and filters out the out of stock products from the API on the client side.

Instead of sending the inputs to the API and have the API's logic handle it and provide you with the dumb data for your frontend to render - here are the products you should render; don't think about anything. So your frontend isn't growing into this brittle thing that is doing too much and is more likely to end up with dupe code as multiple frontend devs get tasked with new but similar components and recreate the wheel.

> In any case, Graphql may have capabilities that look like they help keep business logic in the backend, but it doesn't stop programmers from putting business logic in the front end anyway.

I'd argue that it in many cases it promotes frontend devs adding more business logic. Because your devs can query for whatever they want on the schema, transform the data, do whatever logic in the components instead of relying on an API contract for said data.

It means there's really no thought into: what does this client actually need?

So the frontend devs don't have to involve a backend dev or team to get most of their tasks done, which may be a great thing for their situation.

But the business logic gets pushed more and more into the frontend and gets bloated and brittle.


I believe what you're describing is called "Backend for fronted" (BFF)


Why? What's the difference?


You’re likely duplicating a lot of business logic between the frontend and backend. You can do it, but if you forgot to update one implementation, it could get ugly fast.


Backend doesn't need to deal with animations, styling, browser support, responsiveness, etc.


It really is hard to understate how damaging the half-finished ideas in the code base can be. To the point that I often prefer to stay on something I don't like, if I'm not positive I can finish moving completely off of it.


> It really is hard to understate how damaging the half-finished ideas in the code base can be.

People get promoted for all the shiny new things they do, not for the discipline they show in only focusing on what really matters.


> People get promoted for all the shiny new things they do, not for the discipline they show in only focusing on what really matters.

Depends on the company and its values. I've been in companies where engineers who don't care about the business/customers were promoted by other engineers who don't care about the business/customers, and yeah, promotions were getting handed out for engineers who did a hacky prototype integration with the latest & greatest NoSQL Big Data GraphQL Blockchain OSS project while solving no actual problems. I've also been other places (Amazon) where customers really are front and center, and spending time on cool engineering projects that serve no customer purpose meant absolutely nothing when you wrote up your promotion doc.


I'm trying to select a good framework and coming from long before react, having a tough time finding why shouldn't use just custom elements with no framework. Which is already built in.

   customElements.define('my-element', class MyElement extends HTMLElement { ... })
I can manage state within the component, app state in window.state. Coding up a simple reactivity is really pretty straight forward. Now, for this feature and that - maybe not - but do we need all those features. Programmers like to write code, so every framework always gets bigger and more complicated.

I understand and respect the problem react is trying to solve, I just don't see it as much different than the js world before async/await and fetch, etc.. callback hell - which I saw as much more prickly issues.


Mithril or Svelte should be all you need. If you're coming from React, I'd recommend trying Mithril first. I've been using it heavily for 5 years now and I'll likely stick with it for at least another 15.

Mithril is reactive out of the box, and just works. It smokes React in every category, but still has an optional JSX integration if that's what you're comfortable with.

https://mithril.js.org/

https://svelte.dev/


I was excited about Svelte, but now Astro JS is my favorite.


Those tools are not mutually exclusive. Astro is not a component UI library.


If we’re talking about class-based components then I agree with you. React doesn’t do much… maybe some performance benefits, and maybe you can avoid some complex DOM manipulation here and there, but with the extra abstraction required that all might be a wash.

But with functional components I think React gives you something substantially more debuggable than an object instance with random method calls that manipulate the DOM.

React functional components (with hooks) mandate a very specific control flow that probably halves the debugging surface for any given bug, saving time.

You do have to exercise restraint when incorporating third party libraries, but if you can do that it can be a very rapid development environment.


I'm not sure if I'm following, are you saying that class-based components (whether React or not) could be characterized as "an object instance with random method calls that manipulate the DOM", and thus React functional components offer an advantage to them?


Iirc correctly the hooks in functional react are classes under the hood (maybe I’m wrong and it’s functions, been awhile.) The advantage functional react has over class based is reusability. You could reuse classes before and functions within them but it gets harry keeping a clean architecture.

With functional components you can write hooks that allow you to reuse all state logic between components.


Any good articles I can check out that go into this in depth, or should I just check out the tutorials/documentation? Thanks


I pursued this idea pretty aggressively for a while. What I found is that it was a wonderful fit for small projects, and then became a real drag as the scale/complexity grew, which led me to start thinking in terms of a budget-matching principle [1]

  1 https://paulfrazee.medium.com/building-on-budget-4b91b43d0357


>"having a tough time finding why shouldn't use just custom elements with no framework"

This is exactly what I do on SPA front ends for many of my customers. Of course we use some libs but those have nothing in common with the frameworks, just narrowly scoped solutions. Saves gobbles of time and money.


React itself really hasn't gotten significantly bigger. It's more of a rendering library than a framework.

Custom elements are really neat, and may very well do what you need. The big pain point that React solves (for me at least) is that you get to define your views declaratively instead of imperatively.


Custom elements are just a way to define tags. React solves everything that's inside that class you wrote... and in a better way IMHO. E.g. with custom elements there's a difference between an attribute and a property and it's a PITA.


Compatibility for starters: https://caniuse.com/custom-elementsv1


Last time I used them, web components were incredibly slow. They were so slow to render, after using maybe 2 or 3 of them I realized why nobody is trying to build apps this way. Just isn't there yet. Probably won't be until HTML Imports are merged with JS Imports.


This is a surprising perspective, since we're using web components top-to-bottom to build photoshop on the web, & some of that decision was driven by performance comparisons where web components outperformed react.

It's possible that very naive implementations of web components would render as slowly as you describe - like if you rebuilt the whole DOM tree at every level on every change.

Here is a performance-oriented talk about rendering web components via browser-parsed template literals via Lit (which is how we do it):

https://youtu.be/CJYkwDTaHzY


Stop your propaganda, the Internet largest video platform uses Web components with Polyfill.


They mostly encourage bad practice by design and people do what these tools give an affordance for which is why the results are broken.


People can write bad things in every language. "It takes a lot of skill to write Java in any language." is a pithy quote for a reason.

The issue is usually frontend pedagogy or the lack of it. Maybe things have changed but when I graduated undergrad CS in 2017 the extent of frontend being taught in my school by professors was "hand write some HTML, maybe some PHP if you're lucky". I've never met anyone who learned frontend anything in school to a degree that matters, so everyone is either learning from other junior devs on the job, from blog posts that are often wrong, or from a backend engineer who was pressed into learning frontend.

Yes, JS has a very tortured history coming from the fact that it was not intended to be the long-term development language for web interactivity from the start, but we also don't really teach how to do it properly.


> Maybe things have changed but when I graduated undergrad CS in 2017 the extent of frontend being taught in my school by professors was "hand write some HTML, maybe some PHP if you're lucky"

Here's a secret nobody told you: You don't need to learn frontend specifics. All the same lessons from business software engineering apply.

I not-graduated comp sci in 2012 and have been building webapps since before jQuery was cool. It's nothing special. The biggest problems are always the same: data and domain modeling, managing complexity, teamwork, and state consistency.

If your comp sci degree didn't teach you how to apply solutions to those problems in any context – frontend, backend, iOS, firmware, desktop app, Android, or data pipeline – then it was a worthless degree and you should get your money back. The point of comp sci is to learn about the ideas behind the scenes, not about specific frameworks.


Preach!

Data modelling and managing complexity (or I prefer to say knowledge organization) is a prerequisites for every software program ever.

I'd add one more: System design.

Basically dealing with many asynchronous moving parts, managing entities' lifetime, separating and categorizing domain/data, and understanding what-is-important-to-whom. It is a knowledge that's applicable whether you are programming a kernel scheduler or managing people and projects


Yep and nowhere seems to teach this in practice other than job sites. I’m building a team right now with two mid level engineers and a junior. They’re great and I couldn’t ask for better guys to be clear; but your point stands.

They don’t understand this (subsystems architecture and the the living data model.) It’s like they think I have a giant list of existing solutions to every problem that they haven’t memorized yet so when hit with a problem needing a subsystem they were basically useless until I slowly started teaching it to them. I’m talking Ivy League kids with degrees I only ever dreamed of getting. There brains just aren’t trained to architect systems the way I expected junior/mid level engineers to be as a self taught engineer.

Also the data model stuff has been a real painpoint for me. We were set up with graphql and Postgres so of course the MVP forwent any working data store other than react states.


Eh, to some degree you do get a starting point in uni for various things. You’ll learn basic models for systems or databases as part of core requirements. If a web course exists, it’s most likely optional and out of date.

Web is certainly a different context, and some people struggle to pick it up. There’s no authoritative book like the C Programming Language, and the web is full of wrong information that sometimes comes above more authoratitve sources like MDN in Google results.


> Web is certainly a different context

I mean it's a thin or fat client talking to a fat or thin data source over a network. "We" have been building systems like that since the 1950's.


This is absolutely correct from the perspective of a senior developer. Junior devs generally haven't completed enough language/framework hype cycles to develop the required experience (or cynicism really) to look past the bullshit to this very simple fact.


how we present has changed a lot, though. And we reap the rewards of not teaching.

As a general example, part of why accessibility on the web is so poor is because we don't teach anything about it. It's become this mythical scary thing, when in reality a lot of the pain is avoidable with a little bit of thinking. We just don't teach any of it.


If we're talking language level (even in C, you'd usually be using other libraries and APIs even if it's just POSIX or curses), I'd argue that "JavaScript: The Good Parts: The Good Parts" is probably the most authoritative book out there.


woah woah hold on there young one

This isn't that. My hostile working definition of a framework is something that

. breaks core assumptions about a language or system

. limits what a user is permitted to do

. increases complexities by adding new abstractions

. has non-specific specifications by using unclear and imprecise language

At the end you are hardly writing software. Instead you're deep into a world of new abstractions and are fundamentally limited by these abstractions.

Frameworks work at a subconcious level. They permit the users to be constantly busy as they chaperone codebases which would otherwise have long term stability all while staking the claim that it's the fastest and easiest solution.

Because frameworks exist primarily in a product space it's worth looking at their value proposition. Frameworks essentially act as a modern facilitator to what Frederick Winslow Talor called "Soldiering" in the text "Scientific Management". Essentially this means "the evasion of work or duty", the workers you wish to provide to have a vested interest in their own well-being and do not benefit from working above the defined rate of work when it will not increase their remuneration.

Normally a manager would have every reason to dismiss these programmers. To combat this natural inclination, a proper framework makes sure this is impossible by making them unfirable.

Given a product:

. Systems should not continue to function without the programmer

. Code has to constantly be rewritten in order to achieve the same ends

Also it permits the users to go on constant employer funded vacations to conferences and training sessions.

From a professional programmer's point of view, the primary goals of any framework are to provide the users with the following:

. Job security by ensuring brittle applications

. Endless tasks by ensuring endless complexity

. A sense of elitism and entitlement

. No expectations of deliverables

. Be vague enough so blame can get shifted if things break

By making every project asymptotically impossible to deliver vaporware, the ideal framework ensures that people are always doing something while at the same time nothing ever gets done.

The old is dying and the new cannot be born; in this interregnum they're on salary so they make it last as long as possible.

In trades where there's no guilds or unions, there's a tendency to create career protection through other forms of tribal qualification systems or arcane knowledge. Making things intentionally complicated so that only a select few people can comprehend them is a common way to capture and exercise power.

People adopt the patterns because they want to have the perceived protective properties of the obscurities.

Worlds of irrelevant relations and materially meaningless abstractions are essentially how fields such as fortune telling and astrology continue unabated. The form becomes the function and the elaborations its aesthetic.

...

Btw, this is a collections of excerpts from a 40 page document I have on the psychology and function of frameworks on how the most popular ones service human emotion that I've been working on off and on for a while.


That reads like a parody to me - the cynical engineer that uses conspirational thinking patterns to create a narrative of the world when emergent outcomes are the causes.

Look for counterexamples where your cause incentives don’t exist yet the same outcomes still do: that is scientific thinking.

> Job security by ensuring brittle applications > Endless tasks by ensuring endless complexity > A sense of elitism and entitlement > No expectations of deliverables > Be vague enough so blame can get shifted if things break

The last thing many programmers desire is a millstone of old code they are responsible for. Perhaps you posit that they subconsciously desire to make complex code to give them job security? I suggest you watch (or ideally become) a founder engineer, who’s incentives are the opposite of all the above, yet the founder still ends up with the same problems.


Done both.

This phenomena can also happen organically.

All these things are tools and you can wrestle with tools or have them make life easier.

The question is about in what direction this tools assuage the creative process.

I've had the luck of seeing and being involved in codebases to both billion dollar successes and million dollar moneypits.

There's certainly patterns and difference I've seen.

The most notable one is successes seen to use a lot of boring unexciting old software with ugly websites.

Like say emacs, that's got an ugly old site. Or what about GCC? How about the Apache site? It doesn't even hype up how amazing and easy your life is with their simple and elegant efficient masterpiece. What about debian.org? FFTW? PCRE? Sqlite? imagemagick?

Now compare this with react and vue.

One is "we have this tool" and the other makes lofty emotional pleas about your relationship with your work. They're fundamentally different approaches and thus have fundamentally different outcomes.

One accomplishes a goal while the other accomplishes an affectation.


This is cynical as heck, but a good read. Do you have any plans to publish the larger document?


After that encouragement I do! Thanks!

The premise is how to write a successful framework. The cynical takes are presented as advice.

It's structured like those guru business books like "Blue Ocean Strategy" or "Little Bets".

That genre requires an additional separate focus and some further work. It's by a bunch of narcissists who ran multiple businesses into the ground who pivoted to being a guru and offer acronyms, charts, and X-point frameworks in tidy books with a bunch of business examples, most of which catastrophically collapse within 12 months of publication.

And then the books sell 5 million copies, the authors get Ted Talks, it's the same mechanism at play. People pass around their Clayton Christensen of Geoffrey Moore diagrams and crib paragraphs quoting them like they're bible passages. And people eat it up. It's wild.

I remember looking at the Appendix of one of Jim Collins books for the first time about 10 years ago where he talks about his methodology with his team. When you start cross-referencing and see the omissions, mistakes, and misrepresentations, it's wild. I was like "wow this thing is nonsense".

You've got Sutherland's Scrum, Collins BHAGs, and you burn through $20,000,000 in Series A without releasing shit. Alright, I guess that's what we do.


This is a great reply and something I've noticed IME as well. I'm sure there is an economic term for it, but it's like perverse incentives coupled with unconsciousness.

Echoing the other replies that we want to read more of your thoughts (book, articles, blog). Is your site in your profile the best way to follow you?


This is easily the most accurate description of what a frameworks are and the consequences of their adoption I have come across in my 25 years of experience in industry. A not so minor quibble: I think most end users of frameworks approach framework selection with good intentions, likely from a position of naivete, rather than from some sociopathic desire to build a bunker for themselves in their workplace. This of course doesn't change the outcomes.


Give us the doc


When it's ready. I'm going to look for a published


Link to the doc?


When it's ready. I'm going to look for a published


> Maybe things have changed but when I graduated undergrad CS in 2017 the extent of frontend being taught in my school by professors was "hand write some HTML, maybe some PHP if you're lucky"

And rightly so, because frontend web development is not Computer Science.


I completely agree. And the thing with different frameworks is they let you scale to varying heights of complexity before you reach those high-level problems. For example, I find that functional components can have more complexity in terms of logic than class components before they become a complete mess. React itself allowed us to go way beyond jQuery before becoming a complete mess. I don’t think there will ever be a framework that saves us from that as long as managers keep doing what managers do.


> There are always [] half-finished fix-the-world ideas conflicting with each other,

I work in a code base like this. People's suggestion? Introduce React!


> Some part of your organizations chaos is going to reflect in code,

This is reality, and why organizational chaos is so painful for engineers.


If you read Programming As If People Mattered from 1992, the frontend mess was true then too.


relevant codeless code parable: http://thecodelesscode.com/case/123


I’ve had similar experiences, but I wonder how much of this is truly inevitable because software development is complicated and requirements often change along the way, and how much is simply bad management.

I’ve noticed that over time the prevailing culture in software development has drifted more and more towards “thinking small”. This has certainly been encouraged by the shift to web and mobile apps in an always-connected, always-updatable world.

First it was just the code. Short functions, few parameters, shallow nesting. Make everything testable and maintainable!

Then it was the commits. Release early, release often, merge WIP straight into master in your CI/CD system. We need fast feedback and short cycles to avoid unnecessary conflicts!

Then it was the whole process. Break everything down, do one small thing at once, move it across that Kanban board, next sprint please. We need focus and visible progress!

The danger with all of these is the same: they come from good intentions and even have an element of truth behind them, but they can also mean the big picture gets lost. There’s no coherent vision shared by everyone involved. No-one is watching all the extra dependencies that connect the many small parts. Tech debt compounds. Eventually we are forced to acknowledge that there are “challenges” but even then we somehow convince ourselves that those were inevitable, even though they weren’t really there before.

Yes, of course our early-merged WIP hidden behind a feature flag in CI is completely different to the feature branch we used to use. Now we know everything builds before it can be merged, even though nothing is really testing that all the different combinations of WIP actually work together, so that’s a big improvement on before. And since obviously we have a reliable, automated process for backing out any unfinished code that doesn’t make the cut later, we’re also much better off than the old situation where we’d just have sidelined that feature branch and never merged into the next level up in the first place!

In the real world, this leads to exactly the mess described in the parent comment. There’s no coherent vision for anything big that is shared by everyone involved, no considered and consistent structure for the software architecture or the APIs or the data formats. If we rely on emergent properties that evolve organically, we also run into evolutionary dead-ends, and what survives might work but also be messy.

Personally, I don’t really buy the argument that this is inevitable. Five players can make a great jazz band. With 100 players, you probably want an orchestra with a conductor and sheets and the occasional featured soloist. Neither jazz nor orchestration is “better” or “worse” in absolute terms but they are certainly different.


> First it was just the code. Short functions, few parameters, shallow nesting. Make everything testable and maintainable!

I don't think this is related to losing sight of the big picture, no more than focusing on good clear sentences means you can't write Anna Karenina.

But I do agree that sometimes the big picture is lost, with tasks that have been broken down inappropriately.

I have a suspicion that partly this is driven by open plan offices: tasks have to be broken down, as focus is a luxury.




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

Search: