I’m currently migrating a fairly large Vue.js 2 + django rest framework app by moving all the front end to the django backend templates using apline.js and htmx where necessary.
I’m loving evey moment. It’s thousands of lines of code and dependencies removed. It’s faster.
I feel like I’m waking up from a bad fever dream that was web development for the last 10+ years. What were we thinking?
You can make a mess or not a mess in any framework. The tech is not the problem.
I bet in a few years you’ll have just as big a mess with alpine+htmx as you do right now with vue+rest.
Ultimately the only thing that matters is having clear interfaces, well defined modules, and the discipline to keep it clean. The rest is all window dressing.
PS: SPAs were invented for a world where server compute and bandwidth are expensive and/or you need highly interactive low-latency UX. They were never meant for mostly static websites that are cheap to generate and cache.
I don't think it's going to be the same situation at all.
First of all, the reason why I'm doing it in the first place is because Vue2 is completely deprecated. It's not even getting security updates, and migrating to Vue3 is such a hassle it's not worth it. This is a major maintainability issue.
Now the new "stack" has about 5 JS dependencies total, all of which are very low surface area. It doesn't even require a build step. And Django is not going anywhere.
You can definitely make a mess with any technology. The key issues I have with SPAs are:
1. You have to build your app twice. I don't have a team large enough to write it once in Python and again in JS or TS.
2. The state of the art in SPAs moves so quickly it feels to me like you have to spend a significant amount of your productive time staying in place on the treadmill before you can even consider creating value for your end users.
3. The web browser does a lot of work for us in SSRs. SPAs make (have historically made) us reinvent a lot of this from scratch. I recognize that this has improved in some ways in recent years. It's still not as brain-dead simple as just having different web pages that render HTML.
SPAs were invented for a world where server compute and bandwidth are expensive and/or you need highly interactive low-latency UX
Agree completely. I think there is a ton of value in treating technologies like Svelte, React, and the like as terrific ways to create 'islands of reactivity' within mostly static pages. I can do a ton with Stimulus.js and htmx to simulate much of the behavior I'd get out of a well-designed Svelte component, but sometimes I really do need that extra 20% of polish I'll get out of Svelte or React—and I'm very glad that they exist for that.
> 1. You have to build your app twice. I don't have a team large enough to write it once in Python and again in JS or TS.
I have not found this to be true in almost 15 years of doing this[1]. Would be very curious to hear where you’ve found that you have to build the app twice.
Typically my approach has been to put Serious Business Logic on the server behind an API. This lets you contain all the important stuff in one place and ensure a ground truth for all your clients (web, mobile, BI, 3rd party integrations, async jobs, etc). You build this once. Then the client acts as a pretty interface for all this same data. Anything that smells like business logic, you put on the server and call an API. You also build this once because you’re not building any of it on the server.
Those secondary clients (BI, 3rd party integrations, async jobs, etc) are also where MPAs built on next+rpc or django and friends start falling apart. They’re not gonna load your webpage and parse the html or run the JS you sprinkled on top. You’re gonna have to build an API anyway. At that point you may as well make sure that all your clients talk to the same ground truth business logic so your API and your MPA turn into thin layers on top of core business services.
Congratz, now your MPA is essentially an SPA that runs on the server and you have a backend-for-frontend. You’re just making API calls on the server and not taking advantage of your visitor’s globally distributed compute and bandwidth. But it does make auth/secrets easier because you can mostly trust the server-client.
[1] Seriously, one of my earliest talks was on this newfangled thing called Backbone and how SPAs solve common problems we had with web tech back then (~2011). It’s in Slovenian though
> 2. The state of the art in SPAs moves so quickly it feels to me like you have to spend a significant amount of your productive time staying in place on the treadmill before you can even consider creating value for your end users.
I think this is no longer true, not how it used to be. Of course, you CAN chase the latest cool. However, if you stick with one of the more popular libraries then things should be stable. My react code now doesn't look very different to my react code in 2019. They've added new things but I haven't used them.
> My react code now doesn't look very different to my react code in 2019
Server components, Next application directory breaking emotion for styling, stricter rules for hooks, the compiler breaking change tracking libraries such as MobX removing the need for useMemo and similar. This is just off the top of my head in React land.
You're complaining about MPA. Maybe if you choose SPA with vanilla React you would've felt that for the last 8 years there's been a flurry of conversation and innovation that's specifically not about SPA. The conversation around SPA has been frozen for nearly a decade.
Unless maybe you want to start talking about CRDTs? But that's kind of niche, and CRDTs are actually an old conversation, one which started before React was first released. That should give you a sense at the pace of conversation for SPAs.
Also, because next broke emotion, toolkits such as Mantine broke backward compatibility in order to move off of emotion, so second order instability effects still affect SPAs
If you have a very large project which uses MobX, I don't think the amount of warning matters. You'll most likely have to (eventually) completely rewrite large amount of code, to the point where it might be easier to migrate to SolidJS.
If you have a large project then it's your victory or fault for whatever comes of using software marked as not ready. The React team has been absolutely clear that it's not ready.
On an aside, SolidJS has been taking a huge momentum hit recently, I think the drop in downloads is a lagging indicator. It's not an easy space, I love SolidJS and recognize that Ryan Carniato likely took a career hit to work on Solid, but my bet is that Solid will fail to catch critical mass. Really sad as I love the Solid experience.
That promise doesn't really make sense to me - although partial compilation will likely ameliorate most migraiton pain for library dependencies if they come pre-compiled with the compiler.
Code written with the react compiler in mind will inevitably be MUCH slower without the compiler, as its not going to manually add any memoization. Likely to the point where its not going to be usable without it.
The state of the art moves way faster for MPA / hybrid. Way way faster. Next.js, Nuxt, etc. are strictly more things to learn and keep track of, both technically and practically. Almost all the recent innovation for the last half decade has been about MPA and hybrid apps.
Where are you getting the story about hot innovation happening on the SPA side?
> 2. The state of the art in SPAs moves so quickly it feels to me like you have to spend a significant amount of your productive time staying in place on the treadmill before you can even consider creating value for your end users.
The churn that people complain about is coming from the MPA/hybrid side. Where do you get this idea that you're seeing way more innovation on the SPA side?
It’s the same churn. What was once create react app is now next.js If you go to the official react website now it recommends next.js as a starting point for react development. It’s just what SPAs evolved into.
It's not the same churn. SPA conversation has largely frozen. Anyone writing SPAs using vanilla React would be seeing a flurry of conversation go by that's specifically not about them — for the last 8 years.
Next is a headache if you specifically want a pure SPA. It's not the evolution of SPA, it's a counter-response to too much early focus on SPA and not enough on front-facing MPA and hybrid apps. That's why Next exploded.
Where are people even experiencing conversations on SPA architecture? What is the most popular discussion on SPA right now? On the other side I'd say RSC, React Compiler, isomorphic components, keeping server secrets away from client, hydration, streaming, or whether to eliminate all client state, are all hot topics right now for MPA/hybrid.
So where and what are the hot conversations for SPA? Where is the churn? What are some hot YouTubers talking about new developments in SPA?
You’re not getting the point. Nobody is starting new SPAs. If you want write react now you’re going to write next. So we left behind churn in SPA land and ran right into churn in MPA land. For many people there is we never a break.
This whole article is about SPA and making a careful distinction between SPA and MPA as distinct concepts. aaronbrethorst has not indicated that he is confused about whether MPA and SPA are the same idea.
JPM is recently building greenfield SPAs using Tanner's router. I'm writing an SPA right now for drone automation platform for 1M+ population cities. I recently helped plan out a rewrite for an SPA for a vision ML startup worth 2B. For every front-facing user property that you see there are dozens more internal tooling apps backing it, from dashboards to CMS.
If you're building an SPA then Next does nothing to help you. It just gets in your way. There has been no churn for SPAs as the conversation has frozen for nearly a decade. One might point out CRDTs but that conversation began about a half decade before React was even released.
The only situation I've run into that is a bit of a mess is trying to reconcile loading a React dashboard chart thingy (https://tremor.so) in a Rails web app where I'm using Turbo Drive to mediate page transitions—and that just required some careful reading of the documentation to reconcile.
I'm doing something similar, except with Stimulus.js and htmx. (Alpine's CSP support story is too weird for me to want to deal with.)
If you're using Django Template Language, I highly, highly recommend using https://django-cotton.com to create high level UI components to encapsulate common functionality.
I chose Alpine mostly because the exiting code is in Vue, and Alpine maps really closely to Vue. For the few components where I need to reach for it (lots of client side state) I can copy over verbatim many of the Vuejs components into Alpine, which is a huge boon to the whole refactoring process.
I'm using a self-developed framework (proprietary for now) for my SaaS that almost completely eliminated backend code[1].
The downside is that quite a lot has to be done on the front-end because all the backend can provide are static hosted files and a query-executor[2].
So I looked at quite a lot of front-end frameworks for SPA, nope-ing my way out of each one. I'm still in the process of settling on one of the (very poor, IMHO) options for front-end SPA.
For now I'm still using a bunch of little JS functions on the client because that was faster than learning some framework that might all have to be thrown away some day anyway.
[1] I say "almost", but for my current product it has eliminated all backend code. The only "backend" code I write are PostgreSQL parameterised queries. No Java, C#, Go, Python, JS or anything else. While the framework does have the ability to schedule periodic execution of programs written in anything, for the current product all I have is a script to periodically truncate truncate the log file.
[2] There are no security problems with this: I don't execute queries sent from the client; you can see it in action using `demo.skillful-training.com`, username `one@example.com` .. `ten@example.com` with password set to `1` for all of the users. Just a note, the demo site version is quite far behind the deployments for actual clients.
[EDIT: My `ROADMAP.md` file has actually had `Add in Lua support` for the last year, but I have not had any need yet for coded logic on the backend that cannot be handled by an SQL query. At some point I may add in the ability to handle requests using Lua/$OTHER_PROGRAMMING_LANGUAGE, but for now there is no use-case]
I dunno how you authorize user actions. Especially complex cases that involve shared data. E.g. some user can see all materials, another can edit materials belonging to her group and also shared with him by others.
> I dunno how you authorize user actions. Especially complex cases that involve shared data. E.g. some user can see all materials, another can edit materials belonging to her group and also shared with him by others.
It works just fine for those types of use-cases, including that specific one. I am planning to open-source it one day, but not soon (As an independent developer this gives me a very large edge over my competition for custom SaaS-type apps).
This is a weird article. It feels like an LLM was promoted with a few points about how to critique frontend. They don’t really make any substantial claims nor do they back up their claims with real world evidence, instead just referencing general pain.
If this is a real author: There are definitely valid complaints towards SPA but you need to be more specific and not just throw shade on the FE ecosystem as a whole. Talk about your specific failures and how the tooling got in the way of quality engineering. Generalities don’t really help anyone.
Tl;dr: single page apps (react) are bad, perform badly, have bad tooling, and have a bad ecosystem.
This is a tired critique which fails to mention even one reason why one might choose React (or other SPA framework) in the first place. I work on a big, complex React application and it is a great tool for the job. All of the issues mentioned are easily resolved with a modest amount of research or experience.
I’m loving evey moment. It’s thousands of lines of code and dependencies removed. It’s faster.
I feel like I’m waking up from a bad fever dream that was web development for the last 10+ years. What were we thinking?