Remix.run Logo
imiric 2 days ago

> If you listen to people actually building frameworks (Solid, Preact, Vue, Svelte), you'll learn that "modern web features" have very few actual features that make development easier.

That depends on the subjective definition of "easier", but most of these frameworks use abstractions that are too complex and not worth the value they deliver. They ironically make development more difficult, since there are more moving parts, more concepts to understand, and more things to break, which in turn makes the user experience much, much worse.

The entire idea of writing fake HTML that gets parsed, compiled, and interpreted in JavaScript to manipulate the DOM at runtime is wrong. The concept of a virtual DOM, diffing, reconciliation, and a bunch of related nonsense, is wrong. The insanity of an entire ecosystem of tools built around solving client-side state management. The trend of moving everything, including CSS, to be interpreted in JS is insane. Abstractions like Tailwind that shouldn't exist in the first place, which are then further abstracted away by abominations like daisyUI. The numerous frameworks that promise to blur the line between frontend and backend development, only to fall flat on their face when the insanity of the approach becomes apparent, but not before amassing a significant user base in the process. The fact most web developers have accepted that 100MB+ of dependencies are required to show a "Hello World!" in a web browser. The idea that every web site must be a SPA, and the numerous hacks around that to make it work like a traditional web site. I could go on, and on...

The popularity of these tools and ideas is not an indication that they lead to a sane, let alone optimal, development environment. It just means that the field has become dominated by influencer developers, to the point that junior developers entering the field are not aware of other ways of building web applications. After all, React and Vue stand out in a CV much more than JavaScript. It's practically unheard of to be considered a web developer without having one of these frameworks under your belt, so it becomes a reinforcing loop.

> It hasn't. At least not in the direction you want.

That's not true. JavaScript in web browsers is a stable, modern language. HTML has received numerous transformative updates over the years, such as the `template` element we're discussing here. The evolution of CSS has been mind-boggling, and difficult to keep track of. Gone are the cross-browser quirks and incompatibilities, which is mostly due to Google dominating the web, but that's beside the point. Web servers have become more flexible and easier to deploy. And so on.

Frameworks like Datastar prove that web development can be much simpler, and deliver better user experiences in a fraction of the complexity of traditional frameworks. This is not because it reinvents the same abstractions used elsewhere, but because it takes a first principles approach and rejects building on top of the existing pile of abstractions. It leverages proven technologies such as Server-Sent Events, and doesn't reinvent the wheel. If you've seen the demos and examples, the results speak for themselves.

It's not difficult to imagine a similarly simplified workflow becoming standard across web clients and servers. All it would take is an industry-wide push to bring all existing technologies together in a cohesive package. We're not technically far from that, so frameworks like Datastar are still needed, but we definitely don't need the bloated frameworks of yore.

troupo a day ago | parent [-]

> The entire idea of writing fake HTML that gets parsed, compiled, and interpreted in JavaScript to manipulate the DOM at runtime is wrong.

Because there's nothing in the web standards to do it otherwise.

> The concept of a virtual DOM, diffing, reconciliation, and a bunch of related nonsense, is wrong.

Of the frameworks I mentioned none use virtual DOM or diffing. They have all moved to a much more efficient way that is, guess what, on a way to become a native browser standard: https://github.com/tc39/proposal-signals

> The insanity of an entire ecosystem of tools built around solving client-side state management.

Any time you have a dynamic UI, you have state management. I wish the web remained static, but that ship has sailed long ago. And there's nothing in web standards that helps with state management.

> It just means that the field has become dominated by influencer developers, to the point that junior developers entering the field are not aware of other ways of building web applications.

It's strange how you completely dismissed Solid, Vue, and Svelte which all offer a different way to build web apps when compared to React, for example.

> JavaScript in web browsers is a stable, modern language.

You need more than just a language. You also need libraries and actual useful functionality exposed by the browsers.

Literally the whole reason so many libraries and frameworks have popped over the years, is because no one wants to spend time writing hundreds of lines of code just to properly set up and change some DOM element. And the reason very few libs/frameworks (even newcomers) use "the amazing new features in the browsers" is because these features have a list of features issues and caveats a mile long. Here's just one single example: https://x.com/Rich_Harris/status/1841467510194843982

> HTML has received numerous transformative updates over the years, such as the `template` element we're discussing here.

And what, pray tell, does template give you? On its own it's useless. You need some JS to manipulate it, at least.

> but because it takes a first principles approach and rejects building on top of the existing pile of abstractions.

Didn't you just say this: "The entire idea of writing fake HTML that gets parsed, compiled, and interpreted in JavaScript to manipulate the DOM at runtime is wrong. "?

What do you think Datastar is doing if not literally the same thing. How do you think this works:

    <div data-signals="{counter: 0, message: 'Hello World', allChanges: [], counterChanges: []}">
    <div class="actions">
        <button data-on-click="$message = `Updated: ${performance.now().toFixed(2)}`">
            Update Message
        </button>
        <button data-on-click="$counter++">
            Increment Counter
        </button>
        <button
            class="error"
            data-on-click="$allChanges.length = 0; $counterChanges.length = 0"
        >
            Clear All Changes
        </button>
    </div>
    <div>
        <h3>Current Values</h3>
        <p>Counter: <span data-text="$counter"></span></p>
        <p>Message: <span data-text="$message"></span></p>
    </div>
    <div
        data-on-signal-patch="$counterChanges.push(patch)"
        data-on-signal-patch-filter="{include: /^counter$/}"
    >
        <h3>Counter Changes Only</h3>
        <pre data-json-signals__terse="{include: /^counterChanges/}"></pre>
    </div>
    <div
        data-on-signal-patch="$allChanges.push(patch)"
        data-on-signal-patch-filter="{exclude: /allChanges|counterChanges/}"
    >
        <h3>All Signal Changes</h3>
        <pre data-json-signals__terse="{include: /^allChanges/}"></pre>
    </div>
  </div>
It does (ab)use the browser for the preliminary parsing, but then it does what everyone else does (only probably worse). E.g. by literally parsing attribute contents to reimplement half of Javascript for "reactive expressions": https://github.com/starfederation/datastar/blob/develop/libr...
imiric 21 hours ago | parent [-]

> Because there's nothing in the web standards to do it otherwise.

Sure there is. We've been manipulating the DOM with JavaScript since the dawn of the web, which later projects like jQuery made more ergonomic. There are a bunch of JS libraries that simplify working with the DOM without resorting to writing fake HTML in JavaScript.

> Of the frameworks I mentioned none use virtual DOM or diffing. They have all moved to a much more efficient way

Oh, right, observables are the way to go. No, wait, hooks are the right approach. No, wait, signals are definitely the future.

We expect these trend-chasers to define the future of the web? Give me a break.

> Any time you have a dynamic UI, you have state management.

That's true, but state management became such a big problem because of the trend of SPAs and fat clients. A lot of this complexity can be mitigated by relying on the server more. At some point, developers became obsessed about not making a traditional HTTP request that would do a full page refresh, and libraries and frameworks sprung to resolve issues that were largely self-imposed.

Add to that the ever-evolving nature of the JS ecosystem, and developers constantly one-upping each other and chasing trends, which boils down to the insanity I'm talking about.

> It's strange how you completely dismissed Solid, Vue, and Svelte which all offer a different way to build web apps when compared to React, for example.

I checked out from keeping track of frontend frameworks years ago. FWIW, I did try early versions of Svelte, and enjoyed the DX, but at the end of the day, the apparent simplicity was a facade that hid insane amounts of black magic in the background to make all of it work. These days with SvelteKit and the changes in Svelte 5, it feels like just another React clone.

I have recent experience with Vue, and it is the epitome of everything wrong with modern web development. I just didn't have the time and energy to address it specifically.

Again, my issue is not with specific frameworks, but with the whole concept that developers need such behemoth frameworks to build web sites.

> Literally the whole reason so many libraries and frameworks have popped over the years, is because no one wants to spend time writing hundreds of lines of code just to properly set up and change some DOM element.

That's a strawman. As you can see in this very thread, there are examples of people building advanced interactive web sites without much boilerplate or abstractions. For the remaining rough edges that you may not want to deal with yourself, there are libraries and lightweight frameworks you can choose from. You're not forced to use a monolithic framework. Frameworks are a popular choice because they're trendy, but there are plenty of much simpler alternatives.

> Here's just one single example

Ah, I'm sure authors of popular frontend frameworks are fair and unbiased...

Look, the current web standards, and Web Components in particular, aren't perfect. I'm certainly not a fan of some of the design decisions. But they're tools that in conjunction cover a large amount of functionality that modern web frameworks simply ignore or reinvent. This is what I'm saying is a mistake.

> And what, pray tell, does template give you? On its own it's useless. You need some JS to manipulate it, at least.

`template` is just one building block. You can use it alongside others to do things frameworks can do, except... without a framework! What a concept, I know.

> What do you think Datastar is doing if not literally the same thing.

It's not the same thing. That code is standard HTML with JS in data attributes that does get interpreted at runtime, but it's not an HTML-like DSL that gets parsed and compiled into JavaScript—it is HTML.

To be clear: I haven't used Datastar, nor dug into its internals. I'm personally not a fan of abusing HTML attributes with JS logic like that, and I prefer how old school frameworks like Backbone and Knockout handle this. My frustrating experience with Vue was partly what motivated me to think about and come up with my own approach, which I linked to above, if you're curious.

palmfacehn 18 hours ago | parent | next [-]

>That's true, but state management became such a big problem because of the trend of SPAs and fat clients.

I find it strange that so many developers struggle to maintain the state of a page. Then they turn to "magic" frameworks to handle it for them. What's wrong with having a canonical Object or other data structures to represent the state? Why would anyone want a generalized framework to (mis)represent the core model of your application?

We've been creating applications with internal state for decades now. GUI applications with an internal state existed before the web. Typically it is achieved via code hygiene and sane abstractions. As an example, the template element keeps your document structure out of your logic.

Yet in the modern JS world, display, state and now even the backend are all shoveled together into an unmanageable monstrosity. From this point, even more magic is added to duct tape over the madness. As a result, the accepted norm is now 10mb of cruft to display a static page.

troupo 18 hours ago | parent [-]

State was never easy. GUI apps have struggled with this as well. Hence you have the proliferation of different approaches: MVC, MVVM, various attempts at streams and observables, state machines, flows... All of these came from outside the web world. And, as most things in the web, all these concepts either arrived too late, or couldn't be implemented properly for various reasons.

And the problem is exacerbated by the fact that people are trying to push native app paradigms onto what is still a document-rendering system. So where you can have thousands of objects rendered at 120Hz on a mobile phone, the web struggles showing and animating a few hundred nodes even on a desktop computer. So you have to think of all the machinery to change as few DOM nodes as possible.

--

As for the difficulty...

The difficulty usually comes from people mixing up two concepts: the state of data, and the state of the UI.

E.g. while a music player should present data on the currently playing song (state of data), there's a few other things that are UI-only. E.g.: there's a timer running on when to hide the controls (that has to be reset/disabled when a button is pressed)

palmfacehn 17 hours ago | parent [-]

>GUI apps have struggled with this as well

And when we made mistakes there, it was usually because we took short cuts instead of respecting clean abstractions.

>So you have to think of all the machinery to change as few DOM nodes as possible.

This is where I get off the train in regards to JS frontend frameworks. We should know the state our data. We should also know the state of our display components, whether they are canvas elements rendering more complex data or mere tables. KISS principles apply here.

"All the machinery" of a framework isn't necessary to handle the synchronization between the two. Especially when it mandates ridiculous build steps, thousands of dependencies, opaque "magic", huge blobs of minified JS and loading spinners.

>The difficulty usually comes from people mixing up two concepts: the state of data, and the state of the UI.

Agreed 100%. Which is why I like the <template> element. It is a dose of sanity allowing explicit separation of code and document. I suspect this is the other poster's objection to HTML inside of JS.

troupo 18 hours ago | parent | prev [-]

> there are a bunch of JS libraries that simplify working with the DOM without resorting to writing fake HTML in JavaScript.

The problem with arbitrary lines is that they are arbitrary: there are no criteria for them except your gut feeling.

You can't rant against "fake HTML" and then turn around and talk about a framework that uses fake JS inside its non-fake HTML.

> Oh, right, observables are the way to go. No, wait, hooks are the right approach. No, wait, signals are definitely the future.

1. It's called evolution. We don't know all the best solutions from the get go.

2. Guess what datastar is using underneath.

Honestly, I don't know if I should continue at this point as you clearly have literally no idea about what you're talking about. You "checked out" from keeping track, you haven't used Datastar or dug into its internals, you call literal verifiable facts a biased outlook from a framework developer etc.

> Look, the current web standards, and Web Components in particular, aren't perfect. I'm certainly not a fan of some of the design decisions. But they're tools that in conjunction cover a large amount of functionality that modern web frameworks simply ignore or reinvent. This is what I'm saying is a mistake.

Just a few issues with this "tool" that is not perfect, but must be used. Note, this tool has been in development for 14 years this year, and literally none of the "huge bloated frameworks" have this issue. Note that all of these are from the Web Component Working Group report. They themselves wrote about these issues. And these all are issues that "biased" framework developers had been talking for literal years before this report even saw the light of day:

- ARIA is broken. Needs a separate huge JS-only specification that is only now being slowly developed: https://w3c.github.io/webcomponents-cg/2022.html#cross-root-... See a larger description of the issue here: https://nolanlawson.com/2022/11/28/shadow-dom-and-accessibil...

- CSS cascade and theming is broken. Needs several new specs to function, many of them JS-only, some already shipped, some still just being developed: https://w3c.github.io/webcomponents-cg/2022.html#constructab... and https://w3c.github.io/webcomponents-cg/2022.html#css-module-... and https://w3c.github.io/webcomponents-cg/2022.html#css-propert... and https://w3c.github.io/webcomponents-cg/2022.html#custom-css-... and ...

- Document selection is broken https://w3c.github.io/webcomponents-cg/2022.html#composed-se...

- Form participation is broken as it requires additional Javascript per each component to just participate in forms. Buttons inside shadow roots still cannot function as submit buttons: https://w3c.github.io/webcomponents-cg/2022.html#form-associ... and https://github.com/WICG/webcomponents/issues/814

And that's before we get into how they break many other things. Like the fact (that you labeled as biased) that using custom elements-aware APIs leads to a 30% drop in performance.

> `template` is just one building block. You can use it alongside others to do things frameworks can do, except... without a framework! What a concept, I know.

And end up making your own lib/framework in the process. Unless, of course, you want to pretend that all the issues above are nothing to talk about.

> That code is standard HTML with JS in data attributes that does get interpreted at runtime, but it's not an HTML-like DSL that gets parsed and compiled into JavaScript—it is HTML.

That's not JS, and it's not interpreted at runtime. It's painstakingly parsed with regexes, and then certain code is executed based on the result of that parsing.

Somehow "fake HTML" is a no-no, but fake JS? Yeah, go ahead.