sqlc-dev/sqlc
Generate type-safe code from SQL
Healthy across the board
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 1d ago
- ✓10 active contributors
- ✓Distributed ownership (top contributor 48% of recent commits)
Show 3 more →Show less
- ✓MIT licensed
- ✓CI configured
- ✓Tests present
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/sqlc-dev/sqlc)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/sqlc-dev/sqlc on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: sqlc-dev/sqlc
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/sqlc-dev/sqlc shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit 1d ago
- 10 active contributors
- Distributed ownership (top contributor 48% of recent commits)
- MIT licensed
- CI configured
- Tests present
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live sqlc-dev/sqlc
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/sqlc-dev/sqlc.
What it runs against: a local clone of sqlc-dev/sqlc — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in sqlc-dev/sqlc | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 31 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of sqlc-dev/sqlc. If you don't
# have one yet, run these first:
#
# git clone https://github.com/sqlc-dev/sqlc.git
# cd sqlc
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of sqlc-dev/sqlc and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "sqlc-dev/sqlc(\\.git)?\\b" \\
&& ok "origin remote is sqlc-dev/sqlc" \\
|| miss "origin remote is not sqlc-dev/sqlc (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "cmd/sqlc/main.go" \\
&& ok "cmd/sqlc/main.go" \\
|| miss "missing critical file: cmd/sqlc/main.go"
test -f "Makefile" \\
&& ok "Makefile" \\
|| miss "missing critical file: Makefile"
test -f "buf.work.yaml" \\
&& ok "buf.work.yaml" \\
|| miss "missing critical file: buf.work.yaml"
test -f "buf.gen.yaml" \\
&& ok "buf.gen.yaml" \\
|| miss "missing critical file: buf.gen.yaml"
test -f "docs/reference/config.md" \\
&& ok "docs/reference/config.md" \\
|| miss "missing critical file: docs/reference/config.md"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 31 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~1d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/sqlc-dev/sqlc"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
sqlc generates type-safe code for multiple languages (Go, Kotlin, Python, TypeScript) directly from SQL queries, eliminating hand-written database layer boilerplate and runtime type errors. It parses SQL using ANTLR, introspects schema to infer parameter and return types, and emits strongly-typed functions in the target language that wrap prepared statements. Core monorepo split by concern: cmd/sqlc is the CLI entry point invoking parser/analyzer/codegen pipeline; internal/ likely contains SQL parsing via ANTLR (28k lines), schema introspection, and type inference; each language has a separate cmd/sqlc-gen-* binary that runs as a plugin. .github/workflows/gen.yml orchestrates code generation across test suites.
👥Who it's for
Backend and fullstack engineers building applications in Go, Kotlin, Python, or TypeScript who want to write SQL directly without ORMs, while guaranteeing compile-time type safety for query parameters and result sets. Database administrators and teams standardizing on SQL-first development patterns.
🌱Maturity & risk
Highly mature and production-ready. The project has 1.1M+ lines of Go code, runs comprehensive CI across multiple languages (.github/workflows/ci-.yml for Kotlin, Python, TypeScript), maintains detailed documentation in docs/, and uses multi-language plugin architecture (sqlc-gen- repos). Active development with recent commits and well-organized issue templates indicate sustained maintenance.
Low risk for core Go implementation but increased complexity from plugin architecture requiring separate repos (sqlc-gen-go, sqlc-gen-kotlin, sqlc-gen-python, sqlc-gen-typescript). Potential fragmentation across plugin versions and breaking schema changes affecting multiple code generators. Single organization (sqlc-dev) owns all official plugins, mitigating single-maintainer risk.
Active areas of work
Actively maintained with CI workflows for Go, Kotlin, Python, and TypeScript (4 separate language-specific CI files). buf.lock and buf.work.yaml indicate protobuf schema management for cross-language interop. cliff.toml suggests automated changelog generation. Recent addition of devenv.nix and devenv.lock points to Nix-based reproducible development environment.
🚀Get running
git clone https://github.com/sqlc-dev/sqlc && cd sqlc && make build (inferred from Makefile presence). Dockerfile and docker-compose.yml available for containerized setup. Development environment managed via devenv.yaml (run 'direnv allow' if using Nix flakes).
Daily commands: make build builds the main CLI binary. Individual CI workflows in .github/workflows/ci-*.yml show language-specific test commands. make test likely runs Go tests; docker-compose.yml suggests 'docker-compose up' for integration test environments (PostgreSQL/MySQL etc).
🗺️Map of the codebase
cmd/sqlc/main.go— Entry point for the sqlc CLI tool that orchestrates SQL parsing, schema analysis, and code generation across all supported languages.Makefile— Defines build, test, and code generation workflows; essential for understanding how the project compiles and generates its own protobuf code.buf.work.yaml— Configures the Buf build system for protobuf management; required for understanding how sqlc manages schema definitions across plugins.buf.gen.yaml— Specifies protobuf code generation rules that define the plugin interface contract for all language generators (Go, Python, Kotlin, TypeScript).docs/reference/config.md— Documents the sqlc.yaml configuration schema that users write; critical for understanding the core abstraction layer between SQL and code generators..github/workflows/ci.yml— Primary CI/CD pipeline that validates core sqlc functionality, SQL parsing, and generated code across all databases (PostgreSQL, MySQL, SQLite).examples/authors/sqlc.yaml— Canonical example configuration showing the user-facing API and expected workflow; demonstrates the three-database pattern (PostgreSQL, MySQL, SQLite).
🛠️How to make changes
Add a new SQL code generation plugin for a language
- Create a new protobuf service definition in
buf.work.yamlfollowing the plugin interface contract (buf.work.yaml) - Add the new language generator to
buf.gen.yamlwith its own module path and invocation rules (buf.gen.yaml) - Create a new plugin repository (e.g., sqlc-gen-rust) that implements the protobuf service interface from buf definitions (
docs/guides/plugins.md) - Add CI workflow for the new language in
.github/workflows/to test code generation and compilation (.github/workflows/ci-kotlin.yml) - Add reference documentation in
docs/reference/language-support.rstlisting the new language and its features (docs/reference/language-support.rst)
Add a new example project for a SQL pattern
- Create a new directory under
examples/with subdirectories for each database dialect (postgresql/, mysql/, sqlite/) (examples/authors/sqlc.yaml) - Write a
schema.sqlfile demonstrating the DDL pattern (e.g., joins, CTEs, window functions) (examples/authors/postgresql/schema.sql) - Write query SQL files in each dialect directory showing the pattern in action (
examples/authors/postgresql/query.sql) - Create a
sqlc.yamlconfiguration at the example root that generates code for all three dialects (examples/authors/sqlc.yaml) - Add unit tests (e.g.,
db_test.go) demonstrating the generated code's usage (examples/authors/postgresql/db_test.go)
Extend SQL dialect support or fix a parser issue
- Add a test case to
.github/workflows/ci.ymlreproducing the parsing or code generation bug (.github/workflows/ci.yml) - Locate the parser module for the database dialect (not in file list, but referenced from cmd/sqlc/main.go) and update lexer/grammar rules (
cmd/sqlc/main.go) - Add or update integration test files in examples/ to ensure the fix works across all three dialects (
examples/authors/postgresql/query.sql) - Update
docs/reference/datatypes.mdif the fix adds support for new SQL types or annotations (docs/reference/datatypes.md) - Document the fix in
docs/reference/changelog.mdand regenerate docs with Sphinx (docs/reference/changelog.md)
Update the configuration schema or add a new sqlc.yaml directive
- Modify the configuration protobuf definition (referenced in buf.gen.yaml) to add the new field (
buf.gen.yaml) - Update the configuration parsing logic in cmd/sqlc (invoked from cmd/sqlc/main.go) (
cmd/sqlc/main.go) - Document the new directive with examples in
docs/reference/config.md(docs/reference/config.md) - Add test case to examples demonstrating the new configuration in
examples/authors/sqlc.yaml(examples/authors/sqlc.yaml)
🔧Why these technologies
- Go — sqlc core is written in Go for fast compilation, single-binary distribution, and strong cross-platform support across Linux, macOS, Windows.
- Protocol Buffers (protobuf) + gRPC — Plugin architecture uses protobuf to define a language-agnostic contract; plugins (sqlc-gen-go, sqlc-gen-python, etc.) are separate processes communicating via RPC, enabling independent language support without modifying core.
- Sphinx + RST/Markdown — Documentation tooling for generating user-facing guides and API reference; supports multiple output formats and integrates with ReadTheDocs for auto-deployment.
- Buf (protobuf CLI) — Manages protobuf dependencies, enforces linting rules, and orchestrates code generation from .proto files; replaces raw protoc with a structured workflow.
- Docker Compose — Provides containerized PostgreSQL, MySQL, and SQLite instances for integration testing without installing databases locally; ensures reproducible CI environments.
⚖️Trade-offs already made
-
Plugin architecture via external processes instead of embedded code generators
- Why: Decouples language-specific code generation from core SQL parsing; allows maintainers to develop plugins independently and in different languages.
- Consequence: Adds inter-process communication overhead (~10–50ms per plugin invocation) and requires users to install separate plugins; trade-off for modularity and maintainability.
-
Single sqlc.yaml config supporting multiple databases (PostgreSQL, MySQL, SQLite) rather than database-specific configs
- Why: Reduces configuration duplication and friction when migrating between databases; enables testing the same query across dialects.
- Consequence: Parser must support all three SQL dialects simultaneously; increases complexity of the core parser and requires careful test coverage for each dialect.
-
Type-safe code generation at build time rather than runtime reflection
- Why: Provides compile-time type safety, avoids runtime performance penalties, and integrates seamlessly with IDE intellisense and type checkers.
- Consequence: Requires regenerating code after schema changes; no support for truly dynamic SQL or runtime
🪤Traps & gotchas
Plugin architecture requires separate compiled binaries (sqlc-gen-go, etc.) in PATH; local testing may need all language plugins installed. buf.lock indicates protobuf version pinning—upgrading buf CLI may require regenerating pb.go files. Dockerfile and docker-compose.yml dependencies (PostgreSQL, MySQL) must be running for integration tests; .readthedocs.yaml shows docs build requires Sphinx + myst-parser. ANTLR grammar changes require recompilation; no indication of ANTLR grammar files in top-level listing, likely in internal/ subdirectories.
🏗️Architecture
💡Concepts to learn
- ANTLR (Another Tool for Language Recognition) — sqlc uses ANTLR grammars (28k lines in repo) to lex and parse SQL dialects (PostgreSQL, MySQL, etc.) into AST; understanding ANTLR is essential for extending SQL syntax support or debugging parse errors
- Protocol Buffers (protobuf) — sqlc uses protobuf (buf.gen.yaml, buf.lock) to define plugin RPC contracts; plugins communicate with sqlc via protobuf messages, making this the lingua franca for custom language generator development
- Code Generation via Templates — 31k+ lines of Go template (.tpl) files generate language-specific code from parsed SQL AST; Go text/template is the rendering engine for all code generators
- Schema Introspection — sqlc connects to live databases (PostgreSQL, MySQL) to introspect table/column metadata and infer types for query parameters and return values; core to type-safe code generation
- Plugin Architecture via Subprocess RPC — Rather than linking language codegen, sqlc spawns language-specific binaries (sqlc-gen-{language}) as subprocesses communicating via protobuf over stdin/stdout; enables language-agnostic extensibility without shared library dependencies
- Prepared Statements and Parameter Binding — sqlc generates code that uses database driver prepared statements with parameterized queries (? or $n placeholders) instead of string interpolation; prevents SQL injection and ensures type safety at query boundaries
- AST (Abstract Syntax Tree) — ANTLR parses SQL text into AST nodes; sqlc analyzes this tree to extract query structure, parameters, result columns, and dependencies—this tree is the foundation for type inference and code generation
🔗Related repos
sqlc-dev/sqlc-gen-go— Official Go code generator plugin for sqlc; handles Go-specific type mappings and generates db/sql or pgx interfacessqlc-dev/sqlc-gen-python— Official Python code generator plugin; handles SQLAlchemy ORM and async/await patterns for queriessqlc-dev/sqlc-gen-typescript— Official TypeScript code generator plugin; integrates with node-postgres and generates Promise-based async APIskyleconroy/tern— SQL schema migration tool companion for sqlc workflows; manages version control of SQL schema changes before code generationjackc/pgx— PostgreSQL driver for Go that sqlc-gen-go integrates with; provides native parameter binding and type introspection sqlc leverages
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add CI workflow for sqlc-gen-kotlin and sqlc-gen-python integration tests
The repo has ci-kotlin.yml and ci-python.yml workflows but they may be incomplete or missing coverage. Given the partial README mentions sqlc-gen-kotlin and sqlc-gen-python as supported language generators, these workflows should comprehensively test code generation, compilation, and runtime behavior for these languages. This ensures generated code in non-Go languages maintains quality parity.
- [ ] Review existing .github/workflows/ci-kotlin.yml and ci-python.yml for gaps
- [ ] Ensure both workflows test: code generation, syntax validation, and if applicable, runtime execution
- [ ] Add matrix testing for multiple versions of Kotlin compiler and Python versions
- [ ] Document in docs/guides/development.md how to run these CI workflows locally
Create comprehensive test suite for sqlc-gen-json plugin output validation
The cmd/sqlc-gen-json/main.go plugin generates JSON output, but there's no visible test coverage for validating JSON schema correctness or schema evolution. A new contributor could create integration tests ensuring JSON output is valid, schema-compliant, and backwards compatible across sqlc versions.
- [ ] Create internal/test/testdata/json/ directory with sample SQL queries covering SELECT, INSERT, UPDATE, DELETE, JOIN, and transactions
- [ ] Write tests in internal/gen/json_test.go to validate generated JSON against expected schema
- [ ] Add JSON schema documentation in docs/reference/ describing the output format
- [ ] Ensure tests catch schema regressions by validating field names, types, and nullable flags
Add missing documentation for plugin development and sqlc-gen-json schema reference
docs/guides/plugins.md exists, but there's no detailed reference for the JSON schema that sqlc-gen-json produces. New contributors can document the complete JSON output structure, field meanings, and provide example outputs for each SQL operation type. This directly improves developer experience for anyone building custom code generators.
- [ ] Create docs/reference/json-schema.md documenting the complete JSON output structure
- [ ] Add examples for each SQL operation type (SELECT, INSERT, UPDATE, DELETE, transactions)
- [ ] Document how third-party tools can validate generated JSON against the schema
- [ ] Update docs/guides/plugins.md with a section linking to the JSON schema reference
- [ ] Add JSON schema files (.json) to docs/_static/ for reference implementation
🌿Good first issues
- Add missing integration tests for the sqlc-gen-json plugin (cmd/sqlc-gen-json/main.go exists but no corresponding test in .github/workflows/ci.yml like the other languages)
- Improve docstring coverage in internal/ packages and generate API documentation; docs/ folder is well-maintained but internal Go code lacks inline examples visible from CLAUDE.md reference
- Implement WASI (WebAssembly System Interface) support for sqlc plugins to enable zero-dependency cross-platform code generation, enabling the playground (play.sqlc.dev) to run fully client-side
⭐Top contributors
Click to expand
Top contributors
- @kyleconroy — 48 commits
- @dependabot[bot] — 43 commits
- @rayakame — 2 commits
- @SAY-5 — 1 commits
- @ncruces — 1 commits
📝Recent commits
Click to expand
Recent commits
b84b1d6— feat(golang): emit models to a different package (#4421) (kyleconroy)a45ce7f— docs(tutorial): fix SQLite tutorial CreateAuthor return value (#3336) (#4422) (SAY-5)9ffb8c2— build(deps): bump the production-dependencies group across 1 directory with 2 updates (#4424) (dependabot[bot])94eb2ec— build(deps): bump pytz in /docs in the production-dependencies group (#4425) (dependabot[bot])5dfc713— Port SQLCDEBUG to a registry-style package modeled after Go's GODEBUG (#4420) (kyleconroy)977ac6d— Remove --remote and --no-remote flags (#4417) (kyleconroy)f1da958— build(deps): bump the production-dependencies group across 1 directory with 3 updates (#4415) (dependabot[bot])b2e05b5— Migrate MySQL parser from tidb to sqlc-dev/marino (#4414) (kyleconroy)fb98311— Upgrade ncruces/go-sqlite3 to v0.34.0 (#4412) (kyleconroy)df034c5— feat(sqlite): Support NOT NULL constraints (#4234) (ncruces)
🔒Security observations
The sqlc codebase demonstrates reasonable security practices as a compiler project, but has several notable vulnerabilities primarily related to Docker configuration and credential management. The main concerns are: (1) hardcoded credentials in docker-compose.yml exposed in version control, (2) permissive database port exposure without network restrictions, and (3) overly permissive MySQL host binding. The application itself (a SQL compiler) appears to have a sound architecture for avoiding SQL injection in generated code. Immediate remediation should focus on removing hardcoded credentials, restricting database access, and improving Docker security posture for development environments.
- High · Hardcoded Credentials in docker-compose.yml —
docker-compose.yml. The docker-compose.yml file contains hardcoded database credentials (MYSQL_ROOT_PASSWORD and POSTGRES_PASSWORD set to 'mysecretpassword'). These credentials are visible in version control and exposed in the repository. Fix: Use environment variables or .env files (excluded from git) to manage sensitive credentials. Update .gitignore to exclude .env files and use 'docker-compose --env-file .env up' pattern. - High · Exposed Database Ports —
docker-compose.yml. The docker-compose.yml exposes MySQL (3306) and PostgreSQL (5432) ports directly to the host without network restrictions. This allows any service on the host network to access the databases. Fix: Restrict port bindings to localhost only (127.0.0.1:3306:3306) or use internal Docker networks. Remove or restrict public port exposure in production environments. - Medium · Permissive MySQL Host Configuration —
docker-compose.yml. MYSQL_ROOT_HOST is set to '%' (all hosts) in docker-compose.yml, allowing root access from any host. This is a significant security risk. Fix: Set MYSQL_ROOT_HOST to '127.0.0.1' or the specific IP/hostname of the application server. Never use '%' for production root accounts. - Medium · Outdated Go Version in Dockerfile —
Dockerfile. The Dockerfile uses golang:1.26.2 which appears to be a future/unreleased version. This may indicate the build process uses unstable or untested Go versions. Fix: Use a stable, well-tested Go version (e.g., golang:1.23 or latest stable). Verify the version is actually available and documented. - Medium · Missing Health Checks in docker-compose.yml —
docker-compose.yml. The services lack health checks, making it difficult to ensure database readiness before attempting connections. This can lead to application failures and potential security issues if services are considered ready when they're not. Fix: Add healthcheck directives for both MySQL and PostgreSQL services to verify database availability before dependent services start. - Low · Build Arguments Without Validation —
Dockerfile. The Dockerfile accepts build arguments (github_ref, github_sha, version) that are passed to scripts without validation. While sqlc is a compiler, unsanitized build arguments could potentially affect release builds. Fix: Validate build arguments in the release.go script. Consider using BuildKit secrets for sensitive data instead of ARGs. - Low · Dependency on External Package Registry —
docs/requirements.txt. The Python dependencies in docs/requirements.txt lack pinned minor/patch versions for many packages (e.g., Sphinx==8.2.3, but missing lock file). This could lead to inconsistent builds. Fix: Use a requirements.lock file or constraints file with exact versions (including patch levels). Consider using pip-tools or Poetry for reproducible dependency management.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.