The SwiftUI companion for GRDB

What's New


  • New #49: Make Value an associated type of Queryable.


Latest release: December 1, 2023 • version 0.8.0CHANGELOG

Requirements: iOS 14.0+ / macOS 11+ / tvOS 14.0+ / watchOS 7.0+ • Swift 5.7+ / Xcode 14+

📖 Documentation

This library helps building SwiftUI applications that access "services", such as a local database, through the SwiftUI environment.

Its main purpose is to help users of the GRDB SQLite toolkit. Yet GRDBQuery has no dependency on GRDB: you can use it in other contexts, in a Core Data or Realm application, and generally in any kind of app, as long as you'd like to put the SwiftUI environment to good use.

What's in the Box?

GRDBQuery provides two property wrappers:

  • With @Query, SwiftUI views can automatically update their content when the database changes. Generally speaking, @Query helps subscribing to Combine publishers defined from the SwiftUI environment:

    /// A view that displays an always up-to-date list of players in the database.
    struct PlayerList: View {
        var players: [Player]
        var body: some View {
            List(players) { player in Text( }
  • With @EnvironmentStateObject, applications can build observable objects that find their dependencies in the SwiftUI environment:

    /// A view that displays the list of players provided by its view model
    struct PlayerList: View {
        @EnvironmentStateObject var viewModel: PlayerListViewModel
        init() {
            _viewModel = EnvironmentStateObject { env in
                PlayerListViewModel(database: env.database)
        var body: some View {
            List(viewModel.players) { player in Text( }

    @EnvironmentStateObject is a general-purpose property wrapper, akin to the SwiftUI @Environment, @EnvironmentObject, @ObservedObject, and @StateObject.

    It fits well the view models of the MVVM architecture, as well as dependency injection.

Both property wrappers can work together, so that developers can run quick experiments, build versatile previews, and also apply strict patterns and conventions. Pick @Query, or @EnvironmentStateObject, depending on your needs!

Why GRDBQuery?

GRDBQuery makes sure SwiftUI views are immediately rendered with the content you expect.

For example, when you display a List that animates its changes, you do not want to see an animation for the initial state of the list, or to prevent this undesired animation with extra code.

You also want your SwiftUI previews to display the expected values without having to run them.

Techniques based on onAppear(perform:), onReceive(_:perform) and similar methods suffer from this "double-rendering" problem and its side effects. By contrast, the GRDBQuery property wrappers have you fully covered.


Learn how to use @Query and @EnvironmentStateObject in the Documentation.

Check out the GRDBQuery demo apps, and the GRDB demo apps for various examples.


🙌 @Query was vastly inspired from Core Data and SwiftUI by @davedelong, with a critical improvement contributed by @steipete. Many thanks to both of you! @EnvironmentStateObject was later introduced because @Query does not fit the MVVM architecture. The author sees benefits in both property wrappers.


  • Swift Tools 5.7.0
View More Packages from this Author


Last updated: Fri Jul 19 2024 02:41:24 GMT-0900 (Hawaii-Aleutian Daylight Time)