In this thread, there are several claims that it's impossible to write well-organized jQuery. That sounds an awful lot like dogma to me. Also, your inability to write well-organized code says more about your coding and team-management skills than it does about any one approach. Any tech is only as good as the team using it.
A few years ago, Sam Stephenson (who originally wrote the Prototype library, before jQuery was a thing) gave an excellent talk on Turbolinks at RailsConf. I recommend the whole talk (turn it up to 1.5x speed, of course) but at 4:12 he does an amazing job of showing how the SPA path leads to insanity.
Here's a mental exercise for you: the next time you start a new project, instead of deciding which SPA framework to use, start with an assumption that an SPA is wild overkill for the first iteration of your application - especially if few people on your team have working expertise with the SPA in question. Then see if you can argue FOR the tech. It's much harder to justify something you don't need if you start with an honest conversation about how you probably don't need it. (This works for throwing out CDs, too: start with the assumption that they are all garbage, they all go. Then force yourself to make logic-based arguments for each one you keep. Your outcome will be night and day from if you start with everything in a keep pile.)
That’s not a bad thing but it’s extra work which someone has to be responsible for, similar to how e.g. using a complex custom widget means you’re on the hook for accessibility rather than the browser vendors.
That said, it really feels like a chasm that quite often I choose to cross simply because it'll be easier down the line. I've been bitten more than once by server-side-first projects where going full-on client-side with the server-side as an API would've probably been better.
Whether it was because I needed a mobile app to communicate with said API, or whether the complexity ended up being more of a client-side thing, the result was often that I had to focus on the back-end as as API and go for the full complexity of a front-end app anyways.
I'm enough of a fan of my preferred back-end languages (Ruby, but mostly Elixir these days) that I try to find ways to keep the complexity there, but truthfully I often opt for going for the full complexity of a client-side JS/TS stack because I'm likely to end up needing it eventually anyways.
I've looked into things like Drab (https://github.com/grych/drab), but ultimately there are many reasons why 'going with the flow' seems like the better solution (even if just because it's so much easier to find JS devs than Elixir ones).
So far I'm not confident enough to make any sweeping statements, but from that lack of confidence I tend to opt for the 'safer' option, which seems to be the SPA route much of the time.
I think that you're joking, but if you're not joking, well, we have different definitions of simple.
You threw down a URL to a framework I don't know that is apparently similar to a framework I don't use and runs on Clojure, which I don't work in and none of my codebases run in. You did that with no context or even taking the time to explain why I would do such a thing.
Objectively, there's nothing simple or expressive about the samples on their homepage. Their demos are simplistic (todo?! seriously?) and do nothing to convey why someone would express a complex web app in this manner.
It seriously looks like Matrix code to me.
Wow! Indeed our definitions of simple are different.
If you have anything more substantial to add to the conversation that actually relates to my original comment, I'll be here.
I’m not swayed by the argument, but that’s personal bias. I’m the technical cofounder / solo coder of a venture backed startup, and I built our platform on rails 5. I migrated our front end to Vue over the winter and couldn’t be happier.
When we started (my cofounder and I) our company in early 2017, it had been a few years since I coded daily, and I’ve never been a front end programmer. I’m not well skilled in JS, so I punted on using any front end frameworks for the first six months. Our entire MVP was rails 5 server side rendered pages, with a dusting of jQuery when needed. It definitely got me as far as I needed it to, but I felt a lot of pain once I began to try to mix in a lot more interactivity in the app. For me, migrating to Vue made a lot of sense and continues to pay dividends. For others, the author’s arguments are probably far more applicable.
One area where I deeply agree with the author is around how in JS I often don’t know exactly where I should write certain parts of my code. For a long time, I had a lot of model logic in my Vue components, but that quickly became a nightmare and I’ve abandoned that. Now I use ES6 classes to wrap a bunch of my logic, but even then I still find stuff bleeding places that seem wrong.
One thing I also avoided so far was using any state management (a la Vuex). In some rare examples I use a message bus to send information around, but even then that usually triggers a component to go refetch information from the source of truth (the API endpoint). So far this pattern helps to restrict me from making certain lazy choices which will feel good in the moment but become maddening in the future. My app, as such, is not as maximally performant as it could be, but the trade off for the rare update has so far felt worth it.
So, to sum it up, as a veteran coder who spends 12 hours a day writing code, but knew rails really well and not any SPA frameworks, I’m sympathetic to the article but respectfully have a different experience.
I don't think you're actually disagreeing at all. You're using the right tool for the job. You started with one job and the right tool, and when the job changed you switched tools. That's as it should be!
Use Rails until you can't. That's what you did and I can't see the author disagreeing.
You can generalise this to most technology. I know someone who has gotten it into his head that he needs to write his entire new web app using golang and microservices. I'd suggest that when he actually outgrows Rails enough to require that then he can suggest it to his 50-person-plus engineering team, but in truth I don't think he'll ever actually finish it.
Rails makes a fantastic REST framework, especially if you build your app that way right from the start.
And, to the parent commenter, good point. I do think the gist of the author is to use the right tool for the job, and they are not dogmatic about "never write an SPA". Thanks for keeping me honest.
What are you accomplishing with Vue which was impossible before?
Would love to get a glimpse of the app.
The first "complex" UI design that we came up with was creating a list view that came with all the trinkets you'd want from a sophisticated list view (pagination, sorting, filters, searching). This view needed to be able to apply easily to all the key data structures our app uses (list of users, list of things user has, list of things users do, etc) which meant due to the scale of some of the data sets most of the operation work needed to be on the backend.
Originally, it was built as a completely normal Rails view requiring a full page refresh (form submit) to perform any given operation. This certainly was "doable" but not a great experience as someone administrating lists of things in our app.
We then wrote a React component that manages all the visual state itself based on the data returned from the backend and replaced the existing Rails view with this React component. By pushing responsibility of view state to the client our Rails codebase get simplified. React fully manages visual state, but where we really benefit is the fact that it forces you to design components in such a simple way that UI abstractions become more naturally fitting. The conventions are easy to understand and result in a codebase that can have a lot of cooks in the kitchen without too many problems.
Could this be written in jQuery? Sure. If it's like most large jQuery projects I've seen with multiple hands on it, it will be hard to keep it from being too brittle.
The implementation is really part of a longer term plan to begin building out new user interfaces in React. We find that react delivers on the promise of UI reusability much better than any backend MVC frameworks view or partial system. A front-end codebase is starting to emerge with it's own developer conventions and processes that are more geared towards frontend requirements. Meanwhile, our backend is simplified to only deal with tasks related directly to data management. The split feels very natural as the codebase grows larger. There is no obvious downside to writing in React besides the minified library code payload.
As a summary: our users expect interactions with complex interfaces to respond quickly. React is designed to build interfaces that fulfill that expectation, and the implementation of React in our codebase allows to slide into a more microservices looking architecture in an organic way as the scale and complexity of our app increases.
The objective of our process is to deliver highly actionable feedback for each and every participant, so the “review” you fill out for yourself, your manager, and your peers, feels different than a normal form based review. We ask a series of questions, adjust what we ask on the fly, and try to help encourage writing high quality feedback along the way.
We do a part of this process during a workshop we run on site, and that tends to mean a bunch of people packed on a single WiFi node. Having the app as an SPA allows the user to fill out their 360s, even on a dreadfully slow network, and not notice. This could have been achieved with jQuery, but given how complex I know this code is under the hood, I shiver at the thought.
To the questioner, my email is in my profile. Shoot me an email and I’ll point you towards our demo.
If it really was an issue you could just tell one of the environments to throw a banner up the top of the screen or something in dev mode saying where it's from.
I think the author is missing the fact that it it hard to justify Rails only approach if you have to support mobile interfaces and HTML is not only medium you are working with.
Dealing with stateful and rickety jQuery is why I stopped doing web stuff in the first place. Having React and a halfway decent dev environment in ES6/ES2017 and now TypeScript brought me back.
My feeling is that I don't experience a startup tax with using a frontend framework, like Vue. To me, it's now as natural as using Rails on day 0.
Don’t really see what benefit would I get for adding the complexity of separating the front end in its own layer.
Turbolinks gives me the speed of an SPA and I get 5x the dev productivity by not adding one.
And I absolutely love Vue.
What am I missing?
I don't find using Vue adds complexity for me anymore, and I enjoy a lot of the benefits of it (component libraries, scoped styles). That might not be enough for you when you're working with mostly vanilla CRUD pages, so I totally get it. If your productivity goes down with Vue, then it should take a big reason to add it. For me, it at minimum is not net negative, and I'd say even for trivial pages it's a net positive.
> I'd say even for trivial pages it's a net positive
Curious, what do you consider more complicated than CRUD, yet simultaneously "trivial"?
For me, using Vue is worth for CRUD pages, trivial pages (pure HTML), etc. There's enough it gives me that even though I don't need it, I enjoy utilizing it in my workflow.
What I was attempting to express is that I understand that for many, it doesn't give them anything in a basic CRUD page, and in fact can add a lot of complexity when you move away from built-ins with the backend framework (like what rails gives you). So, I can get why someone might say "it's not enough".
Could you outline your approach to including Vue, to carrying state and changes from the rails api to the Vue-powered views, incl. initial state?
Do you think you could share a code sample?
The tl;dr is:
 Use single file components
 API endpoints return JSON. Nothing super fancy, just taking rails objects and return JSON.
 What would have been a rails "view" corresponds with a route in my vue-router config. Nothing special there either.
 A top level page (think /index or /item)
 Each top level page calls a private endpoint, which is just its own natural route in the browser, and pulls down data it cares about through the JSON request. Each json object corresponds with an ES6 class which wraps any object specific logic (usually end up having to dupe some code between ruby + js here).
 Each top level page is broken down into components (widgets, major sections of the page), for code clarity.
 Anytime I find myself doing a for-each loop, I usually look to see if whatever the sub element is should be its own component. Usually the answer is yes (just depends on whether it has its own independent logic).
Everything is passed top down as an object, but I do break the "cardinal sin" of mutating props on the object. Traditionally, props should be immutable in Vue, which requires use of Vuex or an event bus to change state. I haven't had a case yet where this has been an issue, likely because each page transition reloads whatever data it needs, and the same object isn't being mutated by multiple components in a way that would cause debugging nightmares.
A few patterns I use to keep myself sane are wrapping objects with their own save methods (so I can just .save() ) an object and persist it back to the server.
I dunno, probably a lot more there, but I haven't given this any deep thought. Reach out, and let's exchange thoughts!
On the server side I use Express in Node and either `tsoa` or `inversify-express-utils`, while in Ruby I use my own Modern library to autogenerate a Swagger document from the controllers I specify.
 - https://github.com/lukeautry/tsoa
 - https://github.com/inversify/inversify-express-utils
 - https://github.com/modern-project/modern-ruby
I'd love to take a further look at your modern-ruby library. Hope you're able to continue to flesh out examples and documentation :)
And I like Ruby.
If you want to prototype / start new project with complex UI (think filterable lists / tables, communication apps, dashboards, ...), you are building the app around the client and SPA is natural choice
If your app is more like (simple) CRUD app, then you probably don't need SPA features, and they might even slow you down.
There is no clear line between those two, so lot of the time you can do both approaches, but in the end your desired UI complexity drives the tradeoffs.
EDIT: as for your original question ("significant amount of FE functionality"), from my experience jQuery loses a lot of its appeal when you have over 1k lines of JS, and I guess over 5k JS frameworks (React, Ng, Ember, Vue) start to be significantly better. When over 10k jQuery would be crazy mess (I have seen one such project, it was fun trainwreck).
If I needed to have SEO friendly pages, there are SSR solutions I would look into using (like nuxt) or just pre-rendering the pages myself (I already use puppeteer for PDF rendering elsewhere in the product).
It has pages and AJAX out of the box, and works with existing web tech. Turn your website into an SPA.
As an aside, I find this viewpoint prevalent in the Rails community and the Rails job I had (so, caveat, I'm coloured by my personal experience). It also lead to a culture of staunch refusal to learn or do anything new in that job, and the quality of the product suffered. It consequently led to me leaving the job, and being much happier for it.
I find one of the most difficult aspects of software is the very powerful "local minima" of effective (but not optimal) techniques combined with entrenched knowledge. People are so incredibly biased towards what they know well, and that bias is backed by objective evidence: when they do it X-way they are objectively faster AND better, and what's more, X-way has many objective benefits. This is the local minima in a vast multidimensional space of the benefits and tradeoffs of different possible technical approaches. The multidimensional problem of overall comparing X-way with Y-way is nearly impossible to accomplish, so we nearly always fall back to our intuition (aka bias) which nearly always leads us back to what we already know. And consequently most organisations are stuck in some version of a local minima that is very hard to escape, but ultimately represents a big disadvantage over time. But the question of when is the right time to move out of that minima - and incur the expense of navigating the hills between where you are now and the better minima - is really hard to solve.
That presumes that Y-way is inherently advantageous to X-way. There's still plenty of sites that can and are market leaders using an out-of-flavor framework like rails/spring mvc/.net. New frameworks do not necessarily supersede old ones - they are usually a response to new use cases that have cropped up. These use cases may or may not be important to your business.
In tech, it's not what one particular developer thinks but the consensus among the contributors which decides which one out of X or Y will end up having more benefits.
It's always the people using the tools that decide whether X or Y will have more benefit. You don't easily get contributors without first having users. Or did I misunderstand your point of view?
Anyway I just thought it interesting that you might make valid reference to a very useful concept I've heard and used many times, and yet in your expression the "polarity", as such, is totally inverted! And yet I understood you anyway. A computer would be totally confused.
For comparison, I believe my usage arises from evolutionary fitness, where one might discuss local maxima on a fitness landscape. The challenge is perhaps much the same as in ML, with one strategy being to introduce random mutations in order to escape the same kind of trap.
Actually, my preference for minima vs maxima is because minima translate readily to the natural world where you can imagine balls rolling down surfaces or water running down hills and getting stuck in local "minima" even though there is a lower energy state available to them. It makes a much easier mental model for me than thinking about maxima.
Overall, in each one of these scenarios my gut is that it would have been more efficient to attempt to optimize X-way, rather than layer Y-way on top. It always seems the goal is to incrementally migrate from X-way to Y-way, except we never seem to quite finish and frontend moves quickly enough that Z-way starts to look enticing midway through the painful migration.
I think it is extremely important to differentiate between the benefits of building a fresh application Y-way initially, and the (often extremely painful) friction of migrating from X-way to Y-way. One great example of this is the recent AirBnB departure from React Native. It seems like the majority of their complaint with the framework was that it was difficult to integrate with the rest of their app - had they built from the ground up in React Native, they likely would not have experienced such integration challenges.
Very good point. You'll be building an API anyway if you want a mobile app. However, you can probably get away with a much smaller one, for only the most interactive parts of the app - I've gotten a lot of mileage out of simply embedding web pages for fiddly things like settings pages and other complex forms in mobile apps, saving the native API-driven section for only when needed. The hybrid approach can actually save on mobile implementation time in that way, too.
> a culture of staunch refusal to learn or do anything new in that job
Sigh. I have encountered this too. But I think it's mainly a person-by-person, or perhaps team culture, issue, coupled with the fact that Rails has been around a long time. I've been using Rails since it's in beta and am very happy to use React et al when called for.
Sadly, when (if?) React gets to 10 years old, you're going to see the same thing on that side of the fence! There's a certain type of person who's always going to be grumpy about learning something new.
I resemble that remark :). But I hear you, sometimes you have to invest to figure out if something is any good, and one way to do so is to build something real with it.
However there's danger on the other side too--a company with 5 different apps in 5 different frameworks or languages that all have to be supported by a small team of developers. That can't leverage deployment or performance tuning knowledge across apps. Where work is siloed because "Dev X doesn't know golang and Dev Y doesn't know rails". And where you can't rewrite the app because the business leaders wonder what they'd get.
The problem I see at the moment is that client side "apps" - however they are rendered - hit a wall in complexity that is really hard to overcome without a a sane and sensible way to break them down into pieces. Just like every sane regular programming language has concepts of classes or modules or some kind of system for divide-and-conquering problems into pieces, your front end needs that too once it gets complex. And that's what these React/VueJS frameworks are doing for me. What I like is that they make the right solution - breaking a piece of logic or code into its own component - the easiest solution. So I tend to do the right thing, not because it's "the right thing" but because it happens to be the easiest thing to do.
I know this is a bit of a parallel argument with respect to whether you build a SPA or not (especially Vue can live in either world just fine). But I feel like the author is throwing out the component-baby with the SPA bathwater.
“Component” web apps are by no means simple.
One question which should be included in that is whether you need a huge framework and supporting toolchain or just ES6 classes. There’s a good argument that using standard features will last you longer than frameworks which rapidly go in and out of vogue, and it avoids the constant frictional support costs of regular forced upgrades and debugging complications.
Great article overall but one premise I question is: how often do you really need a non-jQuery JS framework at all in the client?
It seems to me that most apps are simple CRUD apps and server-side rendering is sufficient. Sprinkle in jQuery for simple client functions. Use jQueryMobile for the SPA framework which improves performance by making an AJAX request for any navigation and replacing the page body (instead of doing a full page reload).
I recommend only moving to a full non-jQuery based framework if the design or functions require it (and question that) or the app evolves to require it. As fast as computers, phones, and the internet are today, doing server-side rendering seems good enough for most apps.
This sounds like the "pjax" idea. I did this recently in a prototype; it's about 30-40 lines of JS (not including a shim for the pushstate-API) and maybe a dozen lines in the backend. It just works(R), and makes things as fast as the backend can deliver stuff. Much faster than stuffing hundreds of kB of framework CSS/JS down the browsers throat for each click, and far more simple than any JS-SPA-frontend-bingo-stack.
Not that your point is invalid - many people do jump into modern frameworks for sites and apps that are simple enough to not need them. And SPAs don't need to be anywhere near as complex as this article proposes. But if you are going to go down the road of recommending simpler architectures, without a framework approach, then commit to it fully, and just go with vanilla JS.
Since it's easier to develop, our backend admin system is built in .NET's MVC framework and it's lightning fast compared to our frontend. Like ridiculously fast. I'm not currently a backend dev but I have extensive experience with Rails and I've seen the same with Rails. It's fast.
Despite the fact that I'm a front-end dev and it's not in my best interest, my un-requested recommendation was to do the rewrite in MVC, thus delivering everything from the server side. Here are my stated reasons:
• The site will load and responds incredibly fast
• The "build time" problem disappears
• Backend devs suddenly become full-stack devs
• Deploying is easier
• Testing, both automated and manual, is easier
• SEO is easier
• You can now hire junior developers who are productive and don't create a mess in a new js framework
• Our website is a website full of mostly content and CRUD forms, not an app.
If everything had been build in Rails from the beginning, instead of .NET and Ember, we would have been twice as productive with half as many developers and wouldn't need QA at all if we wrote tests.
This opinion was basically scoffed at with no valid counter-arguments given. They will move forward with a complete rewrite in React, which will solve none of their problems, except MAYBE hiring, and likely create more. They'll also probably do it without me. I'm not against SPAs or React when used for the correct reasons, especially considering I've been focused on front-end for the last 5 years, but I am vehemently opposed to bad decision making.
That should have been your determining factor as to whether or not a SPA was appropriate.
We've had the opposite experience; our new react SPA is noticibly faster than our current rails site, but it is due to the nature of the pages, not "X is always Y compared to Z"
this is the reason we moved in the other direction, in my limited experience, people would should really backend devs doing frontend work because you framework/ arch is full stack and requires it, has been terrible
Judging by how your org made the decision without the devs input though, I'm not too confident it won't be disaster. It's depressing but I've been offered too many contracting opportunities to rescue a project after a similar conversion that is a total dumpster fire.
If this is true, you’ve been doing QA wrong. A good QA team will catch gaps in the developers’ thinking, not just click buttons like robots.
All I would add is that rails can be made to work wonderfully with SPAs if you're willing to do some metamagical programming to auto-follow standards like JSON API.
I love Rails and the power it offers in development productivity and quality. It's code is very maintainable and actually enjoyable to develop in; even when it's someone elses codebase.
Oddly enough, I finally came upon a use case in a project where an SPA frontend (Vue) / ruby backend make more sense given the platform nature and operational needs (runs on a pi, no "models")
9/10 Rails is the way to go though for developing something.
It was an amazing project that let you write normal css/html/js without modifications THEN rendered the html+js into a SPA. It was fast, preloaded pages, clean, easy to write and really well documented - and maintained the root dom element. BUT! The project is mainly(opinion) dead. Instead people want to write in a new language (react,vue,etc) then deal with adding a massive layer of complexity.
> The project is mainly(opinion) dead.
I don't think it's dead so much as they are really worried about backwards compatibility (rightly so), so they're taking their time. It could also be argued that, for its purposes, it's not so much dead as nearly complete.
Overall, I've enjoyed the simplicity of JQM+PhoneGap (I use Rails as the backend). You can still layer on any other JS framework on top, so it's not limiting. My friends and I use the app daily and performance is fine on a modern phone.
Having the same code (and I'd argue, look and feel as well) for web, mobile, and native is the best way to go for a small project trying to contain time and costs.
Perhaps it was simply ahead of its time, and 2011-era browsers couldn't keep up with it, but either way I much prefer using its successors.
In fact, I don't really recall anyone speaking positively at all; at best it was a necessary evil.
If you go the "Rails/Django way" with server side rendered templates and, say, a bit of jQuery for fancy stuff -- you'll end up duplicating lots of code for the API (validation, routing, maybe even business logic).
Anyone got experience with swapping your models/controllers for an API while keeping the rest of Django's/Rails' niceties? (authentication/sessions, Django's forms system, CSRF, etc.)
OTOH having Django/Rails merely as a template system you probably could also go for very simple, self-contained client-rendered JS pages (e.g. .vue files). Not much difference there I guess?
There is always short comings on every tool and library, and part of responsibility of a good developer is discerning trade-offs.
- Code duplication between server and client side
- Added complication threw data transmission between server and client (REST/json)
I think, both problems can be addressed by:
- having (a single) code that works both on server and client-side
- having transparent transport mechanisms for information between client and server.
I am sure, I could implement such a thing for Python/Django, using the already existing tools. But I am not sure, if such a thing would be appreciated by the community.
What do you think?
However, the article author's list of SPA pitfalls is really good, and are probably not all surmountable by a framework/platform.
Also on the plus side, the back end requires less code now. IMHO, where Java is concerned, less of it is better. (There is still WAAAAAAAY too much of it, compared to equivalent Rails code)
I'm an SPA Lover ( Angular , Vue ) , but still most of the points raised here a coherent from a back end perspective.
That said , a lot of the arguments are basically summed up as :
"I don't like Front End Dev. because it's not as mature as Back End".
I will not lie on this point , JS is a fast evolving ecosystem that sometimes has issues to stabilize. Hence , there is a lot of marketing and self promotion mixed with frameworks sometimes ( Growth Hacking ) pushing for unnecessary tech that dies a few days after they have leaved the Github Trending page.
For beginners , when a framework reach a certain threshold ( Github Stars most of the time) they feel like they should hurry and use the framework to stay relevant while most of the time they don't need to and the tech is just fluff.
My point here is very simple, you are ROR or Django or ASP.NET dev and you love what you do ? As long as you find jobs keep doing this , don't bother with Full Stack Fluff.
Now that said , I can only encourage the author to do the Angular or Vue tutorial to discover something different. Rails is great ( it's empowering a lot of website Github , Airbnb etc... ) but SPA are different and when used properly it's hard to go back , the experience is delightful.
Most importantly we are getting closer to the serverless era where backend will be completly different from what it is compared as now, and SPA and SSR will likely be the standard in the future.
> I don't like Front End Dev. because it's not as mature as Back End
No, he says don't do FE and BE when the tools for back end-only (well, Rails is full stack, actually) are so useful and productive. And in the rest of your comment you seem to forget that a front end is completely useless without a back end.
> you are ROR or Django or ASP.NET dev and you love what you do ? As long as you find jobs keep doing this , don't bother with Full Stack Fluff.
Rails is the "Full Stack Fluff".
> SPA and SSR will likely be the standard in the future
How, exactly? What serves your SPA? And who is using "serverless" for anything other than querying other backends (eg Slack bots) or accessing AWS services? I mean, sure, it's nice to not have to stand up a server to resize images coming from S3 but it's hardly going to replace, well, servers. You couldn't implement even the simplest CRUD app.
This is the first general misconception with serverless.
Serverless is not lambda . If you think serverless == lambda, it's like saying cloud == ec2 . You're missing the point of it.
using lambda and its equivalent is - in my understanding - the definition of serverless. You might not be able to utilize the biggest advantages of serverless infrastructure if you combine it with a standard ACID database backend, but it should still be a serverless deployment.
> JS is a fast evolving
What needs to die is this grounded-in-fantasy contempt for mature, very much alive, performant technologies with huge ecosystems.
MVC was a hack of a pattern that developers adopted to get server side rendering architectures to even work. Good developers recognized its many flaws and when front-end development became decoupled from the server, tried and true practices and patterns such as modularity, reusability, and separation of concerns were adopted to the front end and the results of those efforts are the front end frameworks and libraries we have today. They are not variations of MVC. If you work with them as such, your SPA architecture will look just as brittle and shitty as a server-side architecture.
MVC wasn't even developed for networked applications, but for desktop GUI applications; it was later adapted for web applications,
And server-side rendering existed and the worked before MVC was a popular pattern to use for it; MVC was a step forward in making applications doing it maintainable, but want chosen to get it to work at all.
> Good developers recognized its many flaws and when front-end development became decoupled from the server, tried and true practices and patterns such as modularity, reusability, and separation of concerns were adopted to the front end
MVC came from application of exactly those principles to desktop development, and was adopted precisely to bring those to web development. Sure, it wasn't the end of the road in that, but it wasn't done kind of reversion from it, either.