Library / SDK
go-gorm/gorm avatar
go-gorm/gorm

GORM: the Go ORM that trades SQL control for developer speed

The fantastic ORM library for Golang, aims to be developer friendly

39,972 stars4,192 forksGoMIT

At a glance

What is it?
GORM is the most widely used ORM in the Go ecosystem, with associations, hooks, auto migrations and a plugin API. It is a good fit for CRUD-heavy services and a poor fit for teams that want their SQL to stay visible.
Who is it for?
Adopt GORM if your service is mostly CRUD over a relational schema and you want associations, hooks and auto migrations handled by the library rather than by hand. Do not adopt it if your workload is dominated by hand-tuned analytical SQL, or if you need the SQL your application emits to stay legible to a DBA without reading Go code.
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 15 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 28, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What GORM actually removes from a Go service

Without an ORM, a Go service that touches six tables accumulates a layer of code that does three things: build SQL strings, scan rows into structs, and keep the two in sync when a column is renamed. GORM targets that layer. The README describes it as a "Full-Featured ORM" and lists associations, hooks, eager loading, transactions with save points, batch inserts and auto migrations as built-in capabilities. Every one of those is a piece of plumbing you would otherwise write yourself.

The audience is narrower than "every Go developer". GORM fits teams building application services where the schema is relational, the queries are mostly shaped like CRUD, and the cost of writing the same scan-and-assign code repeatedly is higher than the cost of learning a query builder. It fits less well when the interesting part of the work is the SQL itself. The README does not claim otherwise, and the project's own guides at gorm.io are the place where the query surface is documented.

How the statement and callback pipeline works

The repository layout is the clearest description of the architecture. The top level holds gorm.go, statement.go, callbacks.go, chainable_api.go, finisher_api.go and scan.go, with subpackages for clause, schema, migrator, logger and callbacks. That split maps to a pipeline: a chainable call builds up a Statement, a finisher call executes it, and a chain of callbacks in the callbacks package runs around the execution.

The callback chain is what makes hooks work. The README lists hooks for Before/After Create, Save, Update, Delete and Find. Those hooks are not a separate subsystem bolted onto the query path; they are entries in the same callback chain that handles the query, which is why a hook can inspect or modify the Statement before the SQL is generated. The clause package is the other half: it holds the SQL fragments that get assembled into the final query, and the README mentions a SQL Builder, Upsert, Locking, Optimizer/Index/Comment Hints, NamedArg and SQL Expr as features that ride on it.

The schema package is what turns a struct into a table definition, and it is what AutoMigrate reads. The migrator package then compares that definition against the live database. This is a meaningful design choice: the struct is the source of truth, and the database follows it. Teams that treat the database as the source of truth and the struct as a projection will find that direction backwards.

Installing GORM and running a first query

The module path is gorm.io/gorm, and go.mod declares go 1.18 as the minimum. The core module pulls in only three direct dependencies: github.com/jinzhu/inflection, github.com/jinzhu/now and golang.org/x/text. Drivers are separate modules, so the database you choose is an extra dependency you add yourself.

Start by adding the core module. The repository's go.mod lists the module path and the Go version, which is what the import path and the toolchain requirement come from:

code
module gorm.io/gorm

go 1.18

The same file lists gorm.io/driver/sqlite as a dependency, which is the driver the repository itself pulls in:

code
gorm.io/driver/sqlite v1.6.0 // indirect

From there the README points to the GORM Guides at https://gorm.io and the Gen Guides at https://gorm.io/gen/index.html for setup and usage. The README does not include a worked connection example, so the exact Open call, the DSN format and the model definitions are documented in the guides rather than in the repository. Read those before writing your first query; the repository files show the module structure, not the API in use.

Where GORM's defaults become a liability

The struct-first model is convenient until it is not. AutoMigrate reads the schema package's interpretation of your struct and applies it to the database. The README lists Auto Migrations as a feature and stops there. It does not document what happens to a dropped field, a renamed column with existing data, or a type narrowing on a populated table. For a greenfield service this rarely matters. For a service with production data and a change-review process, the migration story is the part you must verify before you depend on it, and the README will not answer the question for you.

A second cost is legibility. Hooks, callbacks and preloading all run inside the query path. A Find call with a Preload attached will issue more than one statement, and the README's Preload and Joins entries are listed as two separate eager-loading strategies precisely because they produce different SQL. When a slow query appears in production, the person debugging it is reading Go, not SQL. Teams with a DBA in the loop, or with a query-log review process, will feel this. Teams without one will not.

The third cost is dependency surface. The core module is deliberately thin, but the plugin API the README describes, with Database Resolver for multiple databases and read/write splitting, means the interesting behaviour often lives in a separate module with its own release cadence. That is a normal Go ecosystem trade-off, not a defect, but it means the version you pin for the driver and the version you pin for the core can drift apart.

GORM against ent and hand-written SQL

The most direct alternative in the Go ecosystem is ent, which takes the opposite starting point: you describe the schema in Go code, and ent generates typed code from it. GORM takes the schema from structs and reflects over them at runtime. The practical difference is when errors surface. With generated code, a schema mismatch is a compile error. With reflection, it is a runtime error or a silently different query. GORM's flexibility is that you can add a field without regenerating anything; ent's rigidity is that the generated API cannot drift from the schema.

The other alternative is no ORM at all: database/sql with hand-written queries and a scanning helper. That gives you the exact SQL, which is what you want for reporting, bulk analytics or anything where the query plan is the deliverable. It costs you the association loading, hooks and batch helpers that GORM provides. The honest framing is that GORM is a productivity tool for the CRUD-shaped majority of an application, and hand-written SQL is the right tool for the minority that carries the performance risk. Many production Go services use both, and nothing in GORM prevents that.

Maintenance cadence, licence and upgrade cost

The repository is not archived, and the last push was on 2026-06-25, which is the same day v1.31.2 was released. The two prior releases, v1.31.1 and v1.31.0, landed on 2025-11-02 and 2025-09-12. That is roughly a twice-a-year minor cadence with patch releases in between, not a rapid one. Plan upgrades around that rhythm rather than expecting a fix to land within days.

The core module is MIT licensed, as the README's licence badge and the LICENSE file state. That is permissive and imposes no copyleft obligation on your application. Drivers are separate modules with their own licences, and the README does not enumerate them, so check the driver you choose independently. Nothing here is legal advice.

Upgrade cost is dominated by the driver, not the core. The core module's direct dependency list is short and stable, which means a GORM version bump rarely cascades. A driver bump is where behaviour can change, because the driver is what translates GORM's clause output into dialect-specific SQL. Pin both and read the driver's release notes, not just GORM's.

Editorial conclusion

Adopt GORM if your service is mostly CRUD over a relational schema and you want associations, hooks and auto migrations handled by the library rather than by hand. Do not adopt it if your workload is dominated by hand-tuned analytical SQL, or if you need the SQL your application emits to stay legible to a DBA without reading Go code. Before committing, verify two things: that a driver exists for your database and is maintained separately from the core module, and that the migration behaviour of AutoMigrate matches what your schema actually needs, since the README lists it as a feature but does not describe its limits. The core module is MIT licensed, so the licence is not the constraint here; your database driver is a separate dependency with its own terms.

Frequently asked questions

What is golang GORM?

GORM is an ORM library for Go, published at gorm.io/gorm under the MIT licence. The README describes it as a full-featured ORM with associations, hooks, eager loading, transactions and auto migrations, and the project's guides live at gorm.io.

What does the name GORM mean?

The repository does not explain the origin or expansion of the name. The README and the module metadata only use GORM as the project's name, so any expansion you see elsewhere is not documented in this material.

What does GORM mean?

The repository does not define the term. The README uses GORM only as the project name, and the module path gorm.io/gorm repeats it without an expansion.

What are the key differences between GORM and ent?

GORM derives its schema from Go structs and reflects over them at runtime, while ent generates typed code from a schema you describe in Go. The practical consequence is that a schema mismatch surfaces at runtime with GORM and at compile time with ent. The GORM README does not discuss ent.

Official sources

  1. go-gorm/gorm on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
For maintainers

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-gorm-gorm.svg)](https://hysenlabs.com/projects/go-gorm-gorm)
Community notes

Community notes