Author: Karsten Silz
Oct 27, 2021   |  updated Jan 24, 2022 3 min read

Permalink: https://betterprojectsfaster.com/guide/getting-started-declarative-ui/

Getting Started: Declarative UIs

What’s This?

I help you learn declarative UIs, the state-of-the-art in building user interfaces.


What are Declarative UIs?

Let me explain with a sample application in a video from a talk of mine at JJUG CCC Spring 2021. The section about declarative UIs starts at 5:33 minutes and ends at 10:36 minutes. The player below is set to the right time already:


So let me sum up declarative UIs:

  • UI as code
  • Status & events
  • Framework drives updates

And who uses declarative UIs? That’s an update to the list of tools from the video. Declarative UIs are recommended here:

  • iOS and macOS: Apple Swift UI (since 2019)
  • Android: Jetpack Compose (since July 2021)

Declarative UIs are or will be an option here:

  • Web: React (since 2013)
  • Windows: .NET MAUI (moved from November 2021 to Q2/2022)

How do Declarative UIs Code Look Like?

Apple’s SwiftUI

SwiftUI is Apple’s take on declarative front-ends. Here’s the counter example from the talk, with slightly changed formatting:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
@State var count: Int = 0

var body: some
View {
  VStack(alignment: .center,
    content: {
      Text("Counter: \(count)").padding()
      Button(
        action: { self.count++ },
        label: { Text("Increment") }
      )
    }
  )
}

Google’s Flutter

Flutter is Google’s cross-platform implementation of declarative front-ends. It reached the stable version 1.0 for mobile in December 2018. Here’s what the SwiftUI counter sample looks like in Flutter:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
int _counter = 0;

return Column(
  mainAxisAlignment: MainAxisAlignment.center,
  children: [
    Text( 'Counter: $_counter' ),
    TextButton(
      onPressed: () =>
        setState({
          _counter++
        }),
        child: Text( 'Increment' ),
    ),
  ],
);

If you want to lean Flutter, then I got you covered!

Google’s Jetpack Compose

Jetpack Compose is Google’s Android implementation of declarative front-ends. So Google has two different horses in this race: Jetpack Compose and Flutter. Of course, it’s Google! 😒

Jetpack Compose went 1.0 on July 28, 2021.

I adopted the counter sample in this tutorial to look like the SwiftUI sample above:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
val count = +state{0}

Column(Spacing(16.dp)) {
  Container() {
    Column() {
      Text(
        text = "Counter: ${count.value}",
        modifier = Spacing(8.dp)
      )
      Button(
        text = "Increase",
        onClick = {
          count.value++
        }
      )
    }
  }
}

Microsoft’s .NET Multi-platform App UI (MAUI)

.NET MAUI is part of .NET 6 and was recently delayed from November 2021 to Q2/2022. And if “Maui” rings a bell for you - it’s the second-largest island of Hawaii.

Microsoft calls its implementation of declarative front-ends “Model-View-Update” (MVU). Here’s what I think the SwiftUI sample from above will look like in MVU. I adapted the sample from the announcement post:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
readonly State<int> count = 0;

[Body]
View body() => new StackLayout {
  new Label( "Counter: {count}" ),
  new Button(
    () => $"Increment",
    () => count.Value ++
  )
};

Facebook’s React

And finally, here’s what the counter looks like in Facebook’s React for web applications. I adapted it from this Stackblitz sample. You see some HTML code in there because I don’t use components to keep things simple. If I did, it would look as declarative as the other examples:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class App extends React.Component {
  state = {
    counter: 0
  }

  render() {
    return <div>
      <p>Counter: {this.state.counter}</p>
      <button onClick={
        () => this.setState({
            counter: this.state.counter + 1
          })`
        }>Increase</button>
    </div>
  }`
}

If you want to lean React, then I can help you!


comments powered by Disqus