Correctly layering an application, specially on the frontend, provides you with infinite possibilities regarding scale and maintainability. Knowing how layers in Software Development work will help you create systems that are understandable, not only for humans but for AI too.
Layers in Software Architecture bring structure, allow you to change the system without affecting unrelated parts and create contexts that are easier to reason with.
Let's understand layers, together.
#What are layers?
If we think what layers truly are... They are self-limitations. They limit us from where we can import code from.
Why would we want to limit ourselves? Why shouldn't I import code from a place that I consider it's another layer? Would it be that terrible to call fetch directly from my UI components? What's the value of this?
Layers group code depending on one main reason:
How often does that code change.
#What value do layers provide?
When we talk about change, in reality we are talking about stability. If a layer tends to change a lot, we can say that it has low stability. If a layer doesn't change that much, then it's a stable layer.
When we work with layers, what we are modeling is the relationship between more stable and less stable layers. This is something not to be overlooked. Let me ask you the following:
If we are in a very stable layer, and we import code from a very unstable layer, what happens?
We've just made a layer that didn't need to change (stable) suddenly have a direct relationship with a layer that changes a lot (unstable). Now, when we change the unstable layer (which will happen quite often), we will need to change the (un)stable layer when that shouldn't have been the case.
#How can we implement layers?
In a given project, we might have different layers, so, what do they actually look like? Well, although layers can be conceptual, I like to make mine as folders.
src layer-a layer-b layer-c
If these names don't bring clarity for now, don't worry; they are just placeholders. I'll show you exactly what layers I use in my Frontend projects in just a bit. I feel is more illustrative that we stay focused on the concept rather than detailed names.
I think it's clearer to have a folder than just remembering what files belong to what layer.
#What is the relationship between layers?
Typically, layers have been represented as concentric circles to represent the relationship between them. Let's explore that concept.

When presented with this graphic, I was always confused, if in our codebase we have three layers that seem to be siblings, how come here they are nested?
The answer is straightforward, this graphic represents where layers can import code from.
Remember what we said previously?
“”If we are in a very stable layer, and we import code from a very unstable layer, we made our stable layer unstable
In practice this means that the outermost layers are the more unstable ones, while the ones inside are the more stable ones.
In this case, layer-a is more unstable than layer-b and layer-c.
So we can say that the knowledge between layers is inwards.
Again, in practice, this means that I can only import code from layers that are more stable than me.

So, I can't import anything from layer-c. From layer-b I can only import from layer-c. And from layer-a I can import code from layer-b and layer-c.
#What should I name my layers?
Now that we've understood layers, let's choose a more appropriate name for them.
In Frontend Architecture the most core layer which represents my business logic, rules, invariants, entities, etc., I call:
domain
Above this layer, where I place my use cases, state logic, rules and permissions code I call:
application
Then, the mechanism I use to deliver my application to the end user, I call:
delivery
I usually have another layer called infrastructure, where I place my repository implementations
Let's refactor rename (Shift + F6) the layers so we have the end picture:

#What are the benefits of using layers?
You might ask yourself, why do all of this?
Well, let's say that we have built a web application where the use cases are separated neatly in the application layer, meaning that every action the user makes it's abstracted in a use case.
Right now our delivery mechanism is a web interface using React. Given these days, we now must implement an AI agent. Nothing changes, the use cases are the same, the logic is the same, but the AI agent is exposed in a different way than a web application.
Would we need to duplicate the project? That wouldn't be wise, since if we want to make a change in one project, we need to change two now.
No, a better approach would be to create two deliveries:
src application delivery ai-agent webapp domain
With this approach, ai-agent and webapp both reuse the same use cases and call the same domain objects, they just do it in a different way.
It's just so clean.
#Conclusion
As we've seen layers not only provide clarity, but are tremendous extension points for our architecture, so it's nimble yet solid.
In the following issue we'll explore how layers can be paired with feature modules to create truly modular systems.
P.S: I just released the best worst landing ever made for my book Software Cafrers. Check it out here: https://www.softwarecafrers.com/Open in a new tab.