CraftD: Server Driven UI for all platforms

Rodrigo Vianna Calixto de Oliveira
CodandoTV
Published in
6 min readJul 29, 2024

Have you ever thought about creating app screens using the Server Driven UI concept quickly and easily?

The purpose of this article is to explain the solution and help you assess if it meets your needs. Within the text, you will find hyperlinks to code guides and variations focused on implementing each platform.

Introduction to Server Driven UI

A brief context for those who are not familiar with SDUI.

Server Driven UI is an innovative approach to user interface design and development. Instead of leaving the responsibility of building and managing the interface to the user’s device — which is quite common — SDUI delegates this task to the server. With the logic and data controlled server-side, the server decides how the interface should appear and behave. This allows for greater flexibility and the ability to quickly adapt the interface as needs change.

Due to these advantages, SDUI has gained prominence in recent years as an efficient solution for businesses that need to deliver interfaces quickly and in a customized way. Many companies are looking or developing their own solutions to implement this approach and adapt it to their specific scenarios. After all, who doesn’t want to make fast and effective deliveries?

When products are delivered quickly and with quality, all stakeholders are satisfied. And when everyone is happy, success is guaranteed, right?

Meet CraftD!

Now that I’ve introduced it, let’s go?

Origin and Evolution for All Platforms

Due to this need, the CraftD library was born. It evolved from a previous solution called DynamicView (deprecated), which had been improved over the years. Some companies adopted this library or adapted it for their own needs.

However, I always felt the lack of a cohesive and uniform solution for all platforms. I wanted something that could be used not only on Android but also ensured a consistent and efficient experience during development, with consistent class names, methods, and practices for all platforms. Moreover, it needed to be versatile enough to be used in any project.

With this goal in mind, I started developing CraftD, and together with the CodandoTV community, we created libraries for the development of dynamic interfaces using SDUI, supporting:

- Android Compose

- Android View System

- iOS SwiftUI

- Flutter

- KMP Compose (in progress)

CraftD has the capability to support you in creating and customizing your own components, working with routes, sending analytics/monitoring, and is capable of receiving other streams smoothly while interacting with screen components and still supports you using your Design System and finally, most importantly, making deliveries without needing to upload a new app version in the store.

Understanding the Solution

The basis of the solution is to use native list components such as ListView (Flutter), RecycleView (ViewSystem), LazyColumn (Compose), LazyVStack (iOS) respective of their platforms. And using CraftD, you have an itemType mechanism ensuring all the responsibility for displaying the screen components.

With this, a sea of possibilities that CraftD delivers for you opens up, such as:

Oficial Documentation from CraftD — Android Setup
Oficial Documentation from CraftD — How to Use
  • Use components from CraftD, that is, each platform within the lib already provides some components ready for you to use
But it does not just stick to these, what the lib provides whether for you to consume or use as an example
Oficial Documentation from CraftD — Flutter How to use
  • The flexibility to perform interactions with external actions, such as deeplink, sending metrics or monitoring, is guaranteed by the component called CraftDynamic. This component is responsible for the entire functioning of the library and is present in all its variants. Thus, all variants have a type of fallback that allows interaction with the user’s click actions.
//Exemplo Android
@Composable
fun InitialScreen(
vm: SampleCraftDComposeViewModel
) {
val properties by vm.properties.collectAsStateWithLifecycle()
val craftdBuilderManager = remember {
CraftDBuilderManager().add(
MySampleButtonComposeBuilder()
)
}
LaunchedEffect(Unit) {
vm.loadProperties()
}
    CraftDynamic(
properties = properties,
craftDBuilderManager = craftdBuilderManager
) {
//Fallback
println(
">>>> category ${it.analytics?.category} -" + " action ${it.analytics?.action} -" + " label ${it.analytics?.label} -" + " deeplink ${it.deeplink}"
)
}
}
  • But if you still read and want to have the power to control the assembly of how it will be done on the screen and use just the itemType mechanism, you can also do this easily by creating your own variants of “CraftDynamic” and using the mechanism with the .craft method, remembering that this is standardized for all platforms.
//Exemplo Android
@Composable
fun MyComponent(
properties: ImmutableList<SimpleProperties>,
modifier: Modifier = Modifier,
craftDBuilderManager : CraftDBuilderManager,
onAction: (ActionProperties) -> Unit
) {
//LazyColumn or another component
LazyColumn(
modifier
) {
items(
count = properties.size,
) { index ->
val model = properties[index]
val builder = craftDBuilderManager.getBuilder(model.key)

// the craft method will take care of component management for you
builder.craft(model = model) {
onAction(it)
}
}
}
}
  • Versatility to work with any data source, by default SDUI is data that comes from the server, that is, it can be used by any type of data source and in this example, it will use a JSON and an array of “components” and within it has two important fields, the key that will be used in the itemType to be able to distinguish what each component is and the value that can be anything that has been mapped in your object, yes anything at all! for example:
[
{
"key": "CraftDTextView",
"value": {
"text": "Knife",
"backgroundHex": "#9A71F6",
"textSize": "30",
"textColorHex": "#000000"
}
},
{
"key": "CraftDButton",
"value": {
"text": "Some Action :)",
"textColorHex": "#9100a0",
"actionProperties": {
"deeplink": "dynamicview://any",
"analytics": {
"category": "hello",
"action": "world",
"label": "everywhere"
}
}
}
]

Remembering that the example was given with a JSON coming from any API, however, it is worth reinforcing that it is necessary to have only a data source, that is, it can be from RemoteConfig or even locally or local json, etc..

With this, you would have all the flexibility of using CraftD.

I tried to offer an overview of the library for you. Follow the CodandoTV channel and the repository to stay updated. If you want to participate in this project, feel free to visit the repository or get in touch with me or talk with us in our Discord community.

If you want to follow the development, take a look our examples:

And that’s all folks. It is worth reinforcing that the idea of CraftD is not to be a silver bullet for all functionalities and screens, but for certain cases it will definitely meet your needs. Due to the levels of use that you can make, you will be able to adapt it to your project easily, as the idea of CraftD is to take responsibility for assembling your layout, leaving room to search from any data source, customizing your needs with your needs.

All documentation is on the website: https://codandotv.gitbook.io/craftd

Code repository: https://github.com/CodandoTV/CraftD

video: https://youtu.be/Co-e1QPD73M?si=pFCPfcirjZ7egHd7

--

--