This article is an English translation of the original in my blog: Alejándonos de ReactJs y VueJs en el front end usando Clean Architecture.
One o...
For further actions, you may consider blocking this person and/or reporting abuse
The article title seems a little clickbaity for my taste. Even the Spanish one, same thing. From the title, you gather that the article is about NOT using VueJS/React on the front-end .
That’s what tricked me into reading this article. 🤷🏻♀️
Same ☝️.
I'm so glad I was "click-baited" into reading this article. This article, is one of the best frontend architecture articles I've read in a long time.
On Using Clean Architecture to Decouple Client Side Architecture from React.js or Vue.js
Similarly: A different approach to frontend architecture
That's true. When I read the title, I thought it was about not using VueJS or ReactJS.
I'm joining a meeting and could read few parts so I may come back later but now and just to clarify Angular is a Framework, also it is Vue, but not React or Preact which are Libs, there are so many differences (from the engineering point of view) that is not even ok to try to compare them 😅
A Framework makes you work on the way this framework was conceived while a lib let you choose which parts to use and how, how to structure your project and so on (that's also the reason why React is the TOP1 in loved, used and demanded)
Well if you think about it React forces you to write applications in a determined way too.
It's just less opinionated on some topics but still gives you a way to do things, the React way. Just saying the thing you have to pass props, never change props, and component will re-render automatically on changed props(or state) without having to manually tell the component what changed, that's already enough to enforce you a way to develop.
Just because React is less opinionated on things like global storage, router, i18n, forms etc.. It doesn't mean it's not a framework
But it's not, and it's not my opinion. React and Preact are not framewors and it's a fact. It's like saying Node is a framework or a language when Node is only a javascript runtime environment so in order to speak consistently and concisely, we need to categorise and qualify things like they are.
In computer programming, a software framework is an abstraction in which software, providing generic functionality, can be selectively changed by additional user-written code, thus providing application-specific software. It provides a standard way to build and deploy applications and is a universal, reusable software environment that provides particular functionality as part of a larger software platform to facilitate the development of software applications, products and solutions. Software frameworks may include support programs, compilers, code libraries, toolsets, and application programming interfaces (APIs) that bring together all the different components to enable development of a project or system.
Frameworks have key distinguishing features that separate them from normal libraries:
By the other hand, a software library is a suite of data and programming code that is used to develop software programs and applications. It is designed to assist both the programmer and the programming language compiler in building and executing software. It generally consists of pre-written code, classes, procedures, scripts, configuration data and more. Typically, a developer might manually add a software library to a program to achieve more functionality or to automate a process without writing code for it.
That being said, from the different options we have for the front-end, i'll pick 5 and they are categorised like this:
Hope it helps you understand the differences :)
Answering from non-work account
That's a really good answer. Yes even tho React has some sort of DI you can't really say it's extensible
When you import a lib just to achieve a goal you usually fit into this approach, otherwise you can either choose another one (and fit into it) or write down your approach and publish it as the new lib to do the same others do but on a different manner, then your lib will need to pass 2 filters:
I can understand your reasons to avoid using a lib or framework "as is" and in the end you can agree with me that is a try to avoid tech debt in a project, not less not more.
Then there reasons that counters this reinvented wheel. If you use react millions of devs out there will be available to work within your project in few hours, if you need higher performance and less included libs, you can simply pick preact and every react dev will be skilled to work with that as well.
If you create your own approach and build a project or even a company with that, the end result is that the world keeps rolling and new tech will appear anyway to solve other problems you don't even know about -yet- or to automate things you didn't even mind -yet- so people will like to use this "latest tech" (We know "latest" mean that it appeared 4-5 or 7 years ago and now it's popular and everyone works with that) so even if you figure out how to trick some dev to work in your company or project, they will eventually fly away to another company at the first sight of working on a non standard dinosaur. This will put you in need to increase the salary for your devs and new hires which is also costly and at this point, the life-cycle of your App will be near the end and needs a tech refresh regardless of your initial effort.
The end questions would be then, Is it worth? what do you prefer?
Hi, thanks for your comment.
Everything has advantages and disadvantages but in long-term applications I think it makes more sense to uncouple and in the future it will be appreciated in my experience.
Regards
Please, I know we live in an opinionated world where people believe what see in tik-tok and so but IT is a science, thus is well categorised. Before being ignorant in front of everyone and especially after the previous explanation make the simple search "react" in Google and you'll see:
React – A JavaScript library for building user interfaces.
Then search "Angular" and you will be able to read the following:
"Angular is a TypeScript-based free and open-source web application framework led by the Angular Team at Google..."
if your opinion is that React is a framework you must try to reach React devs and ask them to change the category of it's Library.
Maybe they can explain what I tried before on a way you can understand it.
So NO, you cannot use React as a framework because it's not a framework, the same way you cannot use Angular as library because it's not a library.
You cannot use a car to travel from europe to america because it's not a plane the same way you cannot use a plane for your commitment to work because it's not a car, even they are both vehicles.
It's not worth to argue if it's a framework or library? There's no clear boundary. This is also not the main point of this article. This is article is about decoupling your core logic from third party code. No matter you call it a framework or library, so that in case you have to migrate to a different library or framework, you don't have to rewrite all your core logic. For the front end world, it's more important as it evolves so fast. Don't expect something you love today will survive for long time.
Show us how, write an article and share with the community for it to be peer reviewed then
The key difference between the Library and Framework related to this article is something known as inversion of control (as I wrote above).
Let's explain inversion of control in detail:
When you import a library such react, you have to call the specific methods or functions of your choice and it's up to you when and where to call the Library, so you are in charge of the flow.
On the other hand, a framework itself makes a call to your code and provide you with some space to write down details. In other words, when using a framework, your framework is in charge of flow.
Having a library and having a framework are completely different levels of coupling just for this reason. If you want to change React with Preact for example you simply change one for another and update your method calls (related to the lib) for the ones of the new lib, test, fix and you're done. You cannot do that with a FrameWork because your code depends on the specific framework flow and way-to-do.
Don't get me wrong I'm just interested on the subject.
Your argument about being able to replace the calls seems a bit off, I mean Preact emulates exactly the same calls of React, maybe does things differently, but if it there was an Angular "emulator" you would be able to do the same. In Angular you are importing @Component, @Injectable, @Module etc, if you override them you're able to "emulate" Angular behavior as with Preact.
Even in Angular you decide what to import, what to use.
Angular just have more tools, it's batteries included, so they made it possible to extend it and to achieve some common tasks through "configurations". But that's it, it just has more tools by default.
Your notion of the role of IoC is correct. However not all frameworks are application frameworks.
React is not an application framework but React is a framework.
For a React component to get a chance to call React, React has to call the component first. The only time that isn't the case is in this one line of code:
And even that isn't just a library call - it's the entry point so React can "play the role of the main program in coordinating and sequencing rendering activity" and behave as a framework.
React is a (view component) framework
Your React Components (user code) are always called by React - that is IoC in action - used exactly in the manner of a framework.
Looking into it further - Redux maintainer Mark Erikson astutely observed
… or the way I like to put it:
In Kent C. Dodds's Application State Management with React - React is a state management library largely focuses on the React is your application (component-centric) style.
Given that React is used for state management, React is the backbone and the skeleton of the application and all functionality and capability tends to become deeply coupled with the React-ness of the overall client application. At this point React might as well be your application framework (and many developers use it in this fashion) - the missing bits and pieces are simply pulled in from the React ecosystem and these "pieces" tend to be specific to React (e.g. while other frameworks may offer hook-like services , hooks written for React will likely not work with other frameworks).
I argue that the React is your application (component-centric) style does not scale. It may work for smaller applications and has an attractive time-to-initial-success (TTIS) but due to the inherent internal coupling it may be more difficult to maintain over the long run. In a way the tools that are being used to implement the solution dominate the client architecture rather than the problem that is being solved.
Contrast that with Michel Weststrate's UI As An Afterthought which advocates a React is not your application (app-centric) style:
…
Here the application is built around the state management solution - Mobx in this particular case - and React's responsibilities are deliberately severely curtailed. Taken to the extreme the client application would eschew integration libraries like
react-reduxormobx-react-liteand instead define an application specific adaptor for the React side to access "the application" which then turns around to use whatever state management solution was actually chosen. In terms of the Hexagonal Architecture the application logic lives in the core while both React and the state management tool is on the "outside" being connected to the application logic via adaptors whose interfaces are dictated by the application logic.Note: the above article is advocating one particular flavour of React is not your application (app-centric).
But even in the case of React is not your application (app-centric) React is still calling the shots as it remains in firm control of the main/UI thread - i.e. the application logic only gets control when React calls a component via IoC. The primary benefit of this style is that it reduces the coupling between React and "the application" (and perhaps even the state management tool).
In effect React is not your application (app-centric) is the modern version of the Segregated DOM a concept which goes back to The Humble Dialog Box.
To wrestle control from React (while still using React) it is necessary to move "the application" into a web worker - example: React + Redux + Comlink = Off-main-thread.
The point is that it actually takes significant work and discipline to avoid React acting as your application's framework.
One issue that tends to rear it's head is that some application capabilities benefit from running on the main/UI thread. One solution is to "actorize" the application. That way it's simple to move the functionality back to the main thread should the need arise:
An actor is essentially a message processor (not an object or a component) which maintains it's own autonomous state. It doesn't share anything and only runs when it has a message to process; it processes any one message as quickly as possible while sending messages to other actors or even spawning new ones.
A lib deals with one or more tasks. React is a group of libraries, take a look at your package.json. In most project there are at least
and there are more, of course.
If you get a library to control your application flow it will do simply this, and this not means it's a framework.
Have you tried to import only a single lib from react and build the rest by your own on the top of that?
The thing is that you simply can.
In order to get some kinda like an actual framework you need a group of libraries (some has nothing to do with react itself such those for state management).
Here it goes a metaphor:
You can go to a scrapper, put some car parts in the same place on a random position and you can say "I've a car", well, eventually, with some work and using certain patterns and order you'll have a car made of isolated pieces but at the starting point you don't have a car, and depending on what you want to do with those parts and the parts you really need to accomplish your goal, you'll never end up with a car.
As I've already cited in my gist:
Martin Fowler: InversionOfControl (2005-Jun-26)
The litmus test:
Your code only starts the DOM renderer - at which point your code gives up control and your components are called by React to specialize the VDOM rendering behaviour - so React is a framework.
When the behaviour of the implementation contradicts the documentation then it's time to disregard the documentation.
I mean, you can consider react-dom the actual interpreter for react, but anyway we are talking about React as a whole. Of course if you start splitting its pieces it becomes less of a framework. So is angular, if you take a single element from it like the rxstore well its not a framework on his own
Just because the react team decided to separate react and react-dom in two different dependencies and allowed people to write their own "interpreter", it doesn't mean it's not a framework.
To the people getting triggered because of the "framework vs lib" discussion. Plus some considerations in regards of the article ;)
Both (React and Vuejs) are considered a "Delivery Mechanism" from the clean architecture point of view, so following that idea both fall into the same category, no matter if one is a framework and the other a library. Both are an abstraction on top of the DOM to facilitate building user interfaces. That's one of the important parts of the article together with trying to decouple/extracting important logic from it, so your code doesn't depend on any lib/framework that much. So, discussing if it's a framework or not is a bit pointless in my opinion.
I think one point to discuss is, if taking the time to code like this makes sense ? or at least to this high degree of decoupling. Because part of the idea is that you could easily interchange the delivery mechanism if you needed to. But in real life, how often does this happens? Which company/startup would be successful enough to last that many years where you would be in need of using a different lib/framework?
Don't get me wrong, this approach makes you write more testable code which is always a good thing and definitely is an approach that should/could be used when developing back-end systems, and personally I like it and try to stick to it as much as possible (it will always depend on the team though).
basically any company that's survived not fully digitizing until now - which is a large part of enterprise IT, manufacturing, banks and insurances. Startups are only a fraction of the market for User Interfaces. UIs can go into products facing customers or facing internal users. Internal promoters of a digitization project will easily get their budget turned down if the UI can't survive for a couple of years at least, and that means salvaging as much as possible from past projects
If you read all the comments about you'll probably find the point on the discussion avobe but I'll expand my boundaries to this one :D
I agree with you that being in need to change the lib/fw for the frontend would take years or decades. I.e. Spring that was released in 2002, Ruby on Rails in 2004, Symfony in 2005 and they are still being used widely. But let's think we've an Angular2 framework and that Google stop maintaining it like they did with tones of tech they released in the past ;)
In the matter of discussion we can introduce a workaround used for migrating monoliths into services (front end side) that also fits well for migrating modern frontend stacks.
You simply pick a feature, isolate it, build a new JS app with that -stand alone- and embed it into any element of your current view where you want to show that and connect it to the global state (if any).
Now you have an entire Angular app but a feature is provided with a different new hypothetical lib.
This is usually a bit easier to handle if you've a lib than if you've a framework and by the other hand the major part of logic on the frontend is related to conditional rendering of elements and having a 1st layer of security in the shape of form validation, which is easy to understand, document and replicate elsewhere. On top of that there's the fact of having functionalities write down in JS and picking an hypothetical JS lib for the "new frontend", then you'll be able to simply copy-paste your preferred methods/functions and refactor them with the "current future ES version" if you want to (js is retro compatible so it may not be even a need).
This is also easy with a lib where you call methods and just the ones that this lib provide than migrating a ng-if statement because it will need to be rewritten according to the new framework or lib.
At the end you'll have a good modern "new" application with the current stack, methodologies etc.... part by part, feature by feature, view by view... whatever is better depending on your base architecture (usually with the current stack would probably be component by component).
So it's this kind of decoupling really needed? Isn't it a patch to make the job of the devs more difficult to get in return... almost nothing? Wouldn't be better to design a good architecture from the beginning to make this process described above as easier as possible and nothing more?
It's a really nice article. However, I'd like to have some complaints/suggestions:
I could not more disagree on spacing. Although it's always a personal preference - I prefer 4-chars spacing, as it makes the code much better readable
Love it. So rare to see somebody discuss this beyond beginner/intermediate level topics like architecture with frontend UI!
Where were you 3 years ago?! ;)
Thanks!
This is an awesome article to me although the title made me confused a little bit at first. Honestly, I really want to learn more from your mentioned links in it, but they're all in Spanish. I think it would be a great help to the readers who want to learn more about your article if you could help to translate them to English. I'm willing to read them as soon as possible I know them translated.
Once again, thank you for the great job!
Okay, i've tried to think of ways to say this without coming off as harsh. I'm going to give pointed criticism and i promise my intent is not to "bash" you. I'm just going to give my honest take.
The Code
The code is bad, doesn't take advantage of implicit returns, hastily abstracts dependencies, makes decent integration testing fairly cumbersome because of the amount of dependency mocking you'd need to do. All in all, it would literally not pass code review, switch statements in a render function vs a hash map? This would get you paired with a senior for a few hours to fix this mess, it's that bad. It's a huge red flag. Too many code smells.
The Concept
The concept is a reasonable one for the backend where the "state" is usually colocated and composability isn't favored over inheritence. But it's just not great for the frontend. It's not composable, it's not easily maintained, it's not extensible, it's tightly coupled to your dependency setup, it's difficult to read, it's difficult to reason about, it's hard to test and therefore it should literally be avoided like the plague. It might actually be one of the worst architectures i've seen for frontend frameworks, including Anguler 1 (insider joke).
If your component/class isn't readable and you cannot discern what it's attempting to do in a short period of time, or extend it with confidence, in the tests/implementation, that it wouldn't break, it's not the solution to the problem.
This is the hastiest of hasty abstractions. Please never write code like this for the frontend. It's fun to see, but it's definitely not realistic or production worthy.
If this comes off as mean spirited, i promise that's not my intent, i'm trying to approach this in good faith.
The idea is good. Thank you! It’s really first time when I see so decoupled from frameworks and libs domain logic
I solve this by using a larger display ;) and I doubt 2-space indentatioin lets you see 'more code on each line' in ~99% of all cases. While 4-space indentation let's you much better see where functions/declarations start/end and what belongs together (no matter how long lines are).
Maybe we should take into account that the world is constantly changing. If we look back 10 years, the browser ecosystem has significantly changed, so I think we will see some changes on the framework side too. There are constantly new ideas trending.
A good software architecture should make us some kind of independent to changes of the framework. Otherwise you are constantly rewriting all your code over and over. I´m not sure if this is possible if you use React or Vue? I assume, if some Post-Vue-Framework is trending some day, people will start totally from scratch again.
Eventually, we are going to be moving away from React and Vue, so the question is how much of your codebase you can throw away then. Anyone remember flash-games, Rich Internet Applications and Silverlight?... 👵🧙
For the business logic part it's clear why you seperate it into the domain, what do you think about separating the UI/UX logic into its own domain as well? I've worked on collecting the most common UI phrases, properties and classes with some documentation and assigning a URL to them. The domains of designers, copy and product owners are more in the daily work of a frontend developer. So for the dev, it's going to be hard to advocate for an architecture that coworkers don't benefit from right then and there.
Correct me if I'm wrong but one particular downside I'm noticing from this is that if you write your components to use a state from a store or from some type of provider, now the component is coupled to that feature. Almost all your components should be written in such a way that they don't depend on anything. Only a top level component such as a page or template should handle fetching/changing state or retrieval of API data, but at the same time, ensure that you don't have too deep of a component tree that you need to pass state several levels down
Hi, thanks for your comment.
I think creating an agnostic of the app state component only has sense if this one is used in several contexts.
For example for a library of components as a table with advanced functionalities that will be used in several apps or a dropdown used in multiple places in your app.
But components (pages or not pages) used in a unique context I think that is not a problem.
Regards
I wanted something easier to work with than the big 3 so I created my own and wrote about it here:
dev.to/bretgeek/vibejs-a-small-jav...
Maybe someone out there will find interest in it:)
freecodecamp.org/news/the-differen...
That's pretty much what I was saying about React. Tbh I don't really care about the discussion but if you think about it, the while props passing and reactive re-rendering inside React is already a kind of Inversion of control if you think about it.
That's why I said it can be considered a framework at some extend, maybe without betteries included? Less opinionated? Still a framework. But yeah if you compare it to the alternatives it might look less of a framework
google.com/search?q=react&rlz=1C1C...
google.com/search?q=angular&rlz=1C...
I'm tired of discussing things that are not suitable for opinions. Things are what they are, not more, not less. I already defined the differences many times here. Both libs and frameworks came to solve the same root concern, it's just the engineering behind and the result, being something devs interact with on a given manner what categorise them to be part of a group or another.
Extrapolation:
Again you can consider that a car is a bike and you could argue that both have wheels, both have an engine, both... but they are in the market to solve different needs, and a bike is a bike and a car is a car even having more similarities than notable differences -leaving the visuals apart- unless you enter into the engineering world.
i.e. if you're driving at 80km/h and you want to turn right you need to turn your steering wheel to the right on a car, while on a bike you'll need to turn your handlebars to the left because some physic laws that are not matter of discussion here.
The differences are enough to avoid some crazy to build a bike with steering wheel and say "hey, it's a car". People would think he's silly or crazy, right? The same happens on any science when people try to give an opinion on things that they don't fully understand.
React could be considered a framework to an extent same way a horse could be considered as an organic car. Or a car could be a mechanical horse. Hotdog can be a sandwich. More about it here => youtube.com/watch?v=O9ak89FwYeI
There are differences between a library and a framework hence vue, angular and react are defined appropriately by the authors.
You could do similar things with both of them, but due to the differences associated by the accepted terminology, your experience will vary.
This is a causal argument that puts the things out of it's own boundaries to deal confusion and intends to take acceptance for the people who don't want to contrast the information. It needs people to blind trust them and the thrust on them are linear according to the similarities that can be abstracted between both groups.
Even the similarities that we can observe on them, let's define the items:
A car does not eat plants, also is not a mammal, has no wheels, is not a vehicle (it's currently an animal), not domesticated, it's not powered by engine and so on...
Let's define the items from the video:
Soup: a liquid dish, typically savoury and made by boiling meat, fish, or vegetables etc. in stock or water.
Is cereal any of this? Nope, cereals are grain and are put into milk (not water) without boiling or any other process.
It's a speech that usually seems funny to me, I don't consider causal arguments on other context but comedy. It's something that is not usually used in devs world but take care about politicians doing this to confront people :)
please, make your own post about FRM vs LIB. Thanks!
And then if you're still obsessed with it, you can just link it here instead of thrilling the main theme, creating the information overload and making us missing the comments that REALLY ARE connected to the topic.
Sorry for the tone, but I contained myself until reading your 101st comment on the non-topic. Thanks!
Hello,
Can you help me?
After the [yarn install], the [yarn test] is stopped with:
src/app/test/App.test.tsx
● Test suite failed to run
Cannot find module '@frontend-clean-architecture/core' from 'src/app/App.tsx'
...
This is exactly what was looming in my head since i've dived into professional frontend development. Thanks for putting it into words.
Not sure it scales well in a codebase maintained by a team/company. It's like asking to team mate to learn an extra layer of abstraction that fits over vue ?
Interesting, thanks for sharing !
You can decouple logic from react components without adding layers of abstraction other than the ones you'll get by default -usually- i.e. with HOCs (High Order Components) can be used for more things than just to increment New functionalities for other components. With HOCs you can actually separate responsibilities too.
You can create a HOC that accepts a React component as an argument, implements the data logic, and passes data, loading, and error as props into the wrapped React component.
This way your data and/or logic is decoupled from the UI.
Perhaps the Clean Architecture ceremony is getting in the way of the core message here.
Clean Architecture is a moniker created by Robert C. Martin as an elaboration of Alistair Cockburn's Hexagonal Architecture and as such he is a proponent of keeping frameworks at arm's length. His talk Architecture the Lost Years is relevant here as he critizes frameworks (in this case Rails) for interfering with effective solution architecture (Bring clarity to your monolith with Bounded Contexts tries to address this).
In UI As An Afterthough Michel Weststrate boils it down to one core idea:
So while his client side application is clearly a React application he can test the client side application logic without the UI (React):
A different approach to frontend architecture also demonstrates this approach by using an application specific interface instead of letting the UI bind to the stores directly.
But we all can agree that Vue and React are no UI frameworks, right? I am really not sure where this is coming from and why some people talk about them in this way.
As you can see from my comments above where I explained the difference between a lib and a framework I agree with you.
I think the reason is that many people in this platform are self-taught developers. Being self-taught means you only put attention and time to what you like most. Yo don't have to pass a networking or software engineering exam and if there's no one that puts you in the right direction... you'll learn "how to" do things with this "language/library/framework" because seeing things finished boosts your motivation so you ditch off the rest.
Of course an individual with this mindset hardly will do other thing than a "technician" work on a third-rate company or fighting in the freelance market for an average salary but there's always people that really want to learn more...
So I'm trying hard since long time ago defining things by what they are and make deeply tutorials/articles for all to get more than a surface knowledge and I hope it help someone :D
please, make your own post about FRM vs LIB. Thanks!
And then if you're still obsessed with it, you can just link it here instead of thrilling the main theme, creating the information overload and making us missing the comments that REALLY ARE connected to the topic.
Sorry for the tone, but I contained myself until reading your 101st comment on the non-topic. Thanks!
Thank you for this informative article. I have a question, please explain how to handle routing in a different application ? is it responsible of react, vue, or whatever ui lib or framework ? as an example handle login scenario when user login success I should redirect him to main page.
thanks in advance
Thanks for your wonderful article. You saved me a precious amount of time
The good old Onion layer architecture.
I like this and I think it's cool, however the amount of verbose code that has to be introduced in order to achieve this level of decoupling troubles me a bit
Fabio React is in no anyways a Framework take that out from your mind, who teached you that ? All The World knows that React is a Blody Library. Read well The React Documentation
So they say it is a library? I will say good luck extending a vue or angular application with react. Possible? Probably. Good idea? I do not think so. Call React whatever you like, it will always be used AS a framework
React is not a framework, it is just a Render library, it doesn't even manage state, a framework would do that.
It manages state. And anyway, managing state is not a requirement for being a framework. It's all about inversion of control out of the box
Clickbait
Hi, thanks, greate article.
can there be nested Plocs?
Thanks for this article it was very helpful .i just and wondering if you will translate your other react articles