Skip to content

Why the Same Frontend Ideas Return Under New Names

Signals, HTML over the wire, utility classes. Each one is older than the hype cycle selling it, and the rerun tells you exactly what to check first.

· · 8 min read
Library shelves filled floor to ceiling with books from many different decades

Quick Take

Three of the loudest frontend ideas of the last five years are reruns. Knowing which constraint changed between the first airing and this one is the difference between adopting on evidence and adopting on fashion.

Quick take: Fine-grained reactivity, HTML over the wire, and utility-first CSS are all second or third runs of ideas that were mainstream years earlier. That is not a criticism. The useful move is to ask which constraint changed between the two runs. If a specific limit was removed (Proxy landing in ES2015, HTTP/2 multiplexing, native CSS nesting), the return is technical. If nobody can name one, it is fashion, and it will leave the same way it did last time.

I've been writing code for the web since the mid-nineties, and the strangest part of a long run isn't watching things change. It's watching them come back. Not similar things. The same thing, with a different name, argued by people who are certain it's new, sometimes with the exact objections from the previous round repeated as fresh insight.

That sounds like a complaint. It isn't one. Why would a rerun be bad news? A returning idea is the single most useful thing you can be handed, because the first run already generated years of production evidence about what the idea costs. You just have to know you're looking at a rerun.

Loop One: Fine-Grained Reactivity Became Signals

Knockout.js was released on 5 July 2010 by Steve Sanderson. Its core primitive was the observable: a value you read through a function call, which tracks who read it and re-runs exactly those readers when it changes. No diffing. No component re-render. The pattern came from MVVM, which .NET developers already knew from WPF and Silverlight.

Read that description again and tell me it isn't a signal. It is a signal, down to the dependency tracking.

Then Knockout lost, mostly to AngularJS and then to React, and the industry spent roughly a decade with a different model: re-run the component, diff the output, patch the DOM. Fine-grained reactivity became a thing old people mentioned.

Then it came back, and quickly:

ReleaseDateWhat it called the idea
Knockout, initial release5 July 2010Observables
Mobservable, renamed MobX in 20162015Observables
Solid 1.028 June 2021Signals
Preact Signals6 September 2022Signals
Angular v16May 2023Signals (developer preview)
TC39 proposal2024Signals (Stage 1)

So what actually changed? Three things, and all three are nameable. Proxy shipped in ES2015, which removed the need to wrap every value in an explicit observable() call and made the ergonomics tolerable. Compilers got good enough to rewrite template code, so the reactivity graph could be built at build time rather than assembled by hand. And by around 2020 there was enough production telemetry to argue that re-render-and-diff has a real cost at scale, rather than a theoretical one.

Three named constraints, all removed. That's what a legitimate return looks like.

Loop Two: HTML Over the Wire Never Actually Left

The web started by sending HTML. Then it sent HTML with a bit of script. Then, for about a decade, the respectable answer was to send JSON and build the HTML in the browser, and anything else was legacy.

I spent a long stretch of my career in PHP, which is where most of the working web genuinely lived while frontend conferences pretended otherwise. The model there was simple: the server owns the markup, the browser renders it. When single-page applications arrived, that model wasn't refuted, it was declared unfashionable.

Look at what came back. Carson Gross started intercooler.js in 2013 to do partial updates with HTML attributes; he rewrote it without the jQuery dependency and released it as htmx on 24 November 2020. Rails shipped Turbo the same year. And React announced zero-bundle-size Server Components on 21 December 2020, taking four years to reach stable in React 19 on 5 December 2024.

Three separate projects, three separate communities, one idea: the server produces markup, the client swaps it in.

The constraint that changed is HTTP. Under HTTP/1.1 with six connections per host, chatty partial updates were genuinely expensive, which is a large part of why bundling everything into one payload won. Multiplexing and streaming responses removed that penalty. If you want the implementation detail rather than the history, React Server Components in TypeScript covers the current shape of it.

Is the returning version identical? No, and that matters. Server Components stream a serialized component tree rather than raw markup, and they compose with client components in a way intercooler never attempted. The idea returned; the implementation learned something.

Loop Three: The Styling Pendulum Keeps Swinging Back

This one is the clearest, because the swings are documented.

Global stylesheets came first, and their problem was always the same: no scoping. Thierry Koblentz argued the utility-class answer publicly in Smashing Magazine in October 2013, under the name atomic CSS, and got roundly told it was inline styles with extra steps. CSS Modules took the scoping route in 2015. styled-components took the runtime route in 2016. Tailwind shipped its first public alpha on 1 November 2017 and won the argument Koblentz had lost four years earlier with substantially the same technique.

Then the pendulum moved again. styled-components entered maintenance mode on 17 March 2025, with its maintainer saying outright that he wouldn't recommend it for new projects. Meanwhile the browser grew the features the libraries existed to supply: native CSS nesting versus Sass is now a real comparison rather than a joke, cascade layers give you the ordering control that specificity wars used to need, and container queries solved component-scoped responsiveness without a JavaScript runtime.

Notice the pattern. Every styling library of the last fifteen years was a polyfill for something the platform lacked. So what's left once the platform ships that thing? Ergonomics, and ergonomics alone doesn't survive a maintainer burning out.

How Long the Gaps Actually Are

Years from first mainstream airing to return Fine-grained reactivity (Knockout 2010 to Solid 1.0 2021) 11 yrs HTML over the wire (intercooler 2013 to htmx 2020) 7 yrs Utility-first CSS (atomic CSS 2013 to Tailwind 2017) 4 yrs Dates: Knockout 05 Jul 2010, Solid 1.0 28 Jun 2021, htmx 24 Nov 2020, Tailwind v0.1 01 Nov 2017

Four to eleven years. That's short enough that the people who lived through the first run are still working, and long enough that most of the room hasn't heard of it. Which is exactly why the reruns keep getting sold as debuts.

The Test This Gives You

One question, asked before adopting anything that feels new: which constraint changed?

A legitimate return names something specific and checkable:

  • A browser API shipped (Proxy, container queries, view transitions)
  • A protocol changed (HTTP/2 multiplexing, streaming responses)
  • A compiler became viable where hand-writing wasn't
  • A cost moved from theoretical to measured

A rebrand can't answer. It'll tell you about developer experience, or that the old version was "before its time", which is a sentence that means nothing. When I hear that phrase in a conference talk now, I stop taking notes.

The second question is cheaper and more useful: what killed it last time, and is that thing fixed? Knockout didn't die because observables were wrong. It died partly because writing observable() around everything was miserable, and Proxy fixed exactly that. If you can trace the fix, you're on solid ground. If the answer is that the old version was unfairly maligned, walk away.

The Prediction I'll Be Held To

Here's where you're welcome to disagree with me, and plenty of people do.

The returning idea almost never wins outright. It gets absorbed. Observables came back; Knockout didn't. HTML over the wire came back; nobody's rewriting their application in intercooler. Utility classes came back and then immediately started ceding ground to native CSS features.

So I'd bet against a signals-based core in React this decade. Not because signals are wrong, they're clearly good, and Solid and Angular have proved it. But React's value was never its reactivity model, it was the component contract that thousands of libraries were written against, and that contract is what makes a core rewrite unaffordable. React will absorb the parts it can and keep re-rendering. Which is roughly what jQuery did with its competitors' ideas for a decade after everyone announced it was finished.

Bet the other way if you like. Just make sure you can name the constraint that changed, because "everyone's excited about it" was also true in 2010, and it wasn't a reason then either. If you want the same lens applied to bundle weight rather than architecture, the three pillars of JavaScript bloat is the measured version of this argument.

The frontend doesn't move in a line. It moves in loops, and each loop returns with better tooling and the same trade-offs. Knowing which loop you're standing in is most of the skill.

Frequently Asked Questions

Are signals a new idea in JavaScript?
No. Knockout.js shipped observables with automatic dependency tracking on 5 July 2010, and the pattern came from MVVM in WPF and Silverlight before that. What is new is the surrounding machinery: Proxy landed in ES2015, compilers got good enough to rewrite template code, and enough production data existed by 2021 to argue that virtual DOM diffing has a measurable cost. Solid 1.0 arrived in June 2021, Preact Signals in September 2022, Angular signals as a developer preview in v16 in May 2023, and a TC39 proposal reached Stage 1 in 2024.
Is htmx just server-side rendering with extra steps?
It is server-rendered HTML delivered over an XHR instead of a full page load, which was the model before single-page applications and is the model Rails and PHP shops never fully left. htmx was first released on 24 November 2020 as a rewrite of intercooler.js, which Carson Gross started in 2013. The reason it works better now than in 2013 is that HTTP/2 multiplexing and streaming responses removed the request-count penalty that made partial updates expensive.
How do I tell a returning idea from a genuinely new one?
Ask which constraint changed since the last time the idea was tried. A real return names a specific removed limitation: a browser API shipped, a protocol changed, a compiler became viable, or a cost that was theoretical became measurable. If nobody can name the constraint, you are looking at a rebrand, and a rebrand is a fashion signal rather than a technical one.
Did CSS-in-JS lose to utility classes?
Both were answers to the same problem, which is that global CSS has no scoping. Atomic CSS was argued publicly by Thierry Koblentz in Smashing Magazine in October 2013, Tailwind shipped its first public alpha on 1 November 2017, and styled-components entered maintenance mode on 17 March 2025. The deciding factor was not aesthetics. It was that the browser grew native nesting, cascade layers, and container queries, so a runtime that generated scoped CSS had less left to do.
Does this mean I should ignore new frontend trends?
The opposite. Recognizing a rerun tells you where the evidence already exists, because the first airing produced years of production experience about what the idea costs. Read the postmortems of the earlier version before you read the marketing for the current one. The failure modes usually survive the rename even when the ergonomics do not.