Declarative UI — What, How, and Why?

Asaf Varon
Israeli Tech Radar
Published in
5 min readAug 17, 2022

--

Photo by Tengyart on Unsplash

Put simply, Declarative coding only instructs a program on what should be done, not how to do it.

The What?

When talking about declarative UI we first have to know that it’s a programming paradigm that focuses on describing the desired result and what it should look like to the user at a given application state.

It does not list the execution steps to get us the result but only the desired outcome.

The opposite programming paradigm will be Imperative UI, listing instructions that are changing the state of the program and manually changing the UI.

To make things clear… picture yourself walking into a fancy restaurant, the hostess welcomes you and takes you to your table, and brings you the menu. You open it looking forward to seeing the dishes they offer, but instead of the dish name it details the process of making it.. for example:

  • Add oil to a medium-sized pot over medium-high heat.
  • Once the oil is hot, add the garlic and let it cook for a minute or so (watch it closely and don’t let it burn).
  • Etc etc…

Instead of just seeing Pasta Arrabiata.

how would you feel??
Of course, most likely, this will never happen... Thank God!

The scenario I described is the imperative way to do things step-by-step until the desired result.

Most restaurants' menus use the declarative approach, showing the dish name, the price, and some of the ingredients.

The How?

The imperative approach would be to create instances for each UI element and perform mutations on them until we get to the final design.

A good example is XML layouts in Android. We design the widgets and components which are then rendered for the user to see and interact with.

For example, let’s have a quick look at how to set up a list.

  • Define ListView in your layout XML
  • Build the ListView child item (also XML)
  • Build the adapter class

In this example, I used the out-of-box adapter provided by Android (just to save up on some space). Still, in real-life applications, you will most likely not use this adapter. You will have to create your own adapter class which extends BaseAdapter, implementing override methods and using LayoutInflater inside getView() with its child view XML as I showed in step 2… repeating the same process of finding the views by the ids and setting the relevant data to them.

  • Find the ListView in the code and create the adapter instance

myStringArray is the data required for the adapter. (child elements)

  • Attach the adapter to the ListView

The declarative approach specifies from the start a blueprint that contains all the needed setup instead of starting from base instances and mutating them. This allows the developers to design the user interface based on the data received.

  • Android example using Jetpack Compose

MessageRow is another Composable to display the child item.
All using Kotlin and no XML!

  • Flutter example:

iterating over the itemCount depending on the messages.length (data),
itemBuilder
will create each child item (widget).

And that is it! no further code is required.

In both cases, we can change the UI dynamically, but the big difference is that in the declarative approach the framework takes care of redrawing everything to match the new blueprint.

The Why?

As a mobile architect at Tikal, I have worked with many clients on many projects, from small startups to large corporates, exploring all UI approaches, starting from classic imperative and shifting to the declarative side.

Here are a few advantages I think you should consider when using the declarative approach:

  • The syntax is shorter and cleaner, which speeds up the development process.
  • Less Code, Less Bugs, Easier to Test, Easier to Maintain ;)
  • You use the same programming language for the UI and the logic.
  • You CAN NOT modify the UI from multiple places, this will ensure correct architecture and a single source of truth for every UI element.
  • UI elements are easily reused and composed together.
  • When combining reactive programming we can have a single component render/rebuild only itself, which will result in better performance than rebuilding the entire page.

Start thinking declaratively

As Mobile and Web development progresses and reaches more and more people, we can see why the big vendors are pushing us towards modern and more expressive programming languages that support the declarative approach.

SwiftUI for iOS

Jetpack Compose for Android

And of course, Flutter which is all declarative.

These days, with modern CPUs, it is OK to accept rebuilding parts of the UI from scratch instead of modifying them.

Conclusion

We saw what declarative UI is and why it’s gaining popularity.
As declarative UI concepts become more popular, it's worth understanding their how and why and keeping track of their evolution and latest updates.

I hope you enjoyed this reading and better understanding the different paradigms.

--

--