Jeffrey Hicks

Jeffrey Hicks

Platform Eng @R360

SwiftUI State Management for Jotai Lovers

A comprehensive guide to SwiftUI state management patterns for developers familiar with React and Jotai's atomic state approach

By Jeffrey Hicks • Aug 20, 2025 • compiled-notes

Since you’re already familiar with Jotai’s atomic approach to state management, you’ll find SwiftUI’s state system both familiar and refreshingly simpler in some ways. Let me break this down using concepts you already know and love.

The Mental Model Shift

Jotai’s Philosophy: Bottom-up atomic state management where you compose small, focused atoms into larger state graphs.

SwiftUI’s Philosophy: Similar atomic approach, but with built-in framework support instead of requiring a library. SwiftUI essentially is what React + Jotai aims to be.

Core State Primitives: Jotai vs SwiftUI

Local Atomic State

Jotai:

const countAtom = atom(0)
const [count, setCount] = useAtom(countAtom)

SwiftUI:

@State private var count = 0
// Use: count, modify: count += 1

The key difference: SwiftUI’s @State is more like useState but with the convenience of Jotai’s automatic dependency tracking. No need for separate getter/setter destructuring.

Derived State (Your Jotai Sweet Spot)

Jotai:

const doubledAtom = atom((get) => get(countAtom) * 2)

SwiftUI (Multiple Approaches):

// Computed property (most Jotai-like)
private var doubled: Int { count * 2 }

// Or as @State with willSet/didSet observers
@State private var count = 0 {
    didSet { doubled = count * 2 }
}
@State private var doubled = 0

Computed properties in SwiftUI are essentially derived atoms that recalculate automatically when their dependencies change.

Global Atomic State

This is where SwiftUI gets interesting for Jotai fans. You have three main patterns:

1. Environment (Like React Context, but Better)

React Context + Jotai:

const ThemeContext = createContext()
const themeAtom = atom('light')

SwiftUI Environment:

// Define the key
struct ThemeKey: EnvironmentKey {
    static let defaultValue = "light"
}

// Usage in views
@Environment(\.theme) private var theme

SwiftUI’s Environment is like React Context but with automatic dependency tracking - only views that actually use the environment value re-render.

2. Observable Objects (Like Zustand Stores)

Zustand Store:

const useStore = create((set) => ({
  user: null,
  setUser: (user) => set({ user })
}))

SwiftUI Observable:

@Observable
class UserStore {
    var user: User?
    
    func setUser(_ user: User) {
        self.user = user
    }
}

// In views
@State private var userStore = UserStore()

The @Observable macro (iOS 17+) gives you Jotai-like granular reactivity - only views using specific properties re-render when those properties change.

3. Atoms Library (Literal Jotai Port)

There’s actually a SwiftUI library called “Atoms” that’s directly inspired by Jotai:

let textAtom = Atom("")
let extractedNumbersAtom = DerivedAtom {
    @UseAtomValue(textAtom) var text
    return text.filter { $0.isNumber }
}

struct ContentView: View {
    @UseAtom(textAtom) var text
    @UseAtomValue(extractedNumbersAtom) var numbers
    
    var body: some View {
        TextField("", text: $text)
        Text("Numbers: \(numbers)")
    }
}

This is literally Jotai syntax in Swift.

The Property Wrapper System (Your New Best Friends)

SwiftUI uses property wrappers instead of hooks, but they map directly to concepts you know:

Ownership Patterns

  • @State = Local atom ownership (like atom() + useAtom())
  • @StateObject = Create and own an observable object (like create() in Zustand)
  • @ObservedObject = Subscribe to external observable (like useAtom() on passed atoms)
  • @EnvironmentObject = Global subscription (like context + atoms)

The critical insight: @StateObject vs @ObservedObject is about ownership, just like in Jotai where you decide whether to create an atom locally or consume one from elsewhere.

Two-Way Bindings (Better Than React)

This is where SwiftUI shines compared to React/Jotai. Instead of:

// Jotai
const [text, setText] = useAtom(textAtom)
<input value={text} onChange={(e) => setText(e.target.value)} />

SwiftUI gives you:

@State private var text = ""
TextField("", text: $text)  // Automatic two-way binding with $

The $ syntax creates a binding - think of it as automatically wiring up both the getter and setter.

Performance: Better Than React + Jotai

SwiftUI’s reactivity is more efficient than React because:

  1. No Virtual DOM: Direct updates to native views
  2. Granular Dependencies: Like Jotai’s atom dependencies, but built into the framework
  3. No Reconciliation: SwiftUI knows exactly what changed

The @Observable macro especially gives you Jotai-like granular updates - if you change user.name, only views accessing .name re-render, not the entire user object.

Migration Strategy for Jotai Lovers

  1. Start with @State and computed properties - These feel most like local atoms
  2. Use @Observable classes for complex state - Similar to derived atoms with multiple dependencies
  3. Leverage Environment for global state - Better than Context + atoms
  4. Consider the Atoms library if you want literal Jotai syntax

The Bottom Line

SwiftUI essentially gives you what React + Jotai + perfect optimization would look like if it were built into the platform. You get:

  • ✅ Atomic state management (built-in)
  • ✅ Automatic dependency tracking (built-in)
  • ✅ Granular re-renders (built-in)
  • ✅ Simple local state (@State)
  • ✅ Derived state (computed properties)
  • ✅ Global state (Environment/Observable)
  • ✅ Two-way bindings (automatic)

The learning curve is gentle because the mental models are nearly identical - you’re just getting a more integrated, performant version of what you already love about Jotai.

References

  1. Jotai - Comparison with other libraries
    https://jotai.org/docs/basics/comparison

  2. Jotai Under the Hood: Simple Magic by a Simple Solution
    https://javascript.plainenglish.io/jotai-under-the-hood-simple-magic-by-a-simple-solution-54ba5b58da9c

  3. SwiftUI Against React
    https://www.mux.com/blog/swiftui-against-react

  4. SwiftUI as a React Developer
    https://blog.maximeheckel.com/posts/swiftui-as-react-developer/

  5. Exploring SwiftUI 2: React comparison
    https://blog.scottlogic.com/2020/01/06/Exploring-SwiftUI-2-React-comparison.html

  6. Swift UI @State Property Wrapper vs React useState
    https://www.christopherbiscardi.com/swift-ui-state-property-wrapper-vs-react-use-state

  7. Avoiding SwiftUI value recomputation
    https://www.swiftbysundell.com/articles/avoiding-swiftui-value-recomputation

  8. Swift Computed Property
    https://mimo.org/glossary/swift/computed-property

  9. SwiftUI: ObservableObject
    https://nalexn.github.io/swiftui-observableobject/

  10. What are best practices to manage the global state?
    https://www.reddit.com/r/swift/comments/psocob/what_are_best_practices_to_manage_the_global_state/

  11. Observable in SwiftUI (YouTube)
    https://www.youtube.com/watch?v=cMkmwUne9Xk

  12. SwiftUI Observable Macro (YouTube)
    https://www.youtube.com/watch?v=hLkTMJ_SFzY

  13. Atoms: new state management library for SwiftUI
    https://www.reddit.com/r/SwiftUI/comments/13251sh/atoms_new_state_management_library_for_swiftui/

  14. Announcing Atoms: A new state management library
    https://forums.swift.org/t/announcing-atoms-a-new-state-management-library/64702

  15. Swift Atoms GitHub
    https://github.com/bangerang/swift-atoms

  16. @StateObject and @ObservedObject
    https://fatbobman.com/en/posts/stateobject_and_observedobject/

  17. @StateObject vs @ObservedObject in SwiftUI
    https://blog.rampatra.com/stateobject-vs-observedobject-in-swiftui

  18. @StateObject vs @ObservedObject differences
    https://www.avanderlee.com/swiftui/stateobject-observedobject-differences/

  19. SwiftUI vs React Comparison
    https://www.jetpackcompose.app/compare-declarative-frameworks/SwiftUI-vs-React

  20. React Native vs SwiftUI choice discussion
    https://www.reddit.com/r/reactnative/comments/1l47gyi/if_you_are_struggling_to_choose_between_react/

  21. SwiftUI vs React: Comprehensive Comparison
    https://zthh.dev/blogs/swiftui-vs-react-comprehensive-comparison

  22. Should I use Binding or State in SwiftUI?
    https://www.reddit.com/r/SwiftUI/comments/1etjxha/should_i_use_binding_or_state_in_swiftui/

  23. SwiftJotai GitHub
    https://github.com/unixzii/SwiftJotai

  24. SwiftUI Craftsmanship: State Management
    https://captainswiftui.substack.com/p/swiftui-craftsmanship-state-management

  25. React useState vs useState discussion
    https://www.reddit.com/r/reactjs/comments/mbav64/reactusestate_vs_usestate_which_and_why/

  26. Jotai Async Utilities
    https://jotai.org/docs/utilities/async

  27. State Management in React with Jotai
    https://blogs.perficient.com/2025/07/07/state-management-in-react-with-jotai/

  28. Jotai vs Zustand for UI state management
    https://www.reddit.com/r/reactjs/comments/1813cxs/jotai_vs_zustand_for_ui_state_management_when/

  29. SwiftUI vs Flutter vs React Comparison
    https://www.jetpackcompose.app/compare-declarative-frameworks/SwiftUI-vs-Flutter-vs-React

  30. SwiftUI for React Devs GitHub
    https://github.com/unixzii/swiftui-for-react-devs

  31. SwiftUI State Management (YouTube)
    https://www.youtube.com/watch?v=wPTVfBrTW3c

  32. 7 Top React State Management Libraries
    https://trio.dev/7-top-react-state-management-libraries/

  33. AtomObjects GitHub
    https://github.com/CozmoNate/AtomObjects

  34. SwiftUI Atom Properties
    https://swiftpackageindex.com/ra1028/swiftui-atom-properties

  35. SwiftUI State Patterns
    https://pauballada.com/swiftui/architecture/2024/06/11/swiftui-state-patterns.html

  36. Computed Properties as Synthesized Bindings
    https://swiftui.diegolavalle.com/posts/computed-properties-as-synthesized-bindings/

  37. A Practical Guide to Computed Variables in Swift
    https://www.dhiwise.com/post/a-practical-guide-to-computed-variables-in-swift-cod