First an Apology...
This is a public apology to my friend Brandon @flybayer. Back in 2020 when he published Blitz, I replied to one of his tweets with something along the lines of:
"I don't understand why people want to go back to the monolith, especially on top of React, I thought we have gone past that and microservices + SPAs are the norm today".
I was wrong, very wrong...
Is There a Middle Ground?
I have been exploring a lot of the new cool stuff that is coming to the JavaScript ecosystem lately, and I have noticed an interesting trend: developers want the flexibility and scalability of modular systems but without the maintenance and complexity overhead that it brings.
This is where backend tools like MicroLib
and Full Stack "meta-frameworks" like Blitz
and Remix
promise to bring back the "good old productivity win" of monolithic frameworks like Ruby on Rails but keeping the modularity and component first approach of the modern web.
Modular Monoliths
This concept is not new and probably not very popular these days; It is an architectural style where you build applications in a modular fashion by enforcing strict boundaries between different domains and improving code reusability which makes code organization and dependency management easier. The key to a Modular monolith is that you keep the parts (modules) that compose the system as a single deploying unit, aka "monolith".
Β Why Would Anybody Use This?
Being the middle ground between a traditional monolith and a full-blown microservices architecture, a modular monolith only brings limited benefits in terms of scalability, autonomous teams, and independent delivery, however, it could be a better approach than starting with microservices from day one. This follows the advice of Martin Fowler in his article "Monolith First".
The modular monolith could be implemented as a way of identifying the boundaries of the system while keeping the agility and low maintenance overhead of a monolith in order to increase development speed and quicker time to market.
This path could lead to an initial design of the system and serve as an intermediate state that can be sliced into individual microservices in the future, however, if the team already has the experience and are comfortable with microservices, there are clear system boundaries from day one and the infrastructure is already in place, then going straight to microservices should be considered instead.
New Generation Modular Monoliths
How are the new full stack "meta-frameworks" like blitz.js
(built on top of next.js) the new generation of modular monoliths?
The way a framework like Blitz
works is by keeping the frontend separate in a Single Page Application fashion but connecting to the data layer without the use of REST/GraphQL APIs allowing for direct database access. It remains as a single deploying unit, however, it has clear boundaries that can be "peeled off" and moved to separate APIs like microservices or serverless functions in the future.
Hexagons, Hexagons Everywhere!
If you want to keep your frontend and backends separate but you don't want to pay the "microservices premium", another interesting pattern that has emerged is libraries like "MicroLib", built on top of Module Federation and based on "hexagonal architecture" to create a "polylith", a monolith comprised of multiple (what would otherwise be) microservices.
The key difference with a traditional "modular monolith" is that a "polylith" can independently deploy the multiple modules that comprise the system. This could be the "best of both worlds" in terms of manageability, reusability, and autonomy.
Conclusion
Senior Engineers learned the phrase "it depends" from Architects... so should you implement a modular monolith? Well, it depends on your requirements and where you are in the lifecycle of your application. Big companies like Shopify have successfully scaled their monoliths by implementing a modular monolith and prove that the answer is not always microservices.
Top comments (7)
In using something like blitz.js, I'd be concerned about coupling frontend directly to databases -- the model, view, controller pattern MVC was created years ago to avoid this and the brittleless that ensues in terms of maintaining the code / application.
Yeah it is a concern, but it is not as bad as before if implemented correctly, for example the react components can be designed in such a way that their interface with the data is abstracted so as far as the components are concerned the data can come from REST/GraphQL or the database. If decoupled and designed this way then it is just the case of swapping those adaptors in the future if needed.
"If implemented correctly" is doing a lot of work there. That is way too rare a beast to depend on.
ETA: And the abstraction you're describing is... MVC.
The answer if we are coming full circle is likely yes then π
There is no "one-size-fits-all" architecture and the choice should be made based on not only the project itself, but the team as well. One-and-a-half developer team will be perfectly fine with a monolith, modular or not. A cross-functional team of a dozen specialists will thrive with micro-services. And yes, there is a middle-ground where some parts of the deployment are "micro" and the others are not.
I agree, "it depends" is a trully valid answer when choosing the architecture for your project. I wrote about the same when choosing micro-frontends and my friend @lucamezzalira has a really nice article about the decisions framework.
medium.com/@lucamezzalira/micro-fr...
that's where Angular shines among other frontend frameworks as it is a modular monolith by design