Here we see a lot less stuff in the Jetpack Compose variant. Most of this is due to the Kotlin DSL that was made for Jetpack Compose. If you don’t know what a Kotlin DSL is, you can read a bit more about it in the documentation. In summary, it helps us write declarative code in a nice format.

Another thing we see in the Jetpack Compose sample is the use of the withOpacity extension function. This may look great, but when we look at the documentation of this method, we see another indication that this toolkit is still in its early stages. It reads:

TEMPORARY solution to apply an opacity for the [TextStyle] even if it has no color provided. We wanted to have this right now to improve our tutorial for ADS. But the problem is actually way wider and we would need to rethink how we apply modifications like this to our styles and do we need similar methods for other params we have in TextStyle. We will continue investigation as part of b/141362712

So to summarise, both UI descriptions look quite similar. Widget or composable means pretty much the same thing, and besides some boilerplate differences, they look very much alike.

Hot Reload and @Preview

If you’re an Android developer, you probably have a healthy distaste for anything that promises to change your app’s code while it’s running on the device. Previous versions of Android Studio contained a feature called “Instant Run” which promised to do just that. However, this often did not work or led to subtle bugs, and you always ended up re-building the whole app anyway.

So naturally I was a bit skeptical when Flutter mentioned “Hot Reloading”. And to be fair, in my first hours with Flutter I did re-build the application a lot of times because I didn’t believe it was Hot Reloading as fast as it did. But it was. This is a game-changer! Whatever you change in your UI, the app just continues running, the state is preserved, and the changes are immediately reflected in the app. I can’t stress enough how amazing this is for a mobile developer, and how much I want this!

On the other hand, Jetpack Compose also has quite an amazing feature so you can preview your Composables. You can add a Composable which you annotate with @Preview, and it will be rendered in the Design tab of your IDE. I see a lot of potential for this feature using it for Design System documentation. For example, imagine you want to check how a Composable will look in light mode vs dark mode. Or you want to see how it behaves with different types of inputs. You could add multiple @Preview methods and they will display like this:

Both Hot Reloading and @Preview are amazing in my opinion. In my ideal world, I’d like to have a mix of both. It seems Flutter is currently working on a feature called HotUI (video here) which could get close to @Preview in functionality. Let’s hope that Jetpack Compose can also pick up hot reloading!

Other random thoughts

In this blog post I compare Flutter and Jetpack Compose, but they seem to be two samples of a much broader movement in tech towards declarative UIs. Apple released SwiftUI, which is similar to Jetpack Compose in its features. On web, the trend has been going on for longer, with React gaining a lot of traction. It’s interesting to watch this shift happening, and I’m intrigued to see where this will end.

For the sample app I was writing with Flutter, I needed some simple model classes. I’m used to working with data classes and sealed classes in Kotlin, and was expecting to be able to find the same in the Dart language, used for Flutter. Boy, was I wrong. There is no easy way to write an immutable data structure that automatically deals with stuff like hashCode and equals . There is a Flutter library called build_value that helps (see explanation) but that requires code generation. Maybe Kotlin developers are just spoiled 😬

At the conference I noticed that there’s a lot of discussion going on in the Flutter world around state management and architectural patterns. It seems the community is choosing a wide range of possible patterns, ranging from using the basic setState method provided by Flutter, all the way to using the very opinionated redux architecture and corresponding package, with stuff like provider , bloc and mobX in the middle. I’m curious about the patterns that will emerge and stabilize.

In Jetpack Compose, there is some talk about state management. You can pass an @Model instance to your subtree of Composables to pass data, or use something called an Ambient to create some data that should be accessible from other places. However, documentation is still quite sparse on this, and I haven’t had the time to really investigate it. In a next blog I’ll dive deeper into state management with Compose, describing the current landscape and trying to look into what the future will bring. Follow me on Twitter to get a notification when this blog is finished!