Unraveling SDUI: A Deep Dive into Server Driven User Interfaces using Mirai in Flutter.

Roberto Carlos
4 min readAug 16, 2023

--

In the realm of digital interfaces, there’s a concept that’s becoming increasingly pivotal: the Server Driven User Interface (SDUI). But what exactly is SDUI, and why is it so crucial to understand?

What is SDUI?

SDUI is a design paradigm where the server dictates the structure and behavior of the user interface, rather than relying on a fixed, client-side UI. In essence, instead of having a static interface embedded in the app, the server dynamically generates the UI based on various factors, such as user preferences, context, or real-time data. But we can combine the static interface and some SDUI widgets to create beautiful and immersive UI’s.

Now, let’s delve into why grasping this concept is not just beneficial but essential:

  1. Dynamic and Adaptive Experiences: With SDUI, applications can change their interface in real-time based on our server data. This adaptability ensures that users always have an interface tailored to their current needs and context.
  2. Efficient Development Workflow: By centralizing UI logic on the server, developers can make interface changes without needing to push app updates. This streamlining accelerates the development process and allows for rapid iterations based on feedback. (this one is really important for the big apps, an standard)
  3. Uniformity Across Platforms: SDUI ensures a consistent user experience across various platforms. Whether accessed from a mobile device, desktop, or other interfaces, the user encounters a consistent and unified UI, enhancing user satisfaction.
  4. Cost and Time Efficiency: Implementing SDUI can lead to significant savings in both time and resources. The reduced need for client-side updates, combined with the ability to make on-the-fly UI changes, makes SDUI a cost-effective solution for businesses.

For this example, we’ll introduce Mirai, a valuable package for Flutter use.

What is Mirai?

“Mirai is a Server-Driven UI (SDUI) library for Flutter. It empowers developers to construct stunning cross-platform applications using JSON in real-time.”

Let’s Dive into the Code!

In this example, we will construct a basic UI by fetching a simple JSON from a mock server (assuming you already have a Flutter project set up). To integrate the library into our Flutter project, run the following command in the terminal: flutter pub add Mirai.

flutter pub add mirai

Also we’re gonna install DIO, that is gonna help us to make our http request

flutter pub add dio

And now we’re ready for the action:

In our Main we’re gonna setup our MiraiApp

import 'package:flutter/material.dart';
import 'package:mirai/mirai.dart';
import 'package:dio/dio.dart';

void main() async {
final dio = Dio();

await Mirai.initialize(
dio: dio,
);

runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});


@override
Widget build(BuildContext context) {

//MiraiApp is gonna replace our MaterialApp
return MiraiApp(
title: 'Flutter Demo',
homeBuilder: (context) {
return Scaffold(body: Container(),);
},
);
}
}

This will establish the foundation for rendering UI widgets. I understand we haven’t displayed anything yet, but let’s retrieve our JSON and unveil the magic! 🔮

import 'package:dio/dio.dart';
import 'package:mirai_example/pages/home/helpers/testing_jsons/example.dart';

class DataService {
static final Dio _dio = Dio();

static Future<Map<String, dynamic>> getJson() async {
try {
//Replace this to your own url server
Response response = await _dio
.get('https://mocki.io/v1/950d06ad-3a6d-47dd-bfa5-19891c6938eb');
return response.data;
} catch (e) {
throw Exception('Error getting data: $e');
}
}

}

but what we’re trying to fetch exactly? here it is

{
"type": "scaffold",
"appBar": {
"type": "appBar",
"title": {"type": "text", "data": "Appbar"},
"leading": {
"type": "iconButton",
"child": {"type": "icon", "iconType": "material", "icon": "menu"},
"onPressed": {}
},
"actions": [
{
"type": "iconButton",
"child": {
"type": "icon",
"iconType": "cupertino",
"icon": "heart_solid"
},
"onPressed": {}
},
{
"type": "iconButton",
"child": {"type": "icon", "iconType": "material", "icon": "search"},
"onPressed": {}
},
{
"type": "iconButton",
"child": {
"type": "icon",
"iconType": "material",
"icon": "more_horiz"
},
"onPressed": {}
}
]
},
"body": {
"type": "column",
"crossAxisAlignment": "center",
"mainAxisAlignment": "center",
"children": [
{
"type": "container",
"padding": {"left": 30, "right": 30},
"child": {
"type": "card",
"color": "#ff000000",
"child": {
"type": "row",
"children": [
{
"type": "container",
"padding": {"top": 80, "bottom": 80, "left": 20},
"child": {
"type": "text",
"data": "Our first SDUI widget",
"style": {
"fontSize": 24,
"fontWeight": "w800",
"color": "#ffC8A2C8"
}
}
}
]
}
}
}
]
}
}

Can you see? It’s essentially Flutter widgets represented in JSON. This is where the magic happens. When crafting your JSON, ensure you adhere to the guidelines we’ve set for all the widgets.

Now, let’s explore how to display the JSON we’ve just retrieved.

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:mirai/mirai.dart';
import 'package:mirai_example/data/api.dart';

void main() async {
final dio = Dio();

await Mirai.initialize(
dio: dio,
);

runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({super.key});

// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MiraiApp(
title: 'Sdui Example',
homeBuilder: (context) {
return FutureBuilder(
future: DataService.getJson(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
return Mirai.fromJson(snapshot.data, context) ??
const MaterialApp(
home: Scaffold(
body: Center(child: CircularProgressIndicator())));
},
);
},
);
}
}

Look:

Mirai.fromJson(snapshot.data, context)

This is precisely what will be rendered from our JSON: all the widgets. The futureBuilder will handle the future data coming from our server.

And what does it look like? Like this:

Of course this is just an example, did that seem a bit complex? Nah, it was straightforward! Next time, we might delve deeper into the JSON file and create an incredibly beautiful UI, but for now, that’s all. Thank you for reading, and any feedback is greatly appreciated 🙏🏻.

Keep Fluttering🪽 💙!

--

--