GORM: what the Go ORM actually gives you, and where it stops
The fantastic ORM library for Golang, aims to be developer friendly
At a glance
- What is it?
- GORM is an MIT-licensed Go ORM whose README lists associations, hooks, transactions, batch operations and a plugin API. This article covers the parts of that list that carry real weight, the migration risk in AutoMigrate, and the maintenance cost of staying on the module.
- Who is it for?
- Adopt GORM when your schema is already stable and you want association loading, hooks and nested transactions without hand-writing that plumbing. Do not adopt it if your team's convention is raw SQL with a thin scanner, or if you expect AutoMigrate to manage production schema changes; the README describes it as Auto Migrations with no caveats, so verify its behaviour against your own migration tooling before you rely on it.
- 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 September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem GORM targets: relation-heavy Go code without hand-written mapping
Go's standard library gives you database/sql plus whatever driver you register. It does not give you a way to say that a User has many Orders and get both back from one call. Teams that skip an ORM end up writing the same three things by hand: a scan loop that maps columns to struct fields, a loader that fetches related rows and stitches them into slices, and a transaction wrapper that decides when to commit. GORM's README frames its scope around exactly that gap. It lists associations as Has One, Has Many, Belongs To, Many To Many, Polymorphism and Single-table inheritance, and it lists eager loading through Preload and Joins. Those two entries together are the pitch: declare the relationship once, then ask for the parent and let the library issue the follow-up query. The audience is a Go service team with a relational schema and enough relations that hand-rolled scanning has become the bulk of the data layer. A single-table service with two queries does not need this. A team already fluent in SQL and happy with sqlc-style generated scanners will read the feature list and see duplication of work they have already done.
How the pieces fit: models, hooks, sessions and the plugin boundary
The README describes a lifecycle, not just a query builder. Hooks fire Before and After Create, Save, Update, Delete and Find. That means the library owns the order of operations around a write: your BeforeSave runs, the statement is issued, your AfterSave runs. Transactions come in three depths according to the same list: ordinary transactions, nested transactions, and save points with RollbackTo to a saved point. Context support sits alongside a Prepared Statement Mode and a DryRun Mode, which the README presents as a way to inspect what would be executed without executing it. Batch work has its own entries: Batch Insert, FindInBatches and Find To Map. On top of the core, the README names an extendable plugin API and gives two examples, a Database Resolver for multiple databases and read/write splitting, and a Prometheus plugin. The architecture that emerges is a core that builds and runs statements, a callback chain that hooks attach to, and a plugin layer that wraps the session. The README does not document the callback internals or the plugin interface signature; for those, the linked GORM Guides at gorm.io are the reference, and the README points there rather than reproducing them.
Getting it running: the module, the guides and the two documentation tracks
The README is deliberately thin on installation. It points to the module path gorm.io/gorm for the Go.Dev reference, and to two guide sets: GORM Guides at gorm.io and Gen Guides at gorm.io/gen/index.html. That split is worth noting before you start. GORM and Gen are separate documentation tracks, and the README treats Gen as its own product rather than a section of the core library. The README does not print a go get line, does not show a connection snippet, and does not list a driver package. So the first real step is not in the repository README at all; it is in the guides. The same applies to configuration. The README names features such as Prepared Statement Mode, DryRun Mode, NamedArg, Optimizer/Index/Comment Hints and Locking, but the config keys and method names for enabling them live in the guides, not here. If you are evaluating GORM from the repository alone, budget time to read gorm.io before you can judge whether the API shape suits you. The README also states that every feature comes with tests, which tells you the test suite is the intended evidence of behaviour, but it does not tell you how to run it or which databases the suite covers.
AutoMigrate and the schema question the README leaves open
Auto Migrations appears in the feature list with no qualifier. That is the entry most likely to be misread. An ORM that can create or alter tables from your struct definitions is convenient in development and risky in production, because the failure mode is silent: a column type changes, a constraint is dropped, and nothing in the README's one-line description warns you. The README does not state which databases AutoMigrate supports, whether it ever drops columns, or how it handles a rename. It also does not position AutoMigrate against a dedicated migration tool, and it does not say that AutoMigrate is additive only. Treat that line as a pointer to the guides, not as a guarantee. The same caution applies to the other one-line entries. Single-table inheritance and Polymorphism are named without an example, and those are the association types most likely to behave differently from what a reader assumes. The README gives you the vocabulary; the guides give you the semantics. Reading the feature list as a specification is the mistake to avoid.
Where GORM is the wrong tool, and what the raw-SQL alternative actually looks like
The honest alternative is not another ORM. It is database/sql with a code generator that produces typed scan functions from your queries. The difference is where the work sits. With GORM, you describe your structs and the library derives statements from them; the query is a consequence of the model. With generated scanners, you write the SQL and the generator derives the Go types from it; the model is a consequence of the query. That second approach keeps every statement visible in review and keeps the database as the source of truth for types. It costs you the association loader, the hook chain and the nested transaction handling, all of which you write yourself. GORM is the wrong tool when your team's review process requires every SQL statement to be readable in the diff, when your queries are analytical and do not map cleanly onto structs, or when you are working against a database whose driver is not maintained under the go-gorm organisation. It is also a poor fit if you need the ORM to manage production schema evolution, because the README's description of Auto Migrations does not support that expectation. The plugin API is a genuine differentiator, since read/write splitting and Prometheus instrumentation are named as plugins rather than bolted on, but a plugin you have to write yourself is not a feature you have.
Maintenance cost: release cadence, module versioning and the MIT licence
The release history in the repository shows v1.31.0 in September 2025, v1.31.1 in November 2025, and v1.31.2 in June 2026, with the last push to master on the same day as the v1.31.2 tag. That is a patch-oriented cadence: two patch releases and one minor across roughly nine months. For an adopter, the practical question is what a minor bump carries. The README does not include a changelog, a compatibility policy or a deprecation process, so the release notes attached to each tag are the only place to check. Pinning a version and reading the notes before moving is the cheap habit here. On licensing, the repository is MIT, and the README carries the line Released under the MIT License with a copyright notice reading Jinzhu, 2013~time.Now. MIT is permissive and imposes no copyleft obligation on your application code, but it does require the copyright notice and permission notice to be preserved in copies or substantial portions of the software. That is a statement about what the licence text says, not legal advice; if your organisation has a licence review process, the LICENSE file in the repository is the artifact to hand it.
What to verify before you commit to GORM in a service
Three checks are worth doing before the first line of production code. First, confirm that the database you run has a driver maintained under the go-gorm organisation; the README lists the core module only and does not enumerate drivers, so this is a separate lookup. Second, read the AutoMigrate section of gorm.io against a real schema change you have pending, and decide whether you will let AutoMigrate touch production or keep it to local development with a separate migration tool for deployed environments. Third, take one association from your schema, ideally a Many To Many or a Polymorphic one, and trace how Preload and Joins would fetch it in the guides before you model it, because those are the entries the README names without examples. None of this requires installing anything. It requires reading the guides rather than the repository README, which is where the detail actually lives. If those three checks come back clean, the feature list describes a library that will remove a substantial amount of scanning and loading code from your data layer.
Editorial conclusion
Adopt GORM when your schema is already stable and you want association loading, hooks and nested transactions without hand-writing that plumbing. Do not adopt it if your team's convention is raw SQL with a thin scanner, or if you expect AutoMigrate to manage production schema changes; the README describes it as Auto Migrations with no caveats, so verify its behaviour against your own migration tooling before you rely on it. Before committing, check the v1.31.x release notes for breaking changes since the version you evaluated, and confirm that the database you use has a driver under the go-gorm organisation.
Community notes