sqlc-dev/sqlc: it calls itself a compiler, and seven of its dependencies are its own modules
Generate type-safe code from SQL
At a glance
- What is it?
- sqlc is a generator that turns SQL you wrote into typed code you call, and it is careful about what it is: the title says compiler, the overview says three steps, and the four language targets are four separate repositories. The dependency manifest is where the project's real shape shows, including a WebAssembly build of SQLite, a Postgres driver, and a declared language floor that is older than the image that builds releases.
- Who is it for?
- Use sqlc if your team writes SQL by hand and wants typed bindings for it without adopting an object mapper, because that is the whole claim and the three step workflow shows it. Do not reach for it expecting a query builder or a schema migration tool, since the SQL stays yours and the repository says nothing else about either.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.
Star history
- sqlc-dev/sqlc18,457 ★ · +147
| Repository | 2026-09-21 | 2026-11-14 |
|---|---|---|
| sqlc-dev/sqlc | 18.3k | 18.5k |
147 Stars in the last 54 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
The generated code is an interface you call, not a layer you query through
The title of the project is the positioning: a SQL compiler. Then there are three numbered steps, and the whole design is in them.
You write queries in SQL. You run sqlc to generate code with type-safe interfaces to those queries. You write application code that calls the generated code.
The middle sentence is the one that matters. The output is an interface layer over queries you already wrote, so the generated function names, parameters and result types are derived from your SQL and your schema rather than from a mapping convention you did not choose.
That is what separates this from an object mapper. There is no session, no unit of work, and no query language; the SQL is the query, and the compiler's job is to notice that a column can be null and make the generated type say so. The README points at an interactive playground to see it, and at a blog post for the motivation, which is the right way to evaluate a tool whose entire value is a boundary it draws for you.
For your own code the consequence is that the generated layer is a dependency of your application and a build step of your repository, and neither is optional once you start calling it.
The four target languages are four other repositories
The supported languages list has four entries and each one is a link to a separate repository with its own name: a Go generator, a Kotlin generator, a Python generator and a TypeScript generator.
So the core tool is language agnostic, and the part you actually import is maintained elsewhere. That is a deliberate design rather than an accident, and the README says so in the next sentence: additional languages can be added via plugins, with a link to the documentation section on community language support.
The practical consequence is versioning. Upgrading sqlc and upgrading your target language plugin are two decisions with two release cadences, and a generated file can change shape when either moves. Anyone pinning this in a build needs to pin both, and a team that assumed the tool and the binding shipped together will find out otherwise at a dependency bump.
The README's overview list has an installation page, a downloads site and a playground rather than a getting started command, so the discovery path is the documentation and the online example.
Seven direct dependencies are the project's own modules
The module manifest is worth reading as an inventory, and one group stands out immediately. Seven direct requirements are modules published under the project's own organisation, most on a version below one and each with a short codename: darkwing, doubleclick, marino, meyer, oliphant, teesql and zetajones.
That is a large fraction of sqlc's direct dependency list spent on sqlc's own surface area, consumed as external modules with their own version numbers. For a single binary that is an unusual shape, and it means the tool's behaviour is spread across at least eight versioned artefacts rather than living in one tree.
The rest of the direct list explains what the tool does. There is a Postgres driver (pgx v5), a MySQL driver, a SQLite driver that is a WebAssembly build, an expression language library, a command line framework with its flag package, a struct tag parser, a comparison library, a WebAssembly runtime, a JSON schema validator, a Markdown parser, a YAML parser, a gRPC stack and a protobuf runtime.
So the dependencies are the honest description of a SQL analyser: several database wire protocols, at least two SQL dialects, an expression evaluator, and a schema validator.
The declared language version and the release build image are not the same
The module manifest declares a language version and a separate toolchain line, and the numbers are specific: the language floor is a recent major release and the toolchain line pins a patch of it.
The Dockerfile uses a different number again. Its build stage is a Go image at a version one higher than the toolchain line in the manifest, and the manifest is what downstream consumers inherit as the minimum.
That gap is normal and it is the kind of thing that is only visible in two files. The consequence for a contributor is that the toolchain that produces a release is newer than the one a consumer is required to have, so a build that fails locally on the declared floor may pass in continuous integration, and a bug reproduced on the declared floor is a real support case rather than an unsupported configuration.
Two other things in the same Dockerfile are worth a line each. The version is stamped at build time by running a release script with three pieces of git metadata passed in as build arguments and then exposed as environment variables, so the binary knows which commit it came from. And the runtime stage is a distroless base image into which exactly one file is copied, which is why there is no shell in the final image and why anything the tool needs at run time has to be inside that one binary.
SQLite arrives as WebAssembly, and Postgres is represented twice
The database drivers in the manifest are the clearest window into how the tool analyses a schema, and two of the entries are informative.
The SQLite driver is a WebAssembly build, and the WebAssembly runtime is a separate direct dependency. That pairing is the standard way to use a SQLite engine from a compiled language without a C toolchain, and for a code generator it means the tool can read a SQLite file on a machine with no build tools installed at all.
Postgres appears through pgx v5.
There is also a MySQL driver and an expression language library.
The aggregate effect is that sqlc is a static analyser with several wire protocol implementations rather than a thin wrapper around one driver, which is why the compose file for its own test matrix runs five different database servers.
The test matrix stands up four database engines, one on the host network
The compose file at the repository root exists to run the tests, and it starts five servers rather than one.
A MySQL image on a specific recent version with a database, a root password and a root host pattern that accepts any host. A Postgres 16 image on the default port with a password. A ClickHouse server image on ports 8123 and 9000 with a password. A Microsoft SQL Server image, on its latest tag, with an end user licence acceptance flag and a system administrator password. And a downloadable Spanner distribution.
The Spanner entry is the one with a comment, and the comment is about the network: it serves plaintext gRPC on one port and its console on another, and its quickstart expects to run on the host network. The service is configured with host networking rather than a bridge for that reason.
Host networking is the part that will not work identically everywhere, since it is a Docker runtime feature with different behaviour and different requirements on the two desktop operating systems. So the cost of running the full test matrix locally is five database engines and one networking mode, and the cost of not doing it is that your dialect is not covered by the tests you just changed.
Two protobuf generation paths coexist, and a test reads the module file
The build file has more surface than a code generator needs, and three entries are worth reading together.
There is a target that generates protobuf code through a buffer configuration, and there is a second target that invokes the protobuf compiler directly with a long list of options. Both exist. Two generation paths for one interface is a place where the committed output and the tool's expectation can drift apart silently.
At the repository root there is a test whose name says it reads the module file. That is a test on the project's own dependency declarations, which is the sort of thing that catches an unpinned or malformed requirement before a release rather than after.
There is also a placeholder file at the root, a changelog generator configuration at the root, a Nix development environment with its own lock and manifest, an editor instruction file, and a second command in the project with its own test target that is not the main binary. So the repository is a compiler, a development environment, a protobuf source of truth, and a set of internal tools, and the build file is the index to all of it.
Editorial conclusion
Use sqlc if your team writes SQL by hand and wants typed bindings for it without adopting an object mapper, because that is the whole claim and the three step workflow shows it. Do not reach for it expecting a query builder or a schema migration tool, since the SQL stays yours and the repository says nothing else about either. Check four things before you adopt it: which target language plugin you take, because each of the four lives in its own repository and versions separately from the tool; which SQL dialects you need tested, because the compose file for the test matrix stands up five engines and one of them needs host networking; which toolchain you build with, because the manifest's declared language version and the release image's version are not the same; and how much of the project you inherit as external modules, because seven of its direct dependencies are its own. The license is MIT, the newest release is v1.31.1 dated 2026-04-22, and the last push was 2026-11-02.
Frequently asked questions
What does sqlc do?
It generates type-safe code from SQL. The project describes itself as a SQL compiler and gives three steps: you write queries in SQL, you run sqlc to generate code with type-safe interfaces to those queries, and you write application code that calls the generated code. There is an interactive playground where you can see the loop, and plugins for four target languages.
How do I install sqlc?
The README contains no install command. It links an installation page in the documentation, a downloads site, and a playground, and the workflow it describes is to write your queries and then run the tool to generate code. The tool is a single binary, and the container build copies exactly one file into a distroless base image.
Is sqlc an ORM?
The README never uses that word. It calls the project a SQL compiler that generates code with type-safe interfaces to queries you wrote, and the third step is writing application code that calls that generated code. There is no session, no unit of work and no query language in the described workflow, and the SQL itself is written by you.
What are 15 common SQL commands?
The repository is not a command reference. It is a generator that reads the queries you have already written plus a schema, and its own test matrix stands up MySQL, Postgres, ClickHouse, Microsoft SQL Server and a downloadable Spanner.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/sqlc-dev-sqlc)Star history chart for your README
[](https://hysenlabs.com/projects/sqlc-dev-sqlc)Was this useful?