I never liked CoreData. A long time ago I was using Realm because it solved my problem with slow batch insertions and brought reactivity. Nowadays there's SwiftData too, but I'm honestly not a fan of it at all.
I'm in love with the server-side approach of working with SQL, like what I use with Vapor and what I originally built my SwifQL for.
Then I found DuckDB, which kind of shares my love for postgres-style SQL and gives you a looooooot more power to play with on the client side.
SuckDB already has an official Swift client, but it wasn't the application-level API I wanted to use in my apps. So I decided to build my own Swift layer around it.
I'd already doing similar things with Bridges and SwifQL on the server side, so I brought a lot of those ideas with me.
And here's what we have now: a beautiful, very Swiftly way of working with Duck and writing SQL:
``` import Duck
struct Todo: Table { @Column("id") var id: UUID
@Column("name")
var name: String
}let todos = try await Todo.all(on: .app) ```
There are more examples in the repo's readme, together with SwiftUI and UIKit example apps you can immediately play with.
This is the first stable 1.0.0 release and it includes Codable integration, async/await, reactive queries, migrations, transactions, reusable prepared statements, connection pooling, bulk ingestion through DuckDB's Appender, native LIST/STRUCT values, and the SwiftStream/SQL DSL.
Underneath it is the real, fresh DuckDB 2.0.0 engine.
Right now Duck targets iOS15+ and macOS12+. I've also tested it on Linux. The engine itself supports many more platforms, but I haven't validated the Duck on those yet.
I wanted a richer SQL engine with a beautiful Swift DSL, and I got it.
I you also want to try something different on the client side, welcome to the Duck club.
And since this is HN, here's a problem I haven't solved to my satisfaction yet.
If you want to hear about any problems... I haven't found a silver bullet for the server-side migrations approach problem yet, so I kept migrations at the foundation level, and I'm going to experiment with one or more higher-level approaches on to of that. If you've dealt with the same problem, I'd genuinely love to hear how you approached it.