Skip to content
devituz edited this page Jun 3, 2026 · 1 revision

FAQ

The questions we actually get asked, with the shortest honest answers we can manage.

Why not just use GORM?

GORM is a fine ORM and lagodev is a different shape, not a better one. lagodev aims for "a single cohesive backend toolkit" — ORM, migrations, factories, seeders, an Artisan-style CLI, and an HTTP framework that all share a connection, logger, and config object. You can use lagodev's ORM without anything else if that's all you need; you cannot use the rest of lagodev with another ORM.

Concrete differences:

  • Generics from day one. orm.Query[User](conn).First(ctx) returns (*User, error) directly — no interface to type-assert. GORM 2 has reflection at the type boundary; lagodev avoids it.
  • No global state. Migrations and seeders register themselves via init() against an explicit registry; the connection is passed in everywhere.
  • CLI included. lago make:model, lago migrate, lago db:* ship with the library. With GORM you assemble a generator (typically via golang-migrate + go-fakeit + Cobra).
  • HTTP framework included. Optional, but it's there.

If your team is happy with GORM, the right move is to stay on GORM.

Does it work with my existing Gin app?

Yes — that's an explicit design goal. Import the ORM, write a service, call it from your Gin handler. The Framework-Integration page has the recipe for Gin, Fiber, Echo, Chi, plain net/http, gRPC, and GraphQL.

adapters/gin is also available — a separate Go module that adds Laravel-style helpers (Resource()-equivalent, paginate helper, JWT middleware) on top of Gin.

Which databases are supported?

In-box: PostgreSQL (pgx), MySQL (go-sql-driver/mysql), and SQLite (mattn/go-sqlite3). Each lives under drivers/ and is enabled by blank-importing it. The runtime is dialect- agnostic via the Grammar interface — see Architecture.

Adding a new dialect (Cockroach, SQL Server, TiDB) is a Grammar implementation + a database.Register call in your driver package — roughly 200 lines.

Is it production-ready?

The components have a thorough test suite (every package has tests; the full suite runs on every PR via GitHub Actions) and the API has been stable since v0.13.0. But the library is still pre-1.0: minor versions can introduce breaking changes if there's a strong reason. Check the CHANGELOG before bumping versions.

What we'd consider production-ready today:

  • ORM, query builder, migrations, schema DSL, factories, seeders
  • web framework + the secure-by-default middleware stack
  • auth (JWT + bcrypt), crypt, cache, events, httpclient, filesystem (local), process, authz, carbon, session, mail (SMTP + LogMailer), mock, i18n

Adapters (adapters/gin, adapters/websocket, filesystem/s3, drivers/redis) are functional and tested, but newer — read the release notes for the version you pin.

How do I handle soft deletes?

Use a deleted_at column with a manual IS NULL filter, or add a status enum column and filter on it. The framework itself does not bundle a soft-delete scope today — it's been removed in favour of explicit, query-level deletion semantics.

If you need an automatic global scope, an issue describing your use case is welcome.

How do migrations behave when two services share a database?

The migrator acquires an advisory lock on Postgres (pg_advisory_lock) or a row lock in a migrations_lock table on other dialects. Two simultaneous deploys from the same service will serialise; a different service running its own migration set against the same database is up to you to coordinate (typically: split schemas).

Can I run lagodev in serverless / Lambda?

Yes for stateless code paths (the ORM, the query builder, the mailer's HTTP drivers). The bundled web framework's graceful-shutdown loop assumes a long-lived process — in a function-as-a-service environment, use lagodev as a library and call the ORM directly from your handler.

Does the web framework support WebSockets?

The web package itself doesn't ship a WebSocket handler. The adapters/websocket module provides a Hub + channel/room model (Laravel Echo-style) built on coder/websocket, and works as a stdlib http.Handler so it drops into any framework, including web.

What about HTML templates / server-rendered pages?

The bundled web framework is JSON-first. For server-rendered HTML today, use the standard library's html/template from a handler (or render into a bytes.Buffer and call c.String(200, …) / c.Writer.Write(…)).

A first-class template integration is on the roadmap.

Why two binaries — lago and artisan?

They're the same CLI. Laravel developers expect artisan; some teams already have an artisan binary for their PHP app; some people just prefer typing lago. Pick one. They're 100 % feature- parity.

How do I sponsor the project?

The repo's "Sponsor" button at the top points to GitHub Sponsors. You can also star and share — that helps newcomers find lagodev just as much.

I found a bug. How do I report it?

Open an issue using the bug-report template. A self-contained reproducer (a small runnable snippet or a public repo link) gets you a fix far faster than a description.

For security issues, follow the private process in SECURITY.md.

How do I contribute?

CONTRIBUTING.md is the short version. Start with a good first issue if you're new.

See also

Clone this wiki locally