Hacker News new | past | comments | ask | show | jobs | submit login
A brief history of web development, and why your framework doesn't matter (gebna.gg)
94 points by thunderbong 16 days ago | hide | past | favorite | 85 comments



I feel old when an article explains that a server can generate HTML and the browser renders the HTML and that this can be done quite efficiently for every interaction with a user.

It’s strange to me that one can be a webdev without understanding that you do not need JS for a web app, although it does improve the UI in some areas.

It feels even stranger that the term server-side rendering became a thing, since the server doesn’t render anything, but just generates HTML and sends it over the wire.

And I’m only 39.


Same here. I remember the days I was new and hip fondly.

I work with frontends among other things so I am semi-aware of the current state of insanity.

I try to not talk too much and go with the flow. The older I get the more software (and business) in general seems like it’s built out of raw insanity.


I feel old too, reading this same argument today. I joined this industry in early 2010 and people were saying the same things about frontend stacks.

Back then, I believed that the people making this argument were onto something, as it felt overly complicated to me as a beginner.

At this point it feels more likely that the people making this argument don't have any kind of experience in frontend development that span multiple teams collaborating on the same UI.

In the backend this was "solved" through mocroservices. In the frontend you're gonna be in a world of pain unless you're using one of the popular spa frameworks. Well, you're probably still gonna be in pain. It'd just be worse if you didn't use the framework.


I see it more like how we have flip phones now. It’s similar but not the same.

I started working post Ajax using jQuery using Java JSP’s (2010).


I remember using ColdFusion to dynamically render HTML on the server, and still support client side rendering in the client via standard JS if needed.

Times were simpler then, I feel the abstraction was a lot simpler.

I'd like to see the simpler ColdFusion / ASP style model grow with support from smarter back end tech.

The crazy levels of abstraction in the client/server model are just confusing for someone like me, who was quite happy with the older way of doing things.

Web delivery should be about simplicity and maintainability, not seemingly academic exercises in purity, speed, or abstractions.


Django has the function render (it used to be render_to_response) that takes a template and converts it to HTML. So it isn't just the JS people who are using the idea of rendering in this sense. More generally, rendering doesn't necessarily mean something visual; for instance, one may talk about how a phrase in one language is rendered in another language.

(I'm also 39. You and I may see each other at the shuffleboard court soon.)


I remember centering content using margin:0 auto, and before that using <table>, and before that hunting mammoth, and I'm 36


> efficiently for every interaction with a user

Well, that's the catch. If you are building marketing web _sites_, then maybe. I made my first website in 1999. But sites never entertained me much, I preferred building apps.

I've even built my first web _app_ using plain JS. It was quite painful. When jQuery came around, it was a miracle. But still, building dynamic forms with dependent fields, multi-step forms etc was quickly becoming chaotic. I was basically doing my own version of htmx, this was sth around 2006. You could theoretically keep some semi-sane architecture with jQuery and server-generated snippets but it rarely happened in reality.

Enter Backbone. Finally some good code organization for frontend code. A bit of boilerplate, some pandemonium of events in large apps. Still fond memories and pretty solid apps.

When I first saw React I was appalled. What is this ugly XML thing with code inside? That's like php at the turn of the century. But then I've never really liked any templating language so I gave it a try and never looked back. React is going through some weird identity crisis, but I would still pick it up for any serious enterprise dynamic web app. I have high hopes for Solid, which should be React but cleaned from some historical mistakes. But for sure I am not going back to stitching some server generated snippets and quickly hitting it's limits.

I didn't forgot about server generated html. It's fine for a _lot_ of web pages. But let's not pretend that this is some universal goodness. It sucks for dynamic experiences. Htmx is not our lord saviour, it will again quickly become a mess with stringly connected bits and pieces. Just a simple form where sometimes you need to return the forms with errors or successfully update some elements elsewhere: you need to use ugly out-of-band updates. They tout Htmx being the true REST but handling 400s is shit, now you're adding some events and lo and behold, you are back where I was in 2006 with tangled ball of strings.


> It feels even stranger that the term server-side rendering became a thing, since the server doesn’t render anything, but just generates HTML and sends it over the wire.

Meanwhile, someone somewhere is working on a backend framework that streams raw display frames to a lone <canvas> element.


I’m 28 and spent my childhood making web pages, so I understand the steps we’ve taken to get to where we are.


Same shit-show with terms like "serverless" - which is just a misleading word for a cloud microservice platform.


I believe generating the HTML is what the term render means in this case.


No it is not. Same as videogames generate scenes and videocards render those scenes.

Render is the final step presented to user. Users do not see HTML, they see text, boxes with background colors, buttons, those are html elements rendered for visual consuption.


In React, 'rendering' means creating the DOM nodes and 'painting' refers to browser rendering [1]. So with server-side rendering the DOM nodes are 'rendered' by the server and the browser 'paints' it.

[1] https://react.dev/learn/render-and-commit


In the whole React ecosystem render is used as a keyword to produce HTML/DOM abstractions though. For example class based components having the render function.

The rendering you mention never happened anywhere in the React JS code. Browser did the rendering internally.


>the whole React ecosystem

Web is much more than the React "ecosystem".


Other libs/frameworks also use the word render. E.g. https://vuejs.org/guide/extras/rendering-mechanism.html


those steps could be understood as pre-renders:

from js class to dom objects => pre render 1 from dom to html => pre render 2 from html to display graphics => final render


As someone who has been developing frontend applications since the jQuery era, it would have been nice to see more explanation of why each new innovation happened. There's some of that for things like GraphQL, but to me the biggest and most interesting changes were the move from backend-driven rendering to frontend-driven rendering, and the move from DOM-as-state to rendering the DOM from state. Those ideas were hugely important, and both affected the design of modern frameworks a lot.

Also more recently, the increasing push for moving everything - from CSS declarations to server-side actions - into components. This gets a brief mention, but again, it's one of the ideas that best explains recent trends in frontend development (and many historical trends as well).


> to me the biggest and most interesting changes were the move from backend-driven rendering to frontend-driven rendering, and the move from DOM-as-state to rendering the DOM from state

I think a lot of this can be attributed the rise of internet-connected smartphones and mobile app development.

This led to a scenario where you had to have a separate backend API anyway to service the iOS or Android app frontends, so it was easy to justify doing an react- or angular-driven SPA for the web.

Plus the new mobile form factor demanded more front-end engineering work, so it made technical sense to have the frontend be completely separate from the backend.

This also explains the shift away from DOM-as-state, since you couldn't really drive mobile apps just from HTML, at least back then.


Yes, but all of the React web apps that don’t have a companion mobile app aren’t just cargo culting (but there is a lot of that in the industry). Managing UI state the React way is easier for anything non-trivial. Sure, for forms the web has you covered. But that’s about as far as things go. I remember seeing the small amount of React code required for a typeahead search for the first time and realizing how much more I could now do. The problem is that we have opened ourselves up to all sorts of new troubles by taking on that power. I still wouldn’t go back. But I will complain when some rookie dev makes me download 10MiB of JS to look at a blog.


>we have opened ourselves up to all sorts of new troubles by taking on that power

I guess we'll never know for certain whether we'd have thought SPAs were a good idea in the absence of having reusable APIs hanging around from mobile dev. It certainly made it easier for the browser to talk to the backend.

OTOH, we could just as easily have consumed the API from the app server and continued to render everything server-side. And, as you say, there are serious costs ("troubles") with going the SPA-route.

So, I believe we accepted the pain of SPAs because we thought it was a superior UX. But, I think it was a massive error and the costs have been far too high for the "gain".

There are much easier ways to boost the UX. Examples like typeahead that you mentioned can be just as easily simplified with a standalone JS-lib like typeahead.js. If you add in something like HTMX, it gets even easier to manage the dynamic bits.

Overall, I'd say we could've gotten +80% of the UX gain by sprinkling in dynamic interaction where most impactful, but continuing to render and manage state on the server. I've come to believe that React, Angular, Vue, etc solve a problem that should never have existed.


I think eventually we’ll see a popular framework come around that provides a simpler alternative to React but with optimal ergonomics. For me there’s no going back to the Ruby on Rails world after using Typescript. I’ve used sorbet a bit but I think it’s pretty rough. Someone needs to put together a traditional MVC web framework for Typescript. It won’t be able to do everything that a React app can, but it will handle most needs just fine.


Yeah, there needs to be more emphasis on server-side frameworks in general; preferably, built from the ground up with dynamic front-end interactivity in mind. Maybe they integrate HTMX or similar in a way that allows you to write everything as components or modules that can be seamlessly rendered as a collection in the context of assembling a full page when needed, or individually when a partial/dynamic update is required. So, that code is write-once.

I think these are beginning to emerge. But, bonus points if these were abstracted in a way that it's the same framework (idioms, APIs, etc) and you could just choose your preferred language.


The GraphQL explanation isn't correct, either. It's not about defining a contract: if you wanted to do that, you'd just throw an existing tool for enforcing schemas at your JSON (Swagger as the article suggests, json-schema, Avro with JSON encoding, etc.) and be done.

GraphQL has a few different advantages. Defining what data an endpoint returns on the client helps frontend teams build views without needing to A) define a new backend endpoint per view, B) cram everything for every view into one huge wasteful endpoint, or C) make a cascading set of render-blocking queries in each component such that a round-trip time of 250ms blocks the page for a whole second. It also requires defining a schema, but that's a side benefit.

This is hard to explain because the problems GraphQL fixes aren't actually problems on many teams. You need a complicated and deeply nested data model and UI, loads of different screens with similar information on them, and a backend workflow where API changes cause a lot of overhead.


>the move from backend-driven rendering

The backend doesn't render anything. It just sends html and CSS to the browser which does the rendering.


Your framework does matter. It just doesn't matter to the end user of your web app.

It matters to your dev team.

A framework is a way of aligning how you approach writing things. It's a way of sharing responsibility between functional blocks of code. A framework is guardrails for how you think - it stops you just wandering off and doing whatever you want, and in a team that's vital.


With that theory in mind, why do dev teams switch from Angular to React or Svelte?


React is not a framework, it’s a tiny lib that renders stuff reactively. There are no guardrails, and it is not even specific to Web. You can use it to render to hardware LCD if you want.

When people switch from Angular to React, it’s not a framework-to-framework move. They may have outgrown a ready-made solution and want a fully custom one (could be some sort of home-grown framework, more aligned with their goals). React allows that, being a library.

Meanwhile, an actual framework-to-framework move can occur due to many factors like mismanagement of priorities or changes in HR situation (maybe they do not have success finding good Angular people cheaply, or they are already using Svelte somewhere and can reuse resources from another team).


"React is not a framework"

I know, people in our industry are lazy with words, but there are meanings behind them.

A framework is when you embed your code into the framework code, and the framework calls your code, like in React.

A library is when you call the library code.


You do not embed your code into some “React project”. You call React however you see fit. Sure, you pass it some callbacks, but it doesn’t make React stop being a library.


I might have always used React wrong, I don't call React but embed my code into React like so (syntactic sugar aside)

    class HelloWorld extends React.Component {
      render() {
         return (
           --- my code here start ---
           <div>Hello World!</div>
           --- my code here end ---
         );
      }
    }
and React is calling my code with render(), I'm not calling React.

React owns the control flow and the execution loop, which calls your code (hooks, render, ...) as needed.

With a library you own the control flow.


Here is what you typically do if you use vanilla React in Web context from scratch:

1. You define a function (or in your example a class) which calls React.createElement(...) one or more times and returns the result.

2. You set up the initial DOM as needed.

3. You call ReactDOM (another library, separate from React) and give it your function as callback.

4. ReactDOM sets up the main loop that handles updates to DOM when things change.

You can claim that ReactDOM’s reconciler “owns” the flow, but you have to keep in mind that reconciler is not part of React proper, that you are the one who calls it in the first place, and that React does not provide a reconciler of its own or impose any constraints whatsoever on the structure of your project or what you use to render things in the end or where (it could be not even DOM at all).

I imagine most people who think of vanilla React as a framework go with CRA or another template that brings in the boilerplate code, bundler configurations that make JSX magically work, etc., and acts as a sort-of-almost-framework (not a particularly good one, perhaps), which obscures the fact that React itself is merely a very generic library.


"It's not a framework because I say so"

Ok!


No. React calls your code (over and over again). That's a framework.


If using callbacks is what makes it a Web framework then you can call anything a Web framework.

React is a library not even specifically for Web. Angular, however, is a Web framework. It’s up to you if you want to compare the two, but you will not be comparing Web frameworks.


>>> React is not a framework, it’s a tiny lib that renders stuff reactively.

yeah, no.

try for example to mix in a single page react components and jquery ui widgets


I did that with React, but you can do that with many frameworks, even Angular probably if you’re careful.

You need to understand what makes a framework a framework. onion2k’s comment does a decent job of explaining that, take a look. React has no guardrails and does not force any particular structure. That’s why there’s a plethora of frameworks built on top of it.


I would include React in the framework camp. It isn't technically a framework but it goes far enough that it pushes you to write code in a specific way. If you approach it like a library you often find yourself writing code that doesn't work well with React, which is a common source of janky websites. If you approach it more like a framework, and make sure you follow 'the React way' you'll almost always end up with a better app. To that end it might be better to think about it like a framework.


> I would include React in the framework camp. It isn't technically a framework but it goes far enough that it pushes you to write code in a specific way.

My litmus test to decide whether I'd personally classify something as a framework or library is to see what it's compared against and how people talk about it, as well as how they actually use it in a given scenario.

For example, people typically consider using either Angular, React or Vue for a project. Then, they talk about it very much like it is "an Angular project" or "a React project" because most of their code is limited to working within the confines of those (life cycles, state management, routing, patterns).

Does the fact that you could swap out one React statement management solution for another actually matter in that case for the distinction? It would... if anyone actually ever did that. Most people stick to whatever is the recommended option.

Same for the ability to run a whole Vue app under a specific div in a greater legacy site - in that case it would be treated more as a library... except that happens very rarely.

Then again, I don't really care about how strongly people care about these things, in my eyes one day the same codebase could be treated as a framework (a SPA in Vue with all of the mainstream packaged like router and Pinia, with hundreds of components and thousands of dev hours) and another as a lightweight library to be embedded into something else.


I believe when people consider using Angular or React they are simply not informed and make a mistake. I was in that camp myself. It’s important to be aware of what you are getting if you go with React, and what you are getting is a far cry from what a framework would offer, with all the corresponding pros and cons.


> It’s important to be aware of what you are getting if you go with React, and what you are getting is a far cry from what a framework would offer, with all the corresponding pros and cons.

Would you like to elaborate on that?

In my experience, with something as great, size/ecosystem-wise as React, there will almost always be at least one mainstream package for whatever you might want to do with it, that integrates pretty well. Where a lot of things might come out of the box with a framework, with a library I often find myself just needing to install the "right" package, and from there it's pretty much the same.

For example, using https://angular.io/guide/i18n-overview or installing and using https://react.i18next.com/

Or something like https://angular.io/guide/form-validation out of the box, vs installing and using https://formik.org/

Or perhaps https://angular.io/guide/router vs https://reactrouter.com/en/main

Even adding something that's not there out of the box is pretty much the same, like https://primeng.org/ or https://primereact.org/

React will typically have more fragmentation and therefore also choice, but I don't see those two experiences as that different. Updates and version management/supply chain will inevitably be more of a mess with the library, admittedly.

Now, projects like Next https://nextjs.org/ exist and add what some might regard as the missing pieces and work well if you want something opinionated and with lots of features out of the box, but a lot of those features (like SSR) are actually pretty advanced and not always even necessary.


There are a bunch of compatible packages, sure, I just meant what you are getting is not actually a proper Web framework, that’s all. It’s a reactive renderer library with another library (ReactDOM) that makes it work with DOM.


I imagine because the framework isn't working for the way they want to build things. That's a good reason to switch. Teams should pick the tech that aligns best with the way they want to work.

If they're switching for user-facing reasons it's likely that they're using just the framework poorly. Changing your own code is usually a much more effective way to get a perf boost than changing an underlying library.


Yes, but I was not interested in general reasons, but reasons with that theory "A framework is a way of aligning how you approach writing things. " in mind.


Take your pick: resume-driven development, Make Your Day Job Exciting Again, or thinking that switching frameworks will magically solve all your technical debt and inherent complexity


There's probably a couple of things missing from the early days - Flash - we quite often built components in flash to provide app-like experiences - the Browser Wars - how difficult it was sometimes just to reliably target a DOM element across browsers

But the most startling thing that's changed since the late-90s is the 'tooling industry' and just how complex the tooling has become, for arguably marginal benefit to the users of the web.


“The only software that I like is one that I can easily understand and solves my problems. The amount of complexity I'm willing to tolerate is proportional to the size of the problem being solved.“ Ryan Dahl - creator of nodejs


Proceeds to assist with the most unimaginably complex system known to man to solve fancy forms and partial refreshes.


Compared to what? Ruby? Python? .net? Java?

Maybe Go can claim to be simpler. But there are many runtimes that are popular and equally complex as nodejs.


Compared to not doing fancy forms and partial refreshes?

I know, I’ll let myself out.


Node.js is a server framework for quickly building small systems like server daemons with good performance and security. It's interesting how much over-engineered it has become (blaming JavaScript) considering that it's now mainly a compiler target for web frameworks.


It's so easy to blame JS though. I recently rediscovered that it can't do divide by zero right. And it even does it wrong in two different ways:

    > 1/0
    Infinity

    > 0/0
    NaN


JavaScript's behaviour in this case is consistent if we accept that JavaScript would always rather compute the next-best gibberish than throw an error.

While `1 / 0` is not a valid operation, it can be interpreted using limits. If `x` approaches 0, then `1 / x` will approach `Infinity`, hence JavaScript's result of this operation.

But with `0 / 0`, there is no unambiguous interpretation, so JavaScript defaults to `NaN` as its indicator for when a number is expected, but not received in valid form.

I'm not defending this behaviour of the language, just pointing out that there aren't "two different ways" of wrong behaviour at display here.


That's not the fault of JavaScript, but of IEEE-754 floating point math. The behavior you're seeing is per design.


That's a huge copout, and thankfully not one Python follows.


>"The amount of complexity I'm willing to tolerate is proportional to the size of the problem being solved."

I like this quote, it reminds me to another favorite of mine, the Sagan standard: "Extraordinary claims require extraordinary evidence"


In 2014 I wrote a "History of Web Programming" that's a good accompaniment to this article since it goes into some more detail on some of the older technologies:

https://www.observationalhazard.com/2018/06/history-of-web-p...


I'm the writer. I do not know how it blew up on HN but I thank OP for sharing and thank you all for reading.


I would say it does matter to the end user when they are in an area with poor network connectivity. The Astro web framework provides a good balance between interactivity and content-driven experiences. Being able to reuse components saves time, reduces the carbon footprint and conserving more joule of energy on million of devices. One of which I believe Reddit have recently make the switch.

You can see the impact we can make. A programmer's focus isn't just limited to following a straight line from start to finish and receiving their paycheck. Only poor soul like me are still out of job.


Although I like the article, I don't agree with the following statement in front-end:

> People rarely pick “the best tool for the job”. They say that. But what they mean is “the tool I’m familiar with the most”.

Front-end developers are the most eager to pick up any new (or hyped up) technology. Going from webpack to vite, going from npm to yarn, going from node to deno. Plus, I work with React developers, and most would also experiment with svelte etc.

They absolutely love to learn and use new technology. At least that's my experience.


It does matter.

When you write a gui, you want to think in a tree of component. Ie React.

If you want to print, you think in document (html, …). That’s also a tree by the way.

Html does not have any composability. They try hard to inject that in it (web component, jquery plugin, …)

React (ie virtual dom) is a beauty in this regard and if you don’t use it, you would have a hard time creating any gui with a certain level of difficulty.


We were creating many complicated yet great user experience frontends before React was even born, using server side template engines.

React makes development at scale of these things easier, and makes a website really a website (clicks are just triggering javascript instead of the classic post/get cycle that fetches new html). But it is completely unnecessary to build any level of GUI


People did, and do, create guis with very high complexity using desktop technologies, I can assure you we don't need React for that.


I don't agree that you need React or a vdom for composability. I remember a lot of server-side libraries with an API something like

    html(
      body(
        div(
          p("hello world"),
          class: "blah"
        )
      )
    )
where the tree was built using function calls. In such a system, HTML was often represented by an AST (or just a wrapper around a string!) and you could compose HTML together just by creating and calling a function.

This is what JSX/TSX are doing under the hood: they're transpiled to a call to React.createElement. You don't actually need them, though.


> React (ie virtual dom) is a beauty in this regard and if you don’t use it, you would have a hard time creating any gui with a certain level of difficulty

Anyone who didn’t grow up building stuff prior to 2010 would have difficulty.

we don’t need react in 2024. And it’s only making things worse now. Not better.


The jump from back-end to SPA and showing the example as yourdomain.com/any-thimg is a big give away. Remember Twitter et al with yourdomain.com/#/any-thing because the history API wasn’t a thing yet and the turmoil it caused when people realised this broke so much of the “new” web.


I would love to found mentioned "mootools" and "960.gs" in the article.


Haha I remember mootools being pretty big when plucky upstart JQuery appeared


at least the name was honest about library weight XD


I do web design like it's 1999.

I write the HTML. I upload the HTML. Works for me.

But that was a good article, it explains the rather odd and frankly underwhelming direction the web went in while I was out of it.


True, as long as the web developed page fits in the frame of the screen on the device of the user who does not care which framework, that does care about the users device, was used by the web developer caring about the readability of their framework generated framed content.


In my little corner of the universe people building small to medium sized web apps are dropping JS frameworks and going back to doing things server side with Rails or Laravel.

HotWire/LiveWire are then used for instant interactivity.

Is anyone else seeing people making that change?


Who here is old enough they first learned webdev from this? https://philip.greenspun.com/panda/


"Not much JavaScript was written."

There was no Javascript.


I think that part refers to the web around 2000. JavaScript was definitely around and being used in a limited extent similar to what the article describes at that point.


I talks about the simplest servers. We wrote those apps ~1993 and there was no Javascript. Then JS arrived for gimmicks (like display the time of day on a page) and later on was used to drive applications.


All the reasons the author lists is primarily why I've been preferring using web components to add interactivity to web pages only when the components need them. Nice thing about web components is that it's browser-native so it doesn't require any framework code to ship with it, and if you do prefer a framework, most modern frameworks have wrappers that work with web components.

We ended up building (yet another) framework dedicated to rendering web components (https://rootjs.dev). It uses JSX for rendering HTML on the server-side, but no JS code is rendered to the browser at all by default. Web components usage is auto-detected and automatically injected into the page as a dependency, which makes for really good developer ergonomics.


What's wrong with websites? Not everything needs to be a web application.


Thanks for sharing a great and fun-to-read piece! :-)


It’s the last paragraph which says it’s all.


What's up with the space before question marks? It's really distracting.


That's how it works in many languages. French being one for example (an unbreakable space before all double punctuation such as '?', '!', ':', ';', etc.). The author probably just isn't a native English speaker :).


Thanks for sharing that, I learn something new every day !


That's French-style punctuation. It doesn't distract me too much. According to LinkedIn the author is in Egypt but has the same (Arabic) name (modulo spelling) as a famous French footballer (and headbutter).




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

Search: