Swift and SwiftUI tutorials for Swift Developers

SwiftUI vs Jetpack Compose

The world of mobile development has undergone a metamorphosis. If you are a veteran iOS developer, you will remember the days of fighting with AutoLayout, connecting IBOutlets, and managing the lifecycle of UIViewController in UIKit. If you are new to the ecosystem, you probably landed directly in the declarative paradise of SwiftUI.

But on the other side of the wall, in the Android ecosystem, a twin revolution has occurred. Google has released Jetpack Compose, a tool that suspiciously resembles our beloved Apple framework.

In this exhaustive tutorial, we are going to dissect what these two technologies are. Not from a neutral point of view, but from the perspective of a Swift and SwiftUI expert. Why should you care about Jetpack Compose? Because understanding it will make you a more complete mobile developer and open the doors to modern cross-platform development.


The Paradigm Shift: From Imperative to Declarative

Before entering the comparison, we must understand the ground we walk on. Both SwiftUI and Jetpack Compose were born to solve the same problem: the unsustainable complexity of imperative UIs.

In the old model (UIKit on iOS, XML on Android), the developer was responsible for how the interface changed.

  • UIKit: “Find the button, change its text, then find the view, change its background color.”

In the modern model (Swift + SwiftUI / Kotlin + Compose), the developer describes what they want to show.

  • SwiftUI: “The view is blue and has this text. If the state changes, redraw yourself automatically.”

This shift towards Declarative UI is the dominant software development trend of the decade.


What is SwiftUI? (A Refresher for the iOS Developer)

As an iOS developer, you have likely already touched SwiftUI, but let’s define it formally. Launched at WWDC 2019, SwiftUI is Apple’s user interface framework built entirely in Swift.

Its fundamental pillars:

  1. Single Source of Truth: Through property wrappers like @State@Binding, and @EnvironmentObject, data flows in a single direction.
  2. View as Struct: Unlike UIKit, where views were heavy classes (UIView), in SwiftUI they are lightweight and disposable value structures (struct).
  3. Composition: We build complex interfaces by combining small, simple views.

SwiftUI is not just a coat of paint; it is a fundamental rewrite of how Apple understands visual development, leveraging the power of the Swift compiler.


What is Jetpack Compose?

Here is where the “rival” enters. Jetpack Compose is Google’s modern toolkit for building native UI on Android. It was released in stable version in July 2021, two years after SwiftUI, which allowed it to learn from some of Apple’s successes (and mistakes).

It is written entirely in Kotlin, the language that has replaced Java on Android, just as Swift replaced Objective-C.

How does it work?

Instead of editing XML files and connecting them with Java/Kotlin code (the equivalent of Storyboards), in Compose you write functions. Yes, you read that right. While in SwiftUI the basic unit is a struct, in Compose the basic unit is a function annotated with @Composable.

// Conceptual example of Jetpack Compose
@Composable
fun Greeting(name: String) {
    Text(text = "Hello $name!")
}

For an iOS developer, Jetpack Compose feels incredibly familiar. It’s as if someone took the philosophy of SwiftUI and translated it into Google’s dialect.


Similarities: Separated at Birth

If you put SwiftUI and Jetpack Compose code side by side, it is sometimes hard to tell them apart if you squint. Both share the DNA of reactive programming.

1. Declarative and Nested Syntax

Both frameworks use a “tree” syntax where containers wrap contents.

  • In SwiftUI we use VStackHStackZStack.
  • In Compose they use ColumnRowBox.

2. State Management

The concept is identical: the UI is a function of the state. When the state changes, the UI regenerates (recomposition).

  • SwiftUI: @State var count = 0
  • Compose: val count = remember { mutableStateOf(0) }

3. Modifiers

Both use the pattern of decorating views to change their appearance.

  • SwiftUI: .padding().background(Color.red)
  • Compose: Modifier.padding(16.dp).background(Color.Red)

4. Real-time Preview

Xcode has the Canvas (Preview). Android Studio has Compose Preview. Both allow you to see changes in real-time without compiling the entire app, although the technical implementation differs (Xcode often builds the real code in the background, while Android Studio renders isolated previews).


Key Differences: Structs vs. Functions

Here is where we must pay technical attention. Although they look alike, the “magic” under the hood is very different.

1. The Atomic Unit: Struct vs. Function

For an iOS developer, this is the most shocking part.

  • SwiftUI (Structs): We use structs that conform to the View protocol. Swift is very good at managing value structures. When a view changes, the old structure is discarded and a new one is created. It is very cheap in memory.
struct MyView: View {
    var body: some View { ... }
}

Compose (Functions): Uses functions. There are no classes or structs wrapping the UI. The Kotlin compiler does a very aggressive job called “Positional Memoization.” It injects code to know if the function parameters have changed. If they haven’t changed, it skips the execution of the function (recomposition skipping).

@Composable
fun MyView() { ... }

2. The Modifier System

In SwiftUI, modifiers wrap the view. When you do .padding(), you are actually creating a new view (ModifiedContent) that contains the original one. Order matters a lot and is part of the Swift type system.

In Compose, modifiers are arguments. Almost all visual elements accept a modifier parameter.

// Compose
Text(
    text = "Hello",
    modifier = Modifier.padding(10.dp).clickable { ... }
)

This avoids the “pyramid of doom” nesting, but sometimes makes the code less linearly readable than in SwiftUI.

3. Navigation

Here SwiftUI wins in integration (although it has been a painful road with NavigationView and now NavigationStack). Navigation is part of the view hierarchy.

In Compose, navigation historically did not have its own visual UI; it was handled through a navigation controller that swapped “screens” (composables) based on text routes (Strings), very similar to how the web works. Although type-safe libraries now exist, it feels less “native” than Apple’s NavigationLink.


The Rosetta Stone: Code Translation

The best way for an iOS developer to learn is to see the direct translation. Let’s create a simple counter.

In SwiftUI (iOS)

import SwiftUI

struct CounterView: View {
    // 1. State Definition
    @State private var count = 0

    var body: some View {
        // 2. Vertical Container
        VStack(spacing: 20) {
            Text("Counter: \(count)")
                .font(.largeTitle)
                .foregroundColor(.blue)

            // 3. Action
            Button(action: {
                count += 1
            }) {
                Text("Increment")
                    .padding()
                    .background(Color.green)
                    .foregroundColor(.white)
                    .cornerRadius(8)
            }
        }
    }
}

In Jetpack Compose (Android)

import androidx.compose.runtime.*
import androidx.compose.material3.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

@Composable
fun CounterView() {
    // 1. State Definition (remember keeps the value between recompositions)
    var count by remember { mutableStateOf(0) }

    // 2. Vertical Container (Column = VStack)
    Column(
        verticalArrangement = Arrangement.spacedBy(20.dp)
    ) {
        Text(
            text = "Counter: $count",
            // Styles are passed as parameters, not modifiers
            style = MaterialTheme.typography.headlineLarge, 
            color = Color.Blue
        )

        // 3. Action
        Button(
            onClick = { count++ },
            colors = ButtonDefaults.buttonColors(containerColor = Color.Green)
        ) {
            Text("Increment", color = Color.White)
        }
    }
}

Observations:

  • VStack is Column.
  • HStack is Row.
  • @State is remember { mutableStateOf(...) }.
  • Style modifiers in Compose are sometimes constructor parameters (stylecolor) and other times part of the Modifierobject. In SwiftUI, they are almost always chained modifiers (.font.foregroundColor).

Why Should an iOS Developer Learn This?

You might wonder: “If I love Swift and the Apple ecosystem, why do I want to know about Android?”

The answer has three letters: KMP (Kotlin Multiplatform).

Unlike Flutter or React Native, which force you to abandon your native ecosystem and use an external rendering engine, the industry is moving towards sharing business logic and keeping the UI native.

But there is an interesting twist: Compose Multiplatform. Jetbrains (creators of Kotlin) has brought Jetpack Compose to work on iOS. It draws the UI on the iOS canvas mimicking native components.

However, the most purist and performant trend remains:

  1. Shared logic in Kotlin.
  2. Android UI in Jetpack Compose.
  3. iOS UI in SwiftUI.

If you understand both frameworks, you become the “Unicorn” of mobile development: an engineer capable of working on shared logic and refining the interface on both native platforms with ease, since the paradigms are identical.


Quick Comparison Table for iOS Devs

ConceptSwiftUI (iOS)Jetpack Compose (Android)
LanguageSwiftKotlin
Base Componentstruct View@Composable fun
Local State@StatemutableStateOf + remember
Shared State@EnvironmentObject / @ObservableCompositionLocal / ViewModel
ListList / LazyVStackLazyColumn
Horizontal LayoutHStackRow
Vertical LayoutVStackColumn
OverlayZStackBox
SpacingSpacer()Spacer(modifier...) or Arrangement
Entry PointApp protocolActivity calling setContent

Conclusion

The mobile framework war has ended in a peaceful truce: We all win. Apple and Google have converged on the same solution for interface design. The declarative interface is here to stay.

For you, as an iOS developer, the learning curve to understand Android has been drastically reduced. You no longer have to understand Fragment lifecycles or XML. If you know SwiftUI, you already know 80% of the theory needed to write Jetpack Compose.

Mastering Swift and SwiftUI remains your priority, but taking a look at the other side of the fence has never been easier or more profitable for your professional career.

If you have any questions about this article, please contact me and I will be happy to help you 🙂. You can contact me on my X profile or on my Instagram profile.

Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Article

Best SwiftUI Apps

Next Article

Xcode vs VS Code (Visual Studio Code)

Related Posts