QUARK ORM
Quark is v0.x — production-grade design with an API that may evolve before v1.0. The core query builder, CRUD operations, and migration engine are considered stable. Breaking changes will be documented in the changelog with a migration path.
QUARK is a modern ORM for Go built around generics, immutable query builders, multi-dialect SQL, and production extension points. It keeps model code close to plain Go structs while still covering migrations, relations, batch operations, transactions, validation, caching, telemetry, and multi-tenancy.
// Query
users, err := quark.For[User](ctx, client).
Where("active", "=", true).
Preload("Posts").
OrderBy("created_at", "DESC").
Limit(20).
List()
// Batch upsert — dialect-specific SQL generated automatically
err = quark.For[Product](ctx, client).UpsertBatch(
feed,
[]string{"sku"},
[]string{"price", "stock"},
)
Why QUARK
| Capability | What it gives you |
|---|---|
| Type-safe API | quark.For[T] returns a *Query[T] — reads map directly back into model structs. |
| Immutable builders | Query methods clone builder state, making shared base queries safe to reuse across goroutines. |
| SQLGuard | Identifiers, operators, and keywords are validated before SQL generation. |
| Reflection cache | Struct metadata is analyzed once per model and reused for fast mapping. |
| Six dialects | PostgreSQL, MySQL, MariaDB, SQLite, MSSQL, and Oracle with dialect-specific DDL, upserts, and pagination. |
| Full batch suite | CreateBatch, UpsertBatch, UpdateBatch, DeleteBatch — dialect-dispatched and chunked automatically. |
| Production hooks | Middleware, lifecycle hooks, observers, L2 cache stores, and OpenTelemetry — all built in. |
| Multi-tenancy | TenantRouter with RLS, schema-per-tenant, and database-per-tenant strategies. |
Why I built this
After running production services on GORM, three patterns kept causing incidents: every db.Find(&result) forced an interface{} cast the compiler couldn't verify; column names in WHERE clauses were plain strings with no guard against typos or injection in dynamic queries; N+1 queries appeared silently whenever a Preload was forgotten, only surfacing in slow-query logs hours later; and multi-tenant isolation meant copy-pasting WHERE tenant_id = ? everywhere, relying on discipline instead of enforcement. Quark is the ORM I wished existed: generics end the casts, SQLGuard validates every identifier at the API boundary, eager loading is explicit, and multi-tenancy is first-class — not an afterthought.
Documentation map
| Section | Contents |
|---|---|
| Installation | Requirements, drivers, optional packages, env vars |
| Getting Started | Connect, model, migrate, CRUD |
| Modeling | Tags, composite PKs, soft delete, validation |
| Query Builder | Filters, scopes, joins, aggregates, streaming |
| Batch Operations | CreateBatch, UpsertBatch, UpdateBatch, DeleteBatch |
| Relations | has_many, belongs_to, many_to_many, polymorphic |
| Migrations | Migrate, Sync, AddForeignKey, CreateIndex |
| Transactions | Callback, manual, savepoints, isolation levels |
| Operational Workflows | Go commands for migrations, sync previews, tenant jobs |
| Multi-Tenant | RLS, schema, database-per-tenant |
| Caching & Observability | L2 cache, middleware, hooks, OTel |
| SQLGuard | Identifier validation, injection prevention, AllowRawQueries |
| Comparison | Cell-by-cell vs GORM, sqlx, Ent |
| Configuration | Limits, WithDialect, WithCacheStore, WithMiddleware |
| Dialects | Dialect table, upsert mapping, custom dialects |
| Architecture | Request lifecycle, SQLGuard, schema evolution |
| Roadmap | v0.1 → v0.2 milestones, long-term goals |
| Release Notes | v0.x changelog |
Install
go get github.com/jcsvwinston/quark
import "github.com/jcsvwinston/quark"
See Installation for driver requirements, optional packages, and test environment variables.