12 ms·
Having a server provide an island or rendering framework for your site can be more complex than an SPA with static assets and nginx. You still have to deal wit
by qudat 1y ago
Having a server provide an island or rendering framework for your site can be more complex than an SPA with static assets and nginx.
You still have to deal with all the tooling you are talking about, right? You’ve just moved the goalpost to the BE.
And just like the specific use cases you mentioned for client routing I can also argue that many sites don’t care about SEO or first paint so those are non features.
So honestly I would argue for SPA over a server framework as it can dramatically reduce complexity. I think this is especially true when you must have an API because of multiple clients.
I think the DX is significantly better as well with fast reload where I don’t have to reload the page to see my changes.
People are jumping into nextjs because react is pushing it hard even tho it’s a worse product and questionable motives.
- freeone3000 1y agoBut on the flip side, you can program the backend in anything you like, instead of being bound to javascript.
- sroussey 1y agoJS/TS is fine. Why switch back and forth between languages and frameworks and data models and…
- baq 1y agoIf your axiom is ‘JS is fine’ then yeah. It isn’t, though. TS is much closer to ‘fine’, but still can’t avoid some dumb JS decisions.
- chipsrafferty 1y agoIt is fine, though.
- const_cast 1y agoNo, it’s footgunny and riddled with bugs. Most JS barely works and edge cases just aren’t addressed. I’ve seen undefined make it all the way to the backend and get persisted in the DB. As a string. JS as a language just isn’t robust enough and it requires a level of defensive programming that’s inconvenient at best and a productivity sink at worst. Much like C++, it’s doable, but things are bound to slip through the cracks. I would actually say overall C++ is much more reasonable.
- Capricorn2481 1y ago> I would actually say overall C++ is much more reasonable. This is where I know that, some people, are not actually programming in either of these languages, but just writing meme driven posts. JS has a few footguns. Certainly not so many that it's difficult to keep in your head, and not nearly as complex as C++, which is a laughable statement. You've "seen null make it to the database," but haven't seen the exact same thing in C++? Worse, seen a corrupted heap?
- hombre_fatal 1y agoYeah, I don't know how someone can say that with a straight face to other engineers. It's like people just talk in memes or something. This is how a lot of discourse feels these days. People living in very different realities. Though in this case, seeing the most complex C++ app they've built would illuminate what's going on in theirs.
- const_cast 1y agoIt's not a different reality. To give perspective to what JS I've dealt with - I worked a couple years on a legacy webapp. It used vanilla JS and the only library used was jQuery. It heavily used iframes for async functionality in combination with XSLT to translate backend XML apis to HTML. Opening up a 10K lines JS file is like jumping into the ocean. Nothing is obvious, nothing makes sense. You're allowed to just do whatever the fuck in JS. Bugs where always ephemeral. The behavior of the code was impossible to wrap your head around, and it seemed to change under your feet when you weren't looking. Now, the backend was written in old C++. And yes, it was easier to understand. At least, I could click and go to definition. At least, I could see what was going in and out of functions. At least, I could read a function and have a decent understanding of what it should be doing, what the author's intention is. The front end, spread across a good thousand JS files, was nothing of the sort. And it was certainly more buggy. Although, I will concede, bugs in C++ are usually more problematic. In JS usually it would just result in UI jankyness. But not always.
- CuriouslyC 1y agoI've been a professional programmer for ~20 years and worked in a variety of languages on a variety of different types of projects, and Typescript with Bun is mostly just fine. It lacks some low level primitives I'd like to have available for certain projects (e.g. Go channels), and the FFI interface isn't as nice as I'd like, but it's basically serviceable for for a very broad range of problems. You should still know a language like Rust or Zig for systems work, and if you want to work in ML or data management you probably can't escape Python, but Typescript with Bun provides a really compelling development experience for most stuff outside that.
- baq 1y agoI agree, nowadays working on mostly TS backend with some parts in JS written before async/await was introduced and I’m inclined to say TS is better than Python at most things bakcendy. I’m missing sqlalchemy and a sane numerical tower pretty much.
- freeone3000 1y agoPython suffers from the same problems: its type system has many escapes and implicit conversions, making soundness opt-in and impossible to statically verify. Any language with an implicit cast from its bottom type to an upper type is unsuitable for use.
- AlchemistCamp 1y agoIt reminds me of an older dev I met when I was just beginning who had worked even more years and said Fortran 95 was "fine". And he could use it to build pretty much anything. That doesn't mean that more powerful language features couldn't have increased his productivity (if he learned them).
- CuriouslyC 1y agoThere's something to be said for using the right tool for the job. There's also something to be said for maximizing your ability to hire developers. Software is a game of tradeoffs, and while I can and do still pick up modern hotness when warranted (e.g. Zig), sometimes the path to minimum total software cost (and thus maximum company value) is to take well trodden paths. As fun side anecdote, if you're doing scientific computing in a variety of fields, Fortran 95 is mostly still fine ;)
- hjgjhyuhy 1y agoIf you already know another backend language and framework, all you need to do is tell LLM or some code generator to convert your models between languages. There is very little overhead that way. I greatly prefer Java with Spring Boot for larger backend projects.
- aweiland 1y agoWhat is 0.1 + 0.2 in JavaScript. I'll give you a hint, it's not 0.3. Is that fine?
- viraptor 1y agoThat's not a JavaScript issue. It's the same for almost any language where you don't use some bignum type/library. This is something all developers should be extremely aware of.
- baq 1y agohttps://en.m.wikipedia.org/wiki/IEEE_754 https://en.m.wikipedia.org/wiki/IEEE_754 To answer your question directly - yes, it’s fine, it’s actually expected behavior.
- SJC_Hacker 1y agoYou haven’t had to deal directly with JS on front end since Dart released over 10 years ago
- freeone3000 1y agoDart hasn’t been much better in my experience, but you have reminded me to revisit Kotlin/JS!
- freeone3000 1y agoI tried getting json deserialization into my app and ended up with a 2MB runtime, so it’s not going great.
- catgirlinspace 1y agoDoes anyone use Dart without Flutter? I've never seen it used separately.
- SJC_Hacker 1y agoYeah sorry I meant Flutter ... 99% of people use Dart with Flutter, they are basically synonymous
- yawaramin 1y agoNo, you still need to deal directly with JS even with a transpiler like Dart or whatever other language you want to use. When things go wrong, and they will, you'll need to deal with the JS errors. When you're trying to debug or even call out to JS APIs, you better be intimately familiar with how your transpiler interops with JS, otherwise you're kinda screwed.
- stavros 1y agoI disagree, the problem with an SPA is that now you have two places where you manage state (the backend and the frontend). That gives you much more opportunity for the two places to disagree, and now you have bugs.
- procaryote 1y agoYou had to manage state on the frontend even before spa though, if you wanted anything but the most basic experience.
- stavros 1y agoNot between page loads.
- tomnipotent 1y agoYou absolutely did. It was common practice to stuff things in cookies or query strings to retain state between trips to the server so that some JS could do its job. Every form also normally ends up duplicating validation logic both in JS for client-side pre-submit UX and server-side with whatever errors it returns for the JS to then also need to support and show to the user.
- stavros 1y agoRight, but validation logic and state transferred by the server isn't in-memory state. The fact that the pages completely reload on each request clears a lot of cruft that doesn't get cleared on pages whose lifetime is tens or hundreds of views.
- tomnipotent 1y agoEvery SPA I come across, especially when using React, uses persistent state so that in-memory changes are synced to cookie/localStorage/server so they survive refreshes. Every popular state management library even supports this natively. And all of that state combined still requires less memory than any of the images loaded, or the JS bundles themselves.
- throwaway7783 1y agoI have repeated this elsewhere. APIs for UI tend to diverge from APIs in general in practice. For applications that are not highly interactive, you don't quite need a lot of tooling on the BE, and since need to have a BE anyway, a lot of standard tooling is already in there. React style SPAs are useful in some cases, but most apps can live with HTMX style "SPA"s
- whatnow37373 1y agoAgreed. We started with one API to rule them all. What happened? Now we got two.. and now we have to communicate like this: “So the backend gave this weird …” “What backend?” “The backend for the frontend…” “So not the backend for the backend for the frontend?” I jest, but only very slightly.
- throwaway7783 1y agoExactly. And state is in two places now. It's like building two applications and trying to somehow keep them in sync.
- recursivedoubts 1y agohttps://htmx.org/essays/splitting-your-apis/ https://htmx.org/essays/splitting-your-apis/
- qudat 1y ago> APIs for UI tend to diverge from APIs in general in practice. I'm arguing to just use a single API, not creating one for UI, at least when you want things to be simple for multiple clients.
- __abc 1y agoIf you truly need for MVC to manage all things state, component communications, and complex IxD in the front-end, sure, but not every app has that level of front-end complexity to warrant a SPA, in my opinion.
- 0cf8612b2e1e 1y agoI think the DX is significantly better as well with fast reload… As a user, the typical SPA offers a worse experience. Frequent empty pages with progress bars spinning before some small amount of text is rendered.
- zozbot234 1y ago> As a user, the typical SPA offers a worse experience. Your typical SPA has loads of pointless roundtrips. SSR has no excess roundtrips by definition, but there's probably ways to build a 'SPA' experience that avoids these too. (E.g. the "HTML swap" approach others mentioned ITT tends to work quite well for that.) The high compute overhead of typical 'vDOM diffing' approaches is also an issue of course, but at least you can pick something like Svelte/Solid JS to do away with that.
- eastbound 1y agoRequires additional engineering.
- boomskats 1y ago> Your typical SPA has loads of pointless roundtrips This is an implementation choice/issue, not an SPA characteristic. > there's probably ways to build a 'SPA' experience that avoids these too PWAs/service workers with properly configured caching strategies can offer a better experience than SSR (again, when implemented properly). > The high compute overhead... I prefer to do state management/reconciliation on the client whenever it makes sense. It makes apps cheaper to host and can provide a better UX, especially on mobile.
- apothegm 1y agoExcept for a user on a lower specced device that can’t performantly handle filtering and joining on that mass of data in JS code, or perhaps can’t even hold the data in memory.
- 1y ago
- switz 1y agoSo here's the kicker: React Server Components don't need a server. They are completely compatible with a static bundle and still provide major benefits should you choose to adopt them (dead code elimination, build-time execution). This is effectively the design of Astro Islands, natively in React Server Components. Letting you write static and client-side dynamic code in a single paradigm through componentization and composition. If you are curious, my most recent blog post is all about this concept[0] which I wrote because people seem to be misinformed on what RSCs really are. But that post didn't gain any traction here on HN. Is it more complex? Sure–but it is also more powerful & flexible. It's just a new paradigm, so people are put off by it. [0] Server Components Give You Optionality https://saewitz.com/server-components-give-you-optionality https://saewitz.com/server-components-give-you-optionality
- chipsrafferty 1y agoThen they are poorly named.
- switz 1y agoI generally agree. Naming things is among the hardest problems in computer science
- dmix 1y agoThe obsession with DX tooling is exactly why JS is such an awful developer experience. They always chase something slightly better and constantly change things. Maybe the answer was never in JS eating the entire frontend, and changing the tooling won’t make it better, as it’s always skirting what’s actually good for the web.
- pier25 1y ago> The obsession with DX tooling is exactly why JS is such an awful developer experience. I used to agree but these days with Vite things are a lot smoother. To the point that I wouldn't want to work on UI without fine-grained hot reloads. Even with auto reload in PHP, .NET, etc you will be wasting so much time. Especially if you're working on something that requires interaction with the page that you will be repeating over and over again.
- ivan_gammel 1y agoEh, I recently stumbled into an open bug in Npm/vite and wasted two days before just reinstalling everything and re-creating frontend app. Hot UI reloads are cool, but such things kill any productivity improvements.
- dmix 1y ago> Especially if you're working on something that requires interaction with the page that you will be repeating over and over again. That’s honestly not that many things IRL. If you look at all the things you build only a minority actual demand high interactivity, or highly custom JS. Otherwise existing UI libraries cover the bulk of what people actually need to do on the internet (ie, not just whatever overly fancy original idea the designers think is needed for your special product idea). It’s mostly just dropdowns and text and tables etc. Once you try moving away from all of that and questioning if you need it at every step you’ll realize you really don’t. It should be server driven web by default with a splattering of high functionality islands of JS. That’s what rails figured out after changing the frontend back and forth. > Even with auto reload in PHP, .NET, etc you will be wasting so much time Rails has a library that will refresh the page when files change without a full reload, using Turbo/Hotwire. Not quite HMR but it’s not massively different if your page isn’t a giant pile of JS, and loads quickly already.
- whatnow37373 1y ago> dramatically reduce complexity If you ever worked seriously on anything non-SPA you would never, ever claim SPAs “dramatically reduce complexity”. The mountain of shit you have pull in to do anything is astronomical even by PHPs standards and I hate PHP. Those days were clean compared to what I have to endure with React and friends. The API argument never sat well with me either. Having an API is orthogonal: you can have one or do not have one, you can have one and have a SSR app. In the AI age an API is the easy part anyway.
- cjonas 1y ago> You still have to deal with all the tooling you are talking about, right? You’ve just moved the goalpost to the BE This. From a security perspective, server side dependencies are way more dangerous than client side.
- t-writescode 1y agoYou can accomplish the "don't have to reload the page to see my changes" with htmx and it's still "server-side rendering" (or mostly server-side rendering). Legendarily, the fastest website on the internet uses partial page caching to achieve its speed
- hirvi74 1y agoWhat do you like about HTMX? I coming from a world of plain JS usage -- no SPAs or the like. I just felt like HTMX was just a more complicated way to write what could be simple .fetch() requests.
- t-writescode 1y agoI like that it still feels like html. I think that's it's biggest selling point. You write: <div id="moo" /> <form hx-put="/foo" hx-swap="outerHTML" hx-target="#moo"> <input hidden name="a" value="bar" /> <button name="b" value="thing">Send</button> </form> Compared to (ChatGPT helped me write this one, so maybe it could be shorter, but not that much shorter, I don't think?): <div id="moo" /> <form> <input hidden name="a" value="bar" /> <button name="b" value="thing" onclick="handleSubmit(event)" >Send</button> </form> <script> async function handleSubmit(event) { event.preventDefault(); // the form submit stuff const form = event.target.form; const formData = new FormData(form); const submitter = event.target; if (submitter && submitter.name) { formData.append(submitter.name, submitter.value); } // hx-put const response = await fetch('/foo', { method: 'PUT', body: formData, }); / hx-swap if (response.ok) { const html = await response.text(); // hx-target const target = document.getElementById('moo'); const temp = document.createElement('div'); temp.innerHTML = html; target.replaceWith(temp.firstElementChild); } } </script> And the former just seems, to me at least, way way *way* easier to read, especially if you're inserting those all over your code.
- hirvi74 1y agoYeah, the JS could technically be shorter, but your example is functional enough to get the point across. Going with your example, how would you do proper validation with HTMX? For example, the input element's value cannot be null or empty. If the validation fails, then a message or something is displayed. If the validation is successful, then that HTML is replace with whatever? I have successfully gotten this to work in HTMX before. However, I had to rely on the JS API for that is outside the realm of plain HTML attribute-based HTMX. At that point, especially when you have many inputs like this, the amount of work one has to do with the HTMX JS API starts to look at lot like the script tag in your example, but I would argue it's actually much more annoying to deal with.
- _1tem 1y agoWith an SPA you're writing two apps that talk to each other instead of one. That is, by definition, more complex. > You still have to deal with all the tooling you are talking about, right? You’ve just moved the goalpost to the BE. Now you're dealing with 2 sets of tooling instead of 1. > And just like the specific use cases you mentioned for client routing I can also argue that many sites don’t care about SEO or first paint so those are non features. There is no app which would not care about first paint. It's literally the first part of any user experience. > So honestly I would argue for SPA over a server framework as it can dramatically reduce complexity. I think this is especially true when you must have an API because of multiple clients. So SEO and first paint are not necessary features, but an API for multiple clients is? Most apps I've worked with for over 15 years of web dev never needed to have an API. > I think the DX is significantly better as well with fast reload where I don’t have to reload the page to see my changes. With backend apps the reload IS fast. SPA's have to invent tooling like fast reload and optimistic updates to solve problems they created. With server apps, you just don't have these problems in the first place.