A typical SaaS product is built in two broad technical areas, the backend and the frontend. The frontend domain is a more recent aspect, because while HTML was always around to help model how the product is going to look like for the user, it was only much later that more and more aspects were added to the client tech, allowing it to become a big enough development area.
Usually as companies start, it is natural to focus a lot the core technology, and the user interface is not as evolved. Moreover, many user interfaces are built for internal use, so how that is built is of even lesser importance in the beginning. So the investment in the frontend domain is smaller in comparison to the backend. This as a side effect also leads to the idea that client side development should go faster!
Now how do we make things to faster without investing more into it? Introduce configuration driven UI. Engineers can write configuration to construct the UI. Write client side code once, repeat it as many times just via configration. There you have it, the most optimized application, where its not code folks, its configuration.
But is it what it looks like? Maybe yes, but in most cases, no.
What is configuration
Configuration is the arrangement of things.
In the frontend context, there can be several type of "arrangement of things". Data that defines the arrangement of UI elements is one type of configuration. The arrangement of pages within a webapp can also be a type of configuration. If abstracted for such a purpose, even the behaviour of the UI element can be driven by a definition that will qualify to be a configuration.
Common configurations used for constructing UI
Let us consider existing configuration based systems that help create the UI experience. It might be hard to appreciate it, but all the client side technologies rely heavily on configuration just because of how the elements on the UI are are ordered set of items, with several nesting possibilities.
HTML
HTML is configuration. It defines the arrangement of items in the browser.
MVC - Model View Controller
With more and more feature requirements on the UI, javascript came along to allow programmatic evaluations, apart from just HTML configuration. But soon further abstractions came up, so that this layer of logic can also be repeated and organized similar to configurations.
Modern Frontend Frameworks
Frameworks like React, Vue, Angular, etc. combine the lessons learnt and experiences gained in the software industry's considerable time with frontend technologies, into a set of best practices, leading to an API that is the best possible way to define the arrangement and behaviour of the elements on the browser.
These frameworks rely heavily on XML like format of organizaing client side code. While earlier only the arrangement of elements was XML (HTML), now even the javascript logic can be abstracted and organized in a way that can be applied as XML (JSX) with variants controlled by "props". These are all configuration based systems, with additional features of reuability and composability.
The evolution of client side configuration for UI
Notice how with the evolution of frontend technologies from HTML to React, lead to pushing complex verbose configurations behind simplified and higher level abstractions. All you need now are props or in other words data, that can be fed to the components to configure a repeated UI element structure. A different model layer is still needed by each component, to be able to transform the incoming data from the backend service into the required prop format.
Apart from React component abstractions, the model layer can also be unified by technologies that can collect the data from different backend services and provided it to the client side in a uniform format. Solutions like graphql allow the UI to use a common client.
Do you need a custom client side config for UI?
Most large projects are at this point thinking how to make it even more simple With all the model and view level abstraction in place, is there scope of further simplifying the configurations for the UI? Most of these simplifications are built with JSON files containing configuration about a page based on a pre decided contract, and those configurations are then fed into a component.
These are just a large number of props meant for components. Having a very broad API of component props is bad from an architectural standpoint. The large number of props suggests violation of the open close design principle. Whenever the number of props for a component increases, the standard solution is to use render props, to give full flexibility to the consumer on the configurability of a portion of the component. If most of the parts of the component are configurable by props, the component itself loses its significance.
Backend configuration driven UI
Since further client side configurations are not suitable, can we explore backend configurations to be able to define the UI elements on the browser? As in the diagram, How about the backend service associated with a particular page specifying which component is required to be rendered. This is the top level of backend configuration driven UI.
Drilling down into Backend configuration
Further if you drill down into it, the backend configurations can also specify the order and component names of the contents of a page. This can be done at more and more granular levels, if required. This lower level of configuration required to structure the look and feel of UI is exactly what React does for us at the Client side! And so what we are really talking about is backend templating.
Custom Templating concerns
For backend templating, the data is collected, passed into a template definition, processed into the required API format. Once received on the client side, the data is then parsed to be converted into react components. This has several problems.
Redundant
The whole process of converting the data into the template, transforming into an api data and finally parsing can be totally eliminated with templating at the client side directly.
Complicated
The backed template must be capable enough of configuring not just the layout but usability logic on the browser, this is very hard to build custom.
Separation of concerns
The templating part is a client side concern, which gets mixed now into the backend data logic.
Solutions for templating at the backend
Redundancy, complications and separation of concerns Translating the server templating format into API format received at the client side further translating this data back into React has too much redundancy. An inhouse templating mechanism at the backend is hard to build (logic at run time on the client side) and to maintain. Typically, this is done via React SSR (hydration) or better RSCs. Not much benefits of shifting the templating from the client side to backend, other than load time improvements and SEO (all the benefits of server side rendering).
Data driven backend configuration for UI
Backend configuration driven UI makes the most sense in case the UI is actually derived from the data itself, without the need of any more modifications. Very small backend template and translation layers Very little additional logic like element relationships and flows UI driven directly by data Redundancy, Complications and Seperation of concerns For example in case of forms, the data can be used to derive the UI elements associated with the data, and appropriately rendered. Little further information is needed for this purpose.
A Hybrid approach for generalizing repeated UI
Webapps that do need configuration driven UI, should take a hybrid approach in building it. Only the parts which deal directly with data to be transformed into the UI with little or no complexities in between qualify for the generic abstraction. Other parts of the app should depend on the client and backend seperation.
Summary
The architecture of web applications should not be based on making development faster. This leads to bad decisions. The focus should be on creating optimal and well designeed systems, that will automatically lead to quick development time, without comporomising on long term maintainablity and scalability.
Modern frontend frameworks are very good configuration based rendering mechanisms and there is hardly any point of creating one for a project.
Backend configuration driven UI is good if the stored data can be directly and easily transpated to renderable items.
A hybrid of classical backend and frontend decoupled webapp and parts of the app with the UI rendered from backend configuration can be the best for those apps that do have data translating directly to the UI.