Open-source project
go-jet/jet avatar
go-jet/jet

go-jet/jet: a type-safe SQL builder for Go with generated models

Type safe SQL builder with code generation and automatic query result data mapping

3,809 stars194 forksGoApache-2.0

At a glance

What is it?
Jet generates Go table and view types from a live database schema, then lets you build SELECT, INSERT, UPDATE and DELETE statements against those types. It is a query builder with a mapper, not an ORM.
Who is it for?
Adopt go-jet/jet when you want SQL-shaped queries with compile-time checking and generated model types, and when running a code generator against a live schema fits your build. Do not adopt it if you need an ORM with lazy relations and identity tracking, or if you cannot give the generator read access to information_schema.
Can I use it commercially?
Yes. Apache-2.0 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 31 days 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 September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What go-jet/jet solves, and who it is aimed at

Writing SQL inside Go usually means choosing between string concatenation with placeholders and a full ORM. The first gives you SQL but no compiler help when a column name changes. The second gives you types but hides the query behind a session API. Jet takes a third position: the README states plainly that Jet is __not__ an ORM. Instead it generates Go types that mirror your tables, views and enums, and those types are what you write queries against.

The target reader is a Go developer who is comfortable with SQL and wants the database schema to be the source of truth in the codebase. The README frames the project as a complete solution for database access, combining a type-safe SQL builder with code generation and automatic result mapping. The generated builder covers SELECT, INSERT, UPDATE, DELETE, LOCK and WITH, including sub-queries, UNION, INTERSECT, EXCEPT and window functions. That is a wide surface, and it is the reason the generator exists: hand-writing that much type information would not be practical.

Code generation is the core mechanism, not a side feature

Jet has two halves that must stay in sync. The generator, invoked as the jet command, connects to a running database, reads information_schema, and writes Go packages for every table, view and enum it finds. The runtime package, github.com/go-jet/jet/v2, provides the statement builders and the result mapping that consume those generated types.

The README describes the generator output as a directory tree keyed by database name and schema name. For a PostgreSQL database called jetdb with schema dvds, the output lands under .gen/jetdb/dvds, with subfolders for the enum builder package and, by extension, the table and view packages. Each generated file corresponds to one database object. That layout matters in practice because the import path of your generated code is derived from the module and the output folder, so moving -path later means updating imports.

One behaviour deserves attention before you run it the first time. The README marks the cleanup step with a warning: the generator deletes all contents in the target schema folder before writing. It is not an incremental generator. If you have hand-edited anything inside .gen, that edit is gone on the next run. The generator also needs permission to read information_schema tables, which the README calls out explicitly.

Installing go-jet/jet and running the generator once

The README requires Go 1.24 or newer. The library itself is added to your module with go get, which pulls in the runtime package used by generated code. This command does not install the generator.

bash
go get -u github.com/go-jet/jet/v2

The generator is a separate binary. The README gives two options. The first is go install, which places the jet command in the directory named by GOBIN, defaulting to $GOPATH/bin or $HOME/go/bin.

bash
go install github.com/go-jet/jet/v2/cmd/jet@latest

The second option builds from source and writes the binary to a directory you choose, which the README notes must be on your PATH for global access to the jet command.

bash
git clone https://github.com/go-jet/jet.git
cd jet && go build -o <target_directory> ./cmd/jet

With the binary available, point it at a running database. The README's quick start uses the PostgreSQL dvd rental sample with user user, password pass, database jetdb and schema dvds. The -dsn flag carries the connection string, -schema selects the schema, and -path sets the output folder.

bash
jet -dsn=postgresql://user:pass@localhost:5432/jetdb?sslmode=disable -schema=dvds -path=./.gen

The README shows the expected output: a connection line, a retrieval line reporting the number of tables, views and enums found, the cleanup step, and then one generation line per object category before Done. If the counts look wrong, the schema or the user's read permissions are the first things to check. The same command shape works for other engines by changing -source or the DSN scheme: mysql with a tcp DSN, postgres for CockroachDB, mariadb, and sqlite with either -source=sqlite and a file path or a file:// DSN.

Where go-jet/jet stops being the right tool

The generator's cleanup step is the sharpest edge. Because it deletes everything in the destination folder, the generated tree must be treated as build output, not as source you edit. Teams that expect to tweak a generated model and keep the tweak will be disappointed, and the README offers no rollback or merge behaviour.

The second constraint is the live database. Generation requires a reachable database with readable information_schema at the moment you run the command. That is workable on a developer machine and in CI, but it makes the generator dependent on network access and credentials that a pure parser-based tool would not need. If your schema only exists as migration files and no instance is running, the generator has nothing to read.

The third is scope. Jet is a query builder and mapper. The README's own note that it is not an ORM is the clearest statement of the boundary: there is no lazy loading, no identity map, no automatic relation traversal implied by the feature list. If your application model is a graph of objects that you want the library to walk for you, Jet is the wrong shape. It gives you SQL and a destination struct, and you compose the rest.

How go-jet/jet differs from sqlc

The closest comparison people search for is sqlc, and the difference is in where the SQL lives. With sqlc, you write SQL queries by hand in .sql files and the tool generates Go functions for those specific queries. The query text is the input, and the generated API is bounded by the queries you wrote.

Jet inverts that. You write the query in Go using the generated builder types, and the generator's input is the database schema rather than a set of queries. Nothing is generated per query, so a query you have not written yet is still expressible, and the builder composes at runtime: joins, sub-queries, UNION and window clauses are assembled from the same typed primitives. The trade-off is that your queries are Go code rather than SQL text, which means you cannot paste them into a database console without translation, and reviewers read Go expressions instead of a statement.

A second practical difference follows from the first. sqlc's output depends only on files in the repository, so it runs without a database connection. Jet's generator needs the live schema, as the quick start command shows. Neither approach is strictly better; they put the source of truth in different places.

Maintenance status, licence and upgrade cost

The repository is not archived, and the last push was on 2026-08-31. The release history shows v2.16.0 on 2026-08-31, v2.15.0 on 2026-05-21 and v2.14.1 on 2026-01-22, so the cadence across 2026 is roughly one release per quarter with a smaller patch in between. Versioning is listed as a README section, though the excerpt does not spell out the policy beyond the v2 module path in go.mod.

The module declares go 1.24.0, which sets the floor for consumers. The generator's own dependencies are notable because they are real drivers: go-sql-driver/mysql, lib/pq for PostgreSQL, and mattn/go-sqlite3 for SQLite. The SQLite driver is cgo-based, which affects how the generator binary is built and where it can run. The library dependency you add to your application is separate and lighter.

Jet is licensed under Apache-2.0, and the repository carries both a LICENSE and a NOTICE file. Apache-2.0 permits commercial use and modification and includes a patent grant, but the NOTICE file must be preserved in distributions. That is a general property of the licence, not legal advice; check your own obligations before shipping.

Upgrade cost is concentrated in the generated code rather than the library. Because the generator rewrites the whole destination folder, upgrading the generator and regenerating produces a fresh tree. Any drift between your checked-in generated code and the current schema surfaces at that moment, which is useful, but it also means a generator upgrade and a schema change can land in the same diff and be hard to separate.

Editorial conclusion

Adopt go-jet/jet when you want SQL-shaped queries with compile-time checking and generated model types, and when running a code generator against a live schema fits your build. Do not adopt it if you need an ORM with lazy relations and identity tracking, or if you cannot give the generator read access to information_schema. Before committing, verify that the generator can reach your database from CI, and read the generated folder layout under .gen to confirm the package paths match your module.

Frequently asked questions

Is go-jet/jet an ORM?

No. The README states directly that Jet is not an ORM. It is a type-safe SQL builder with code generation and automatic query result mapping, so there is no lazy loading or identity map.

Which databases does go-jet/jet support?

The README lists PostgreSQL, MySQL and SQLite, and notes that CockroachDB and MariaDB are tested and known to work because they use compatible wire protocols. Support for other databases may come in future releases.

Does the go-jet/jet generator overwrite existing files?

Yes. The README warns that the generator deletes all contents in the target schema folder before writing new files, so the output directory should be treated as generated build output.

How do I install the go-jet/jet generator?

The README gives two options: go install github.com/go-jet/jet/v2/cmd/jet@latest, which places the binary in GOBIN, or cloning the repository and running go build -o <target_directory> ./cmd/jet.

Official sources

  1. go-jet/jet on GitHub
  2. Issues
  3. License: Apache-2.0
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/go-jet-jet.svg)](https://hysenlabs.com/projects/go-jet-jet)