This article aims to introduce a frontend architecture (for applications built with Vue, React, Svelte, etc.) that is easy to reason about and has ...
For further actions, you may consider blocking this person and/or reporting abuse
👍 really good article. I've been writing FE apps almost identical to this for a few years now and it's a great pattern to use. Bonus points if you use dependency injection to further decouple your layers!
Hi Jack, thanks for reading the article 😃.
In the example app, I'm already doing some simple manual dependency injections in the Application layer. In the frontend world, we still have to keep in mind code splitting & lazy loading, so dependency injection is a little bit different from what we do in the backend side I think.
Yes code splitting is a big issue for DI on the front end. In a node app, for example, you can just grep all of your dependencies when bootstrapping with very little cost. This is actually something I'm trying to work out right now 🤔
@jackmellis Please write an article about it if you ever figure it out 😍.
How do you use dependency injection on the FE side?
@tuanlc I guess you can check out Jack's article about it: dev.to/jackmellis/dependency-injec....
Hello Huy, thank you for this awesome article ! It reminds me a lot Domain Driven Design, applied to frontend. Well done !
Thanks for dropping by. This architecture is indeed inspired by the CLEAN architecture, the Onion architecture and DDD, with a few tweaks to make it applicable to the frontend world.
What do you think of adding this to the post? Might be useful for people that are new to these concepts to understand the ideas didn't come outta nowhere. We lose a lot to context when we don't reference the canonical source of this kind of info.
Hello Sir, is there any resource about how to apply this for react
@shaalanmarwan Perhaps in the future I'll write a detailed article about applying this architecture in a React application. But for now you can use the example repo where a React application is included.
Great article!
This is known as Hexagonal Architecture, right? DDD (Domain Driven Design) is another closely related concept. Problem is that most devs aren't familiar with it, and that for most small to medium apps it isn't really worth it. But for larger apps I'd say yes, it's worth looking at.
P.S. what I like about this approach is that you raise the abstraction level, and that you focus on the problem rather than the implementation, and you cut yourself loose from endless discussions about Redux, versus Context, versus whatever. What I like less about it is the added boilerplate, if you can get rid of that then you have a win win situation.
I don't know what this architecture should be called. Some say it's like Hexagonal Architecture, some say it's related to DDD. All I know is it got inspired by a lot of architectures 😁.
And yes, the trade-off of this architecture is it will add more boilerplates. So in the end it might not be worth it if you want to quickly build a small application.
Very nice article! I'm a full stack developer used to Clean Architecture on the backend. Obviously, the frontend world has a lot of catching up to do in the architecture department. One specific thing that strikes me how is frontend state management (like Redux) should be passed into presentational components by dependency injection instead of the way it's currently done. It has to be said though that DI seems harder to do nicely in the JavaScript/TypeScript world. One reason why DI nicer in the backend is that backend languages allow DI containers to use injectees' static types (since those types are around even at runtime and can be accessed via reflection, unlike in TypeScript). So it seems a DI container in JavaScript or TypeScript will necessarily have a less convenient API,
I totally agree. I don't really like the idea of a state management tool being tightly coupled to UI components, but that is probably what library authors want though.
There are some good ways to do DI in the frontend nowadays, with BottleJS for example. Angular also heavily uses DI. Another reason why I don't get why people don't seem to talk about that more.
I just glanced over the docu of BottleJS. It's interesting to see how the DI container API compensates for the language's lack of static types: When you register a service whose "constructor" has arguments, you have to list, during registration, the names of the registrations that should be passed for those arguments. For example, assume that Beer has three arguments:
Then, when we register Beer, we have to pass the names of the registrations for 'Barley', 'Hops', and 'Water' during registration:
In a statically typed language, we wouldn't have to list 'Barley', 'Hops', and 'Water' during registration since they would be discovered via reflection from the typed arguments of the Beer's constructor. This is what I meant when I wrote DI containers are less convenient in languages without runtime types.
Be that as it may, BottleJS looks nice.
As far as I can understand this article, this seems to be the way Angular puts together it's apps. Everything seems to guide you to modularize not just features, but components themselves. I've always loved this about Angular, but unfortunately, its steep learning curve and verbosity makes it difficult to work with. If React had done this from the beginning and not encourage sloppy components with no direction as to how to organize apps, I would have chosen React a long time ago for my apps. Instead, I use Vue since it resembles Angular in terms on syntax but it's simplified; now I can just apply this architecture for large apps.
Good to read better architectural articles regarding frontend.
However, I would argue that your counter repository is part of the domain, not infrastructure. The code necessary to build out your counter, includes your counter repository. The infrastructure part consists of things like base repositories and their methods.etc.
The code you put in a repository is always an aspect of business knowledge and therefore, belongs in the domain.
Thank you for the concise article/summary.
We almost do/did everything like that but the facade for the store.
I always thought exchanging the store would never be required/an option. Turned out in one of our projects we had to do exactly that (replacing redux with plain angular services).
Even though we had no facades for the store in place, the separation of the domain and presenters into dedicated services/components already helps a lot. A huge part of the (old) redux based implementations is now replaced and it is/was possible without too much effort/pain.
So even if it seems like a lot of effort in the beginning these abstractions help a lot in the long run.
Yes, the benefits of this architecture will really shine the most in the long run even though you might find it a little bit verbose at first.
Nice article!
I understand your feeling, coming from android / iOS, where many projects follow this kind of architecture decisions vs going into frontend projects where it's difficult to find (or at least in my experience) projects that are not coupled with frameworks.
Thanks for sharing
I like this architecture. It is simple and well divided.
Thanks for sharing.
Glad to hear you like it!
Brilliant article, I was wondering what do you think about having a wrapper around i.e pinia stores, that with pinia stores, live in application layer, that accept adapters for data fetching and if you ever need to switch from pinia to whatever else, you just adjust the wrapper for a particular store to accept different type of state, or even make an interface as to what you expect the pinia or w/e store does. so you'd endup with something like this new UserStore(userAdapter, piniaInstance). for me, I created a base class for storage wrappers and I pass piniaInstances inside actual wrappers implementations, so they are coupled in that sense, however I can then in Vue create a Context object that contains all the necessary stores,auth etc. and inject it into components where necessary. This idea came to me when I was trying to listen to actions on pinia store and I didn't like the way you had to check for what action was called etc.
Hi, Thank you for the great article.
I also agree that making week connection between modules is very important to long-term management.
by the way, recently Recoil is rising for state management, but It seems It's strongly connected with React and Hooks.
It makes me difficult to divide Infrastructure(state) layer from others.
have you any ideas about this architecture with Recoil?
Hello this is really cool architecture, was wondering if you could share some core where it becomes more complex or have much more in it so I could learn more about this implementation
Hi, I intend to publish another article just for this. Please look forward to it.
I've come to this article by recomendation and a very big thanks for this. I can say it is a really powerfull project management!
Hi, Huy.
Great article!
But I have less experience in Vue.js so could you give me an overview about react?
How can react project be structured with this pattern?
Best.