DEV Community

Cover image for Web apps are too complex. This is how we can simplify them.
Michał Pietraszko
Michał Pietraszko

Posted on • Updated on • Originally published at

Web apps are too complex. This is how we can simplify them.

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.

Simple web app architecture diagram

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

JavaScript opened a door for more considerations in user experience. Adding a dynamic menu, forms, or calendar to a WordPress website was the coolest thing you could do.

web app with javascript architecture diagram

We have a complexity spike on the client-side.

Many browsers differed in JS implementation, which required jQuery to come into existence.

This gave a lot of power to designers and has moved more engineering effort into the front end. JavaScript made the browser extensible.

Did the testing complexity increase? Yes. Each new JavaScript bit could only be tested in a browser.

This requires testing, backend programming, JavaScript, and design expertise in your team. Jumping between server-side and client-side languages became frustrating. There was a trend to have different people responsible for each side.

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.

Welcome to the single-page era where front-end development became even more complex than back-end development - mostly due to relevant logic moving to the client. As a result, the divide has increased and JavaScript fatigue became a thing.

single-page application architecture diagram

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.

Simplicity renaissance

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 generation of JavaScript frameworks

People who want to stay in JavaScript land should consider the following.

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.

In conclusion

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 (9)

fredericbonnet profile image
Frédéric Bonnet

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".

pietmichal profile image
Michał Pietraszko

Metamodernism - I like the sound of it. Your articles look interesting! I will give them a read.

pietmichal profile image
Michał Pietraszko

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.

samuelmunoz profile image
Samuel Munoz • Edited

Sad you didn't mention Blazor (the Server side flavor). Quite the same of Laravel Components or Hotwire, but for the .NET world.

pietmichal profile image
Michał Pietraszko

I have to admit that I have completely forgotten about it. It definitely is a good consideration for .NET folks!

adnanhz profile image

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.

pietmichal profile image
Michał Pietraszko

Blitz.js readme mentions React Native support as one of the upcoming features so fingers crossed 🤞

lrdiv profile image
Lawrence Davis

In my opinion, Ember.js has been solving most of these problems since about 2012

pietmichal profile image
Michał Pietraszko

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 👀