I believe that we can do a better job of managing the complexity of our apps.
Not many of us realize how many second-order effects our decisions have caused.
Let's see how complexity had grown over time.
The Static era
Simple times. We had a MySQL database, business logic and HTML + CSS views.
All content was static, the browser's job was to display content, navigate and submit forms.
I like to think about test effort as a benchmark for simplicity. There were 3 layers.
Business logic and persistence layer can be easily integrated and view layer can be browser tested.
You may need a tester, developer, and a designer to maintain something like this. It is realistic to have one person responsible for all of this.
The AJAX era
We have a complexity spike on the client-side.
Many browsers differed in JS implementation, which required jQuery to come into existence.
The Single-page era
Remember the first example of the Angular.js app? The input field that automatically updated the content of the div? Good times.
We have ended up with two apps that are tightly coupled.
To maintain this, you need at least someone experienced in testing, backend, frontend development (extensive framework, tooling, and browser knowledge), and design.
Now, two apps have to be maintained, and there is much more code than ever. You have to maintain unit, integration, and end to end tests on both sides. Now business logic is not directly accessible due to security concerns.
Frontend and backend now have to maintain layers that are responsible for communication.
Client code needs lots of API mocks to be tested on lower levels - DOM tests are resource-heavy.
Orchestration becomes difficult because you have to make sure that deployments are synchronized. It is even more difficult if you have separate teams for the backend and frontend.
Don't forget about browser testing that also can have a lot of overlap with client-side integration tests. Even more, things to consider in terms of complexity and trade-offs.
That resulted in more code, which contributed to - again - increased complexity.
SEO became problematic, but thankfully this problem has been addressed by the ecosystem through server-side rendering and hydration.
Good patterns have emerged too. UX became better and more creative. We are finally capable of defining client-side logic in a manageable and scalable way.
We all know now that we want to have components and avoid excessive side effects, together with uncontrollable state mutation.
React de facto became a standard.
The remedy to complexity is embracing the coupling and making the developer experience unified.
Simplicity through innovation in older frameworks.
Ruby on Rails and Laravel are relevant.
Consider them. Their maturity will allow you to move very fast.
They have recently innovated in many interesting ways.
Take a look at Laravel's components or RoR's Hotwire!
Next.js started a good trend by putting React and server logic next to each other.
Blitz.js, which is based on Next, is a good ruby on rails equivalent. It brings the right amount of abstraction that makes you treat your app as a unified whole. Using it sometimes feels like cheating - in a good way. It inspired me to talk about the complexity issue in our ecosystem.
Remix with a fresh take on the problem domain and bringing a lot of good and forgotten patterns.
React's Server Components to make everything even better.
Recently, the React team has presented a new idea that can make our component-driven world better.
Consider reading the article and watching their presentation.
When they are released, then we will end up in the best-case scenario where web apps are only dynamic in
places that require it without having to jump between server-side and client-side paradigms.
All of the frameworks above will benefit from them.
We should start asking ourselves if our standard approach is something we still want to maintain.
Suggested frameworks reduce complexity and allow us to experience the simplicity of older approaches while having the benefits of the modern approach.
They embrace the fact that both backend and frontend are tightly coupled and make the developer experience unified.
This is an opportunity to write less code, spend less time testing, simplify orchestration, spend less money on more people having to maintain the complexity, and put more effort into products we are trying to create.
Top comments (12)
The suggestion here seems to be try even more abstractions within the React ecosystem, but in my experience simplicity, stability, and an improved developer experience only came after abandoning React and turning to standards-like solutions (e.g. Vue, Riot, Custom Elements, plain HTML and CSS).
We should strive for simplicity and we can achieve it in many different ways. There is no one size fits all solution.
The thing is that Blitz boils down common problems into simple patterns and it is an interesting offer if you need them to be solved so you can focus on the end product more. DX is great when everything follows one general pattern which is React in this case.
Sounds like a monolithic web framework architecture of the past, which is no surprise because React prefers to operate in its own framework-like ecosystem.
I’ve found that independent libs with clean, interoperable API surfaces composed in any way you need is a better approach.
And does Blitz really look like this:
Your articles resonates a lot with my series on web development history (especially the Third Age in my periodization system). Your approach belongs to the movement I call "Metamodernism".
Metamodernism - I like the sound of it. Your articles look interesting! I will give them a read.
Sad you didn't mention Blazor (the Server side flavor). Quite the same of Laravel Components or Hotwire, but for the .NET world.
I have to admit that I have completely forgotten about it. It definitely is a good consideration for .NET folks!
Doesn't seem like a good candidate for APIs that will have multiple frontends such as a website and a mobile app, right? Probably not bad if you intend to just have a webapp tho.
Blitz.js readme mentions React Native support as one of the upcoming features so fingers crossed 🤞
In my opinion, Ember.js has been solving most of these problems since about 2012
I have always kept hearing about Ember but never tried to dig into it.
I might give it a test drive to see how it compares to what I've listed down 👀