RepoPilotOpen in app →

sqlc-dev/sqlc

Generate type-safe code from SQL

Healthy

Healthy across the board

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

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 →
  • 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.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/sqlc-dev/sqlc)](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:

  1. 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.
  2. 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.
  3. 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 |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>sqlc-dev/sqlc</code></summary>
#!/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).

</details>

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

  1. Create a new protobuf service definition in buf.work.yaml following the plugin interface contract (buf.work.yaml)
  2. Add the new language generator to buf.gen.yaml with its own module path and invocation rules (buf.gen.yaml)
  3. Create a new plugin repository (e.g., sqlc-gen-rust) that implements the protobuf service interface from buf definitions (docs/guides/plugins.md)
  4. Add CI workflow for the new language in .github/workflows/ to test code generation and compilation (.github/workflows/ci-kotlin.yml)
  5. Add reference documentation in docs/reference/language-support.rst listing the new language and its features (docs/reference/language-support.rst)

Add a new example project for a SQL pattern

  1. Create a new directory under examples/ with subdirectories for each database dialect (postgresql/, mysql/, sqlite/) (examples/authors/sqlc.yaml)
  2. Write a schema.sql file demonstrating the DDL pattern (e.g., joins, CTEs, window functions) (examples/authors/postgresql/schema.sql)
  3. Write query SQL files in each dialect directory showing the pattern in action (examples/authors/postgresql/query.sql)
  4. Create a sqlc.yaml configuration at the example root that generates code for all three dialects (examples/authors/sqlc.yaml)
  5. 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

  1. Add a test case to .github/workflows/ci.yml reproducing the parsing or code generation bug (.github/workflows/ci.yml)
  2. 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)
  3. Add or update integration test files in examples/ to ensure the fix works across all three dialects (examples/authors/postgresql/query.sql)
  4. Update docs/reference/datatypes.md if the fix adds support for new SQL types or annotations (docs/reference/datatypes.md)
  5. Document the fix in docs/reference/changelog.md and regenerate docs with Sphinx (docs/reference/changelog.md)

Update the configuration schema or add a new sqlc.yaml directive

  1. Modify the configuration protobuf definition (referenced in buf.gen.yaml) to add the new field (buf.gen.yaml)
  2. Update the configuration parsing logic in cmd/sqlc (invoked from cmd/sqlc/main.go) (cmd/sqlc/main.go)
  3. Document the new directive with examples in docs/reference/config.md (docs/reference/config.md)
  4. 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
  • sqlc-dev/sqlc-gen-go — Official Go code generator plugin for sqlc; handles Go-specific type mappings and generates db/sql or pgx interfaces
  • sqlc-dev/sqlc-gen-python — Official Python code generator plugin; handles SQLAlchemy ORM and async/await patterns for queries
  • sqlc-dev/sqlc-gen-typescript — Official TypeScript code generator plugin; integrates with node-postgres and generates Promise-based async APIs
  • kyleconroy/tern — SQL schema migration tool companion for sqlc workflows; manages version control of SQL schema changes before code generation
  • jackc/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

📝Recent commits

Click to expand
  • 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.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · sqlc-dev/sqlc — RepoPilot