One of the best parts of SwiftUI is how it handles state. But with every new iOS version, Apple refines the tools we use to observe and react to data changes. Today I wanted to go back a little to iOS 17 (yes I know we’re all working hard readying for iOS26).

With iOS 17, we got the new Observation framework. It’s SwiftUI’s next step towards clearer, faster state updates — and if you’ve been juggling ObservableObject, @Published, @StateObject, and the rest, this update might simplify your codebase more than you expect.
In this post, I’ll break down:
- What
Observationis and why it exists. - How it compares to
ObservableObject. - A simple example to get you started.
- Things to watch out for when adopting it.
What is Observation?
Before iOS 17, your go-to for sharing state across views was usually ObservableObject. You’d mark properties with @Published and update your views with @StateObject or @ObservedObject.
But this can get boilerplate-heavy fast — especially when you have nested models.
Observation introduces the @Observable macro. It’s a lightweight, compiler-powered way to auto-synthesize the same behaviour — but with less clutter and (potentially) faster updates because it’s more fine-grained.
ObservableObject vs @Observable
ObservableObject | @Observable |
|---|---|
| Uses Combine under the hood | Pure Swift macro |
Needs @Published for each property | Automatically observes all stored properties |
| Works with all Swift versions SwiftUI supports | iOS 17+ only |
A Simple Example
Let’s say you have a Counter model:
import Observation
@Observable
class Counter {
var count = 0
func increment() {
count += 1
}
}
Notice:
- No
ObservableObjectprotocol. - No
@Publishedoncount.
In your view, you can now do:
struct ContentView: View {
@State private var counter = Counter()
var body: some View {
VStack {
Text("Count: \(counter.count)")
Button("Increment") {
counter.increment()
}
}
}
}
That’s it. SwiftUI tracks count automatically. Any time it changes, your view updates. No extra syntax.
A Note on Reference vs Value
@Observable works with both class and struct. But when you use it with a struct, SwiftUI will track its properties too — just be mindful how you store and pass it around.
Should You Migrate Now?
If you’re targeting iOS 17 and above, I’d definitely recommend experimenting with @Observable for new features. It trims down your state code and plays nicely with Swift’s macro system.
But for existing projects with wide deployment targets, ObservableObject and @Published still do the job & work fine with no signs of deprecation — they are also better for backward compatibility.
Final Thoughts
SwiftUI is evolving fast. Observation is part of Apple’s push to make reactive code easier for everyone — and reduce the magic under the hood.
Try it out in a small module first. If you like how clean it feels, maybe it’s time to sprinkle it across your next big update.

Have you tried @Observable yet?
If you have, I’d love to hear how it went — drop me a comment or share your experiments. Happy coding!
