GitHunt
KA

KayLeung/swift-structured-queries

Truly type-safe SQL.

StructuredQueries

CI
Slack

A library for building SQL in a safe, expressive, and composable manner.

Learn more

This library was motivated and designed over the course of many episodes on
Point-Free, a video series exploring advanced programming topics in the
Swift language, hosted by Brandon Williams and
Stephen Celis. To support the continued development of this
library, subscribe today.

video poster image

Overview

StructuredQueries provides a suite of tools that empower you to write safe, expressive, composable
SQL with Swift. By simply attaching macros to types that represent your database schema:

@Table
struct Reminder {
  let id: Int
  var title = ""
  var isCompleted = false
  var priority: Int?
  var dueDate: Date?
}

You get instant access to a rich set of query building APIs, from simple:

Swift SQL
Reminder.all
// => [Reminder]
SELECT
  "reminders"."id",
  "reminders"."title",
  "reminders"."isCompleted",
  "reminders"."priority",
  "reminders"."dueDate"
FROM "reminders"

To complex:

Swift SQL
Reminder
  .select {
     ($0.priority,
      $0.title.groupConcat())
  }
  .where { !$0.isCompleted }
  .group(by: \.priority)
  .order { $0.priority.desc() }
// => [(Int?, String)]
SELECT
  "reminders"."priority",
  group_concat("reminders"."title")
FROM "reminders"
WHERE (NOT "reminders"."isCompleted")
GROUP BY "reminders"."priority"
ORDER BY "reminders"."priority" DESC

These APIs help you avoid runtime issues caused by typos and type errors, but they still embrace SQL
for what it is. StructuredQueries is not an ORM or a new query language you have to learn: its APIs
are designed to read closely to the SQL it generates, though they are often more succinct, and
always safer.

You are also never constrained by the query builder. You are free to introduce safe SQL strings at
the granularity of your choice using the #sql macro. From small expressions:

Reminder.where {
  !$0.isCompleted && #sql("\($0.dueDate) < date()")
}

To entire statements:

#sql(
  """
  SELECT \(Reminder.columns) FROM \(Reminder.self)
  WHERE \(Reminder.priority) >= \(selectedPriority)
  """,
  as: Reminder.self
)

The library supports building everything from SELECT, INSERT, UPDATE, and DELETE statements,
to type-safe outer joins and recursive common table expressions. To learn more about building SQL
with StructuredQueries, check out the
documentation.

Important

This library does not come with any database drivers for making actual database requests, e.g.,
to SQLite, Postgres, MySQL. This library focuses only on building SQL statements and providing the
tools to integrate with another library that makes the actual database requests. See
Database drivers for more information.

Documentation

The documentation for the latest unstable and stable releases are available here:

There are a number of articles in the documentation that you may find helpful as you become more
comfortable with the library:

As well as more comprehensive example usage:

Demos

There are a number of sample applications that demonstrate how to use StructuredQueries in the
SharingGRDB repo. Check out
this directory to see them all,
including:

  • Case Studies:
    A number of case studies demonstrating the built-in features of the library.

  • Reminders: A rebuild
    of Apple's Reminders app that uses a SQLite database to model the
    reminders, lists and tags. It features many advanced queries, such as searching, and stats
    aggregation.

  • SyncUps: We also
    rebuilt Apple's Scrumdinger demo application using modern, best practices for
    SwiftUI development, including using this library to query and persist state using SQLite.

Database drivers

StructuredQueries is built with the goal of supporting any SQL database (SQLite, MySQL, Postgres,
etc.), but is currently tuned to work with SQLite. It currently has one official driver:

  • SharingGRDB: A lightweight replacement for
    SwiftData and the @Query macro. SharingGRDB includes StructuredQueriesGRDB, a library that
    integrates this one with the popular GRDB SQLite library.

If you are interested in building a StructuredQueries integration for another database library,
please see Integrating with database libraries, and
start a discussion
to let us know of any challenges you encounter.

Installation

You can add StructuredQueries to an Xcode project by adding it to your project as a package.

https://github.com/pointfreeco/swift-structured-queries

If you want to use StructuredQueries in a SwiftPM project,
it's as simple as adding it to your Package.swift:

dependencies: [
  .package(url: "https://github.com/pointfreeco/swift-structured-queries", from: "0.4.0"),
]

And then adding the product to any target that needs access to the library:

.product(name: "StructuredQueries", package: "swift-structured-queries"),

If you are on Swift 6.1 or greater, you can enable package traits that extend the library with
support for other libraries. For example, you can introduce type-safe identifiers to your tables
via Tagged by enabling the
StructuredQueriesTagged trait:

 dependencies: [
   .package(
     url: "https://github.com/pointfreeco/swift-structured-queries",
     from: "0.1.0",
+    traits: [
+      "StructuredQueriesTagged",
+    ]
   ),
 ]

Community

If you want to discuss this library or have a question about how to use it to solve a particular
problem, there are a number of places you can discuss with fellow
Point-Free enthusiasts:

License

This library is released under the MIT license. See LICENSE for details.

Languages

Swift99.9%Makefile0.1%C0.0%
MIT License
Created July 24, 2025
Updated July 24, 2025
KayLeung/swift-structured-queries | GitHunt