What is Server-Driven UI?

Server-driven UI (SDUI) is an emerging technique used by companies like Airbnb and Lyft that leverage the server to build the user interfaces of their mobile apps. This opens up new possibilities and addresses some fundamental challenges with native mobile app development. Before we look at how server-driven UI works, let’s take a look at how mobile apps are developed today.

How it Started

In a traditional mobile app the layout and presentation of the user interface is created by a developer and packaged into the app. The app package is submitted to the App/Play Store where it is reviewed by Apple or Google and then made available for users to install.

User interfaces in these apps are made dynamic by separating the UI from the data it displays. While the user interface is part of the app’s binary, the data is typically fetched from a server and embedded into the UI.

Let’s look at an example of a typical listing screen that displays a list of products. The developer will build a list view with a single row template used to display each product. In this case, we’ll display each product’s thumbnail, title and price.

When the listing screen is displayed to the user, the app fetches a list of products to display from a server.

[
    {
      "thumbnail": "https://images.example.com/instinct.jpg",
      "title": "Rocky Mountain Instinct",
      "description": "Stable and aggressive, the Instinct is..."
      "price": 6999.99,
      "rating": 4.8,
      "sale": false,
      "featured": false
    },
    {
      "thumbnail": "https://images.example.com/stumpjumper.jpg",
      "title": "Specialized Stumpjumper",
      "description": "The Stumpjumper brings all-new..."
      "price": 3178.99,
      "rating": 4.3,
      "sale": true,
      "featured": false
    },
    //...
]

The list of products, the data, is combined with the UI built by the developer and transformed into a list view.

The Release Cycle

Now let’s imagine after launching our listing screen we decide to add the product’s star rating to each row and give a special treatment to sale items.

The logic that determines how the data is presented for each row is built into the app so in order to make these changes to the user interface we need to run through a full release cycle. The process looks something like this:

  1. Developers write code to make the desired UI changes.
  2. The UI changes are reviewed by testers.
  3. A new version of the app is submitted to the App/Play Store.
  4. Apple/Google reviews and approves it.
  5. Users update to the new version.

For a typical app supporting iOS and Android the release cycle must be done twice, once for each platform—and generally you will need different developers for each one.

By the time these changes have made it to our users’ devices, we’re already looking to make additional changes. In this case, we now want to display featured products at the top of the list in a horizontal scroll container.

Once again, we have to go through the full release cycle to make these changes.

Between development, testing and waiting for approval—on both platforms—each of these simple changes take weeks or even months to make their way into the App/Play Store. And even after they’ve made it into the store, we still have to wait for our users to update to the new version of the app before they will see them.

The Problem

The necessity to run through a full release cycle for even simple UI changes comes with a few problems.

First, it slows down experimentation and iteration. The overhead of the release cycle means we are waiting long periods of time before understanding how users are responding to each change we make to the UI. Because of this, many companies fallback to testing prototypes instead of learning from live users. In an ideal world we could A/B test our user interfaces but the release cycle makes this difficult.

Second, as Ryan Brooks from Airbnb put it, it creates a versioning problem. Each time we release a new version of our app we have to wait for our users to update to it. Some will update right away, some will take their time and some won’t update at all. This creates a fragmented user experience.

Finally, because we have to develop our changes independently for iOS and Android, it can be difficult to keep our user interface consistent. Both platforms have different UI paradigms that must be accounted for and it’s common for the results to diverge from each other. Additionally, users on iOS typically update their apps more frequently than Android users which introduces even greater fragmentation.

How it’s Going

With the traditional development process the user interface is embedded in the app which makes it inflexible and difficult to update. But the data is fetched from a remote server. The data displayed in the app is always up-to-date and can be modified any time through a backend system. What if we could apply the same technique we use for data to the user interface itself?

What if we could apply the same technique we use for data to the user interface itself?

Enter server-driven UI. In a SDUI implementation the user interface in the app is a blank slate. The app knows it will be rendering a listing screen but makes no assumptions about how that screen will look. The app makes a request to the server which returns both the UI and the data together.

The response from the server is some form of proprietary markup that the app understands. Instead of fetching a list of products, the app fetches a list view, which contains a set of row views, each of which contains text and image views with information about spacing, alignment, color and typography.

{
  "list": {
    "rowHeight": 44,
    "dividerColor": "#979797",
    "rows": [
      {
        "padding": [7, 14, 7, 14],
        "image": {
          "source": "https://images.example.com/instinct.jpg",
          "alignment": "leading",
          "width": 30,
          "height": 30
        },
        "label": {
          "text": "Rocky Mountain Instinct",
          "alignment": "top",
          "fontSize": 11,
          "fontWeight": "semibold",
          "color": "#000000"
        },
        //...
      },
      //...
    ]
  }
}

The app renders the response from the server and the result is identical to the version using traditional development techniques.

Does this sound familiar? This is exactly how web browsers work with HTML and CSS. Remember, everything old is new again.

Advantages of Server-Driven UI

The resulting list screen using both the traditional development approach and the server-driven UI approach is identical. So what did SDUI really gain us?

The advantages of SDUI come into play when we want to make changes. In our previous example we went through two UI iterations that took weeks or months to get to our users because of the release cycle. Let’s revisit the release cycle and see how SDUI can streamline it.

  1. Developers write code to make the desired UI changes.
  2. The UI changes are reviewed by testers.
  3. A new version of the app is submitted to the App/Play Store.
  4. Apple/Google reviews and approves it.
  5. Users update to the new version.

With server-driven UI the first step is replaced with a server-side update to the listing screen markup. That’s it. The other four steps aren’t needed. We’re not writing any new code so we don’t need to test it. We’re not making any changes to the app, so we don’t need to submit a new version and therefore we don’t need to wait for Apple or Google’s approval. Since we haven’t submitted a new app, and our updates were made server-side, all users see the changes immediately.

The updates that previously took weeks or months can now be made in days or hours. The changes are made to both the iOS and Android app consistently and all users see the same version at the same time.

Two-Phase Rendering

In the SDUI example we saw that the server includes the data and user interface as a single response. The downside to this approach is that the user interface must be fetched every time the listing screen is viewed. The user is presented with a blank screen and shown a loading indicator while waiting for the UI and data from the server. This is a step backwards from the traditional approach where the UI is embedded in the app and users never have to wait for it to load.

An alternative way to implement SDUI, and the one that Judo uses, is to separate fetching the user interface and fetching the data into two phases. This has a dramatic reduction in the server response sizes for list views as the presentation markup doesn’t need to be repeated for each item. More importantly, this allows us to pre-fetch the user interface.

With this technique the UI can be fetched ahead of time and stored on disk so it is available before the user needs to see it. The user interface can even be fetched in the background while the user’s phone is in their pocket, keeping it up to date at all times. When the user opens the app and views the listing screen the UI is presented immediately. The data is then fetched from the server, combined with the pre-fetched UI and transformed into the list view.

This approach allows us to have our cake and eat it too. The result is imperceptible from the traditionally developed app but we have far greater control over how and when our user interface is updated.

Is This Allowed?

Apple and Google don’t allow you to modify the code in your app after it has been reviewed and released. At first glance it seems like a server-driven UI implementation would be in violation of this rule but this is not the case. SDUI customizes the user interface of your app based on the response from a server but it does not change the code. Most modern apps are already using some basic form of SDUI today.

Imagine our product listing page built using traditional development techniques. Each row in the list has a white background but our app contains logic to display rows for featured products with an orange background instead. This is a very simple example of server-driven UI. Based on the product’s featured status we are styling each row with either a white or orange background color. We are modifying the user interface of our app based on the response from the server. By updating our product’s featured status on the server, we are changing the UI remotely without an App/Play Store update.

Judo, and other server-driven UI implementations, expand on this same technique to provide a much greater degree of customization. In Judo’s case, our SDK contains the logic to render the user interface based on the server’s response. All the code is contained in the SDK and includes the finite set of what is possible. This code goes through the normal Apple review process the first time you integrate the SDK into your app. After that initial review, you can take advantage of SDUI to update parts of your user interface without having to go through the review process again.

Conclusion

Server-driven UI is new and requires a large amount of up-front investment to implement. Companies like Airbnb and Lyft are pioneering this space but not everyone has the capacity to develop their own SDUI implementation. At Judo we’re building a platform to make server-driven UI accessible to product teams of all sizes. If you’re interested in trying SDUI for yourself, download our free Mac app, check out the learning center and join our community of growing SDUI enthusiasts. I’ll see you there.


Share this post: