Skip to main content
Version: 0.7.0

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

CapabilityWhat it gives you
Type-safe APIquark.For[T] returns a *Query[T] — reads map directly back into model structs.
Immutable buildersQuery methods clone builder state, making shared base queries safe to reuse across goroutines.
SQLGuardIdentifiers, operators, and keywords are validated before SQL generation.
Reflection cacheStruct metadata is analyzed once per model and reused for fast mapping.
Six dialectsPostgreSQL, MySQL, MariaDB, SQLite, MSSQL, and Oracle with dialect-specific DDL, upserts, and pagination.
Full batch suiteCreateBatch, UpsertBatch, UpdateBatch, DeleteBatch — dialect-dispatched and chunked automatically.
Production hooksMiddleware, lifecycle hooks, observers, L2 cache stores, and OpenTelemetry — all built in.
Multi-tenancyTenantRouter 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

SectionContents
InstallationRequirements, drivers, optional packages, env vars
Getting StartedConnect, model, migrate, CRUD
ModelingTags, composite PKs, soft delete, validation
Query BuilderFilters, scopes, joins, aggregates, streaming
Batch OperationsCreateBatch, UpsertBatch, UpdateBatch, DeleteBatch
Relationshas_many, belongs_to, many_to_many, polymorphic
MigrationsMigrate, Sync, AddForeignKey, CreateIndex
TransactionsCallback, manual, savepoints, isolation levels
Operational WorkflowsGo commands for migrations, sync previews, tenant jobs
Multi-TenantRLS, schema, database-per-tenant
Caching & ObservabilityL2 cache, middleware, hooks, OTel
SQLGuardIdentifier validation, injection prevention, AllowRawQueries
ComparisonCell-by-cell vs GORM, sqlx, Ent
ConfigurationLimits, WithDialect, WithCacheStore, WithMiddleware
DialectsDialect table, upsert mapping, custom dialects
ArchitectureRequest lifecycle, SQLGuard, schema evolution
Roadmapv0.1 → v0.2 milestones, long-term goals
Release Notesv0.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.