CLI tool
gobuffalo/pop avatar
gobuffalo/pop

gobuffalo/pop for Go Database CRUD and Migrations

A Tasty Treat For All Your Database Needs

1,525 stars251 forksGoMIT

At a glance

What is it?
gobuffalo/pop is a convention-based Go database layer built around sqlx, with support for CRUD, queries, migrations, and several SQL dialects. It suits Go applications that want ActiveRecord-style conventions without adopting a full ORM.
Who is it for?
Adopt pop when a Go service benefits from sqlx-backed CRUD, conventions, and file migrations across supported database engines. Do not choose it when automatic unit-of-work or schema generation is required, because the README documents neither feature.
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 5 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 October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Why gobuffalo/pop Exists for Go Database Work

gobuffalo/pop addresses repetitive database code that appears in Go applications after a project adopts SQL. The README says it wraps `github.com/jmoiron/sqlx` and simplifies common database workflows. Pop supplies a higher-level interface while retaining sqlx as its foundation.

The target user is a Go developer who wants database access to follow recognizable naming rules. Pop's defaults are influenced by the Ruby ActiveRecord gem. A struct named `User` maps by default to the lowercase, plural, underscored table name `users`. A struct named `FooBar` maps to `foo_bars`. Tables must have an `id` column, and the corresponding Go struct must contain an `ID` field.

Pop is also relevant to applications that need more than basic inserts and lookups. The README explicitly names CRUD operations, migrations, and building or executing queries. Repository files add concrete areas such as associations, callbacks, joins, groups, having clauses, connection instrumentation, and dialect implementations. This makes it closer to an application database toolkit than a thin query helper. It is still not a replacement for the underlying SQL database, and the README does not describe automatic schema creation or a long-lived object graph.

The repository topics include CockroachDB, MySQL, PostgreSQL, and SQLite. Its module also contains a MariaDB dialect and driver dependencies for these environments. That breadth matters for applications that share a data-access design across local development and multiple production databases, although SQL behavior can still vary by dialect.

The sqlx Backed CRUD and Convention Model

Pop's central mechanism is a database layer above sqlx. The repository includes connection handling, executors, finders, clauses, and dialect-specific code, while `go.mod` directly requires `github.com/jmoiron/sqlx v1.4.0`. Based on this repository layout, Pop delegates much of the SQL execution and struct scanning foundation to sqlx and adds conventions around it.

Record creation and updating have timestamp behavior when matching struct fields exist. If the table contains `created_at` and the struct has `CreatedAt time.Time`, Pop sets that field to the current time on creation. If both the `updated_at` column and `UpdatedAt time.Time` field are present, Pop sets it during an update. This is conditional rather than universal. A project with differently named audit columns cannot rely on these defaults unless it follows the convention.

Table naming is likewise automatic. The conversion rule derives from the struct name, including lowercase, pluralization, and underscores. That works well for conventional schemas, but creates a boundary for physical table names that do not follow the generated result. The README does not document a naming annotation or override syntax, so the exact override mechanism should be checked in the linked documentation before committing a schema with irregular names.

The repository separates common SQL features into files such as `join.go`, `group.go`, `having.go`, and `clause.go`. Association code appears in `associations/` and `belongs_to.go`. These files show that relationships and query composition are part of the library rather than features invented by an application wrapper. The README does not establish lazy loading, identity mapping, or automatic transaction boundaries.

Migrations, Dialects, and Local Database Services

File migrations are a separate repository concern, represented by `file_migrator.go`. Pop therefore does more than map rows to structs: it can organize schema changes alongside Go code. The README does not show migration file syntax, command names, rollback behavior, or production ordering rules. Those omissions matter. An evaluation should not assume that the familiar `up` and `down` model exists merely because other migration tools use it.

Dialect handling is more visible. The repository contains separate source files for CockroachDB, MariaDB, MySQL, PostgreSQL, and SQLite. The `dialect_sqlite_tag.go` filename and the Makefile's default `sqlite` build tag indicate that SQLite support can depend on build selection. This matters when packaging an application that includes both a compiled binary and migration tooling.

For contributors to this repository, the Makefile defines the following installation target. It calls the dependency target and installs `./soda` with the selected build tags. This is a repository build command, not a documented consumer setup command for applications.

makefile
install: deps
	$(GO_BIN) install -tags ${TAGS} -v ./soda

The same Makefile sets `TAGS` to `"sqlite"` by default. A local integration can start from the Compose services after confirming that a compatible container runtime is available. The repository defines MySQL on host port `3307`, PostgreSQL on `5433`, and CockroachDB SQL on `26258`, plus CockroachDB's web interface on `8081`.

yaml
services:
  mysql:
    image: mysql:26.7
    ports:
      - "3307:3306"
  postgres:
    image: postgres:18
    ports:
      - "5433:5432"

These are repository test-service settings. Their credentials and deployment settings should not be reused as a production configuration.

Installing pop and Performing the First Application Check

The README sends users to `https://gobuffalo.io/docs/db/getting-started` for the current consumer tutorial and to `https://gobuffalo.io/docs/db/toolbox` for CLI installation. It does not provide a complete application installation command in the README. The repository's Go module identifies the import path:

text
module github.com/gobuffalo/pop/v6

For an existing Go project, verify that its toolchain satisfies `go 1.26.0` from `go.mod`. The Makefile's CLI build is not the same as adding the library to an application, and the README does not state whether the toolbox uses a separate installation command in the current release.

The first application check should cover one struct and one conventional table. Use an `ID` field, derive the table name with Pop's lowercase plural underscore rule, and use `CreatedAt` and `UpdatedAt` only if those are the actual column names. The repository has a `database.yml`, but its configuration keys are not shown in the README. Consult that file and the linked configuration documentation for connection syntax and environment-variable behavior.

A useful smoke test creates a record, loads it by primary key, updates it, and observes the expected timestamp fields. Run a query path that joins or filters records if the application depends on those features. Finally, exercise a file migration against the target database dialect. This sequence separates connection failure from struct-mapping failure and dialect-specific SQL failure. The README does not promise a compatibility matrix for every supported database, so SQLite success alone is not sufficient evidence for PostgreSQL, MySQL, or CockroachDB.

Where pop's Conventions Create Friction

The first limitation is schema convention. Pop expects an `id` column and a matching `ID` field, and it derives table names from struct names. That is convenient for conventional schemas but creates friction for designs centered on composite primary keys, renamed identifiers, views, or domain-specific table names. The README does not confirm override mechanisms for those cases.

The second limitation is the depth of the project overview. It links to external documentation rather than showing complete connection, CRUD, transaction, or migration examples. Transaction scope is especially important. Although the repository has `executors.go`, its presence does not establish a high-level unit-of-work API, automatic transaction wrapping, or rollback semantics. An application that needs explicit aggregate boundaries should verify those behaviors in the external documentation or source before selecting Pop.

Pop is also the wrong tool when the project wants schemas generated automatically from Go structs. The documented capabilities center on CRUD, query execution, conventions, associations, and file migrations. No schema-generation mechanism is identified by the README or repository entries. Teams whose main requirement is model-first schema creation should compare a migration generator built around model changes.

SQLite's build-tag treatment introduces another packaging decision. A developer build using the default tag may differ from a release build that omits SQLite. Support for multiple engines does not guarantee identical SQL behavior across them. Dialect-specific validation remains necessary for transactions, migrations, locking, and query features.

Direct sqlx and Pop Make Different Ownership Choices

Direct sqlx is the clearest alternative because Pop explicitly wraps it. A sqlx-based application keeps control over SQL construction, table naming, primary-key assumptions, timestamp handling, and migration organization. Pop reduces that repeated setup by adding ActiveRecord-inspired defaults, CRUD facilities, query composition, associations, and file migrations. The trade is reduced control over conventions that do not match an existing schema.

Direct sqlx is likely the better fit when an application already has established repository patterns, unusual table identifiers, explicit SQL review requirements, or a migration system that should remain independent. It also keeps the application layer smaller and removes uncertainty about ORM-style mapping behavior. Pop is more attractive when several services need the same conventions or when writing untyped CRUD by hand has become repetitive.

Another alternative is a full ORM with its own identity tracking, lifecycle hooks, and transaction model. Pop does not document those capabilities, so treating it as equivalent would be misleading. Its README defines a narrower role: a convenient layer over sqlx with CRUD, queries, and migrations. Teams needing ownership of every SQL statement may prefer sqlx directly; teams wanting common database conventions without adopting a separate object identity model may find Pop's approach more suitable.

Maintenance Signals and v6 Upgrade Constraints

The repository is not archived, and the last push was on 2026-10-10. Recent releases include `v6.4.1` on 2026-09-16, `v6.4.0` on 2026-09-08, and `v6.3.0` on 2026-04-18. These dates show recent release activity, but release notes would be needed to determine compatibility and migration requirements between versions.

The declared Go version is `go 1.26.0`. That creates a direct environment requirement for consumers of this module version and may increase upgrade cost when an application is pinned to an older Go toolchain. The module path includes `/v6`, so an adopter must use the v6 module path rather than an unversioned import.

Database upgrades add separate work. Pop depends on drivers including `github.com/go-sql-driver/mysql`, `github.com/lib/pq`, `github.com/jackc/pgx/v5`, and `github.com/mattn/go-sqlite3`. A production engine upgrade can affect both server behavior and driver behavior. Migration compatibility must be checked separately for every deployed database.

The repository uses the MIT license. That identifies the stated permission and condition framework for reuse and modification, but this review does not provide legal advice. Dependency licenses should be reviewed through the adopting organization's normal approval process.

Editorial conclusion

Adopt pop when a Go service benefits from sqlx-backed CRUD, conventions, and file migrations across supported database engines. Do not choose it when automatic unit-of-work or schema generation is required, because the README documents neither feature. Before adoption, verify connection configuration, generated SQL, dialect behavior, and the migration path against the application schema; the repository's last push was on 2026-10-10.

Frequently asked questions

Which databases does gobuffalo/pop support?

The repository includes dialects for CockroachDB, MariaDB, MySQL, PostgreSQL, and SQLite. Its repository topics also name PostgreSQL, MySQL, SQLite, and CockroachDB.

How does gobuffalo/pop name database tables?

By default, it converts a struct name to a lowercase, plural, underscored table name. For example, `User` maps to `users` and `FooBar` maps to `foo_bars`.

Does gobuffalo/pop support migrations and CRUD operations?

Yes. The README identifies CRUD operations, migrations, and query building or execution as core functions. The repository also contains `file_migrator.go` and related query source files.

What Go version does gobuffalo/pop v6 require?

The repository's `go.mod` declares `go 1.26.0`.

Does gobuffalo/pop replace SQL?

No. Pop wraps `github.com/jmoiron/sqlx` and adds CRUD, query, association, convention, and migration features around that SQL-oriented foundation.

How is gobuffalo/pop installed?

The README points consumers to Buffalo documentation for CLI installation and application setup. For repository contributors, the Makefile installs `./soda` with configured build tags.

Official sources

  1. gobuffalo/pop on GitHub
  2. Issues
  3. License: MIT
  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/gobuffalo-pop.svg)](https://hysenlabs.com/projects/gobuffalo-pop)

Was this useful?