Sqlc: Compile SQL to type-safe code
Sqlc, a tool that compiles handwritten SQL into type-safe code, is praised for letting developers work directly in SQL while still getting static checks and strongly typed results in languages like Go and Rust. Commenters weigh it against ORMs and query builders such as go-jet, jOOQ, SQLx, and Kysely, arguing over tradeoffs between code generation, dynamic query composition, and reliance on database-specific drivers or dialects. The broader theme is how best to leverage modern relational databases—especially PostgreSQL—without leaky abstractions, balancing raw SQL, type safety, ergonomics, and maintainability across evolving schemas and environments.
Sqlc approach and perceived benefits
- Generates type-safe code from plain SQL, avoiding ORM/query-builder DSLs.
- Users like keeping SQL in
.sqlfiles and getting checked, compiled interfaces in Go and other languages. - Appreciated for small and medium projects where developers are comfortable writing SQL directly.
- Some teams report successful migrations from ORMs (e.g., GORM) and prefer sqlc’s simpler, explicit abstractions.
Limitations and pain points
- A recurring complaint is lack of first-class support for dynamic queries; workarounds (e.g., CASE-based conditions) are seen as clumsy.
- Some say sqlc is “great until it breaks,” citing loss of context in joins and allowing invalid columns.
- One commenter argues it works only for “basic stuff,” failing on more complex use cases; others dispute this, saying complex queries are fine if not overused.
Dynamic queries vs static SQL
- Sqlc’s design principle is static queries in application code so it’s always clear what hits the database.
- Critics counter that composition of query fragments is a major reason to use builders, and that if queries must be static, stored procedures might be simpler.
Comparisons with other libraries and ecosystems
- Go: go-jet, sqlboiler, XO, GORM mentioned. Jet is praised as a jOOQ-like builder with good type safety and debugging, but lacks some DB features and reverse-SQL translation.
- Rust: SQLx and Cornucopia compared; some feel sqlc adds little beyond SQLx-style macros.
- JVM: jOOQ repeatedly cited as a gold standard for type-safe SQL.
- Kotlin/Android: SQLDelight seen as a close analogue.
- TypeScript/JS: Kysely, Slonik, and Prisma’s TypedSQL highlighted for type-safe SQL without heavy codegen.
Schema evolution, migrations, and rollbacks
- Discussion on how codegen interacts with schema changes: some avoid destructive rollbacks entirely.
- Others enforce migrations that are always backward compatible with at least the previous app version and deploy migrations before service updates.
- Use of separate DBs per environment and ephemeral DBs for tests is recommended.
Broader views on SQL, ORMs, and DB-centric design
- Many dislike ORMs and query builders as unnecessary abstractions that are leaky and hard to learn.
- Several advocate treating the RDBMS (especially Postgres) as the core of the app, using advanced SQL features, with the backend as a thin layer.
- There is frustration about SQL dialect fragmentation and the difficulty of local testing for nonstandard or cloud-specific SQL engines.