SwiftUI.cc
Compare
CompareIntermediate

SwiftUI ObservableObject vs @Observable: When to Use Each

Choose between ObservableObject and @Observable based on complexity and iOS version requirements.

6 min readUpdated 2026-06

Quick Summary

Dimension ObservableObject @Observable
Performance Similar Slightly better (less boilerplate)
Use case Complex state management Simple, lightweight models
iOS minimum iOS 13+ iOS 17+
Complexity Higher (requires object binding) Lower (macro simplifies code)
Flexibility High Moderate

ObservableObject — When to Use

ObservableObject has been the go-to protocol for managing state in SwiftUI since its introduction. It works by publishing changes using @Published properties, which trigger view updates when values change.

Use ObservableObject when:

  • You need compatibility with iOS versions prior to iOS 17
  • Your app has complex state logic or dependencies between properties
  • You're using Combine or need fine-grained control over object lifecycle
// Using ObservableObject
class UserSettings: ObservableObject {
    @Published var username = "Guest"
}

struct ProfileView: View {
    @StateObject var settings = UserSettings()

    var body: some View {
        TextField("Username", text: $settings.username)
    }
}

@Observable — When to Use

The new @Observable macro, introduced in Swift 5.9 and iOS 17, simplifies state management by reducing boilerplate and offering a more declarative syntax. It leverages Swift's new observation framework and automatically tracks changes to properties.

Use @Observable when:

  • You're targeting iOS 17 and later
  • Your model is simple and doesn't require Combine publishers
  • You want cleaner code with less ceremony
// Using @Observable
@Observable
class UserSettings {
    var username = "Guest"
}

struct ProfileView: View {
    @State var settings = UserSettings()

    var body: some View {
        TextField("Username", text: $settings.username)
    }
}

Side-by-Side Example

Here's the same username editing feature implemented with both approaches:

// Using ObservableObject
class UserSettings: ObservableObject {
    @Published var username = "Guest"
}

struct ProfileView: View {
    @StateObject var settings = UserSettings()

    var body: some View {
        TextField("Username", text: $settings.username)
    }
}
// Using @Observable
@Observable
class UserSettings {
    var username = "Guest"
}

struct ProfileView: View {
    @State var settings = UserSettings()

    var body: some View {
        TextField("Username", text: $settings.username)
    }
}

Both implementations achieve the same result, but @Observable removes the need for @Published and allows more flexible state ownership via @State, @Binding, or @ObservedObject.

Decision Guide

Use ObservableObject when you need to support iOS versions before iOS 17 or require Combine integration. Use @Observable for new iOS 17+ apps where code simplicity and reduced boilerplate are priorities.