Open-source project
ariga/atlas avatar
ariga/atlas

ariga/atlas: Declarative Database Schema Migrations as Code

Declarative schema migrations with schema-as-code workflows

8,758 stars376 forksGoApache-2.0

At a glance

What is it?
Atlas compares a live database to a desired schema written in HCL, SQL or an ORM and generates the migration plan itself. It is aimed at teams that already treat infrastructure as code and want the same review cycle applied to tables, indexes and row-level security policies.
Who is it for?
Adopt Atlas if your schema already lives in a repository and you review changes through pull requests, particularly if you run several databases or want migration linting in CI. Do not adopt it if you need a migration runner that works without a dev database, or if your team will not maintain an HCL or SQL schema file as the source of truth.
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 9 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

The problem Atlas solves for teams with more than one database

Most migration tools assume a human writes each migration file by hand and the tool applies them in order. Atlas inverts that. You describe the schema you want, and the tool computes the difference between that description and the database as it currently exists. The README calls the declarative workflow "similar to Terraform": you declare the target state, and the plan is derived rather than authored.

That matters most when the same logical schema has to exist in several places. A local Postgres for development, a staging instance, a production cluster, and a test container all drift apart over time. Hand-written migrations accumulate and nobody can say with confidence what the schema looks like. Atlas treats the schema definition as the artifact under version control and the databases as things to be reconciled against it.

The intended user is a backend or platform engineer who is comfortable with infrastructure-as-code patterns and who owns the database layer of an application. It is not aimed at someone who wants a graphical schema designer, and it is not a database administration console.

How the diff engine and dev database fit together

The mechanism rests on three inputs. There is the current state, read from the target database through a connection URL. There is the desired state, read from an HCL file, a SQL file, or an ORM's schema definition. And there is a dev database, which Atlas uses as a scratch space to normalize and compare the two.

The dev database is the part that surprises people. Atlas does not simply compare two schema dumps textually. It needs somewhere to load schemas so it can reason about them, which is why the README's apply example passes a dev-url pointing at a Docker container. The documentation states that this container is spun up for the comparison. In environments where Docker is unavailable, that requirement becomes the first obstacle.

From those inputs Atlas produces a migration plan: the set of statements that would move the current state to the desired state. The same plan becomes either something you inspect and run, or something you save as a versioned migration file. The versioned workflow uses the same planning machinery but writes the output to disk so it can be reviewed and committed.

The repository layout reflects this split. The top level holds cmd, internal, schemahcl, sql and sdk directories alongside atlasexec. The go.mod file lists hashicorp/hcl/v2 as a direct dependency, which is consistent with HCL being a first-class schema format rather than a bolt-on.

Installing Atlas and running your first schema apply

The README lists several install paths. On macOS and Linux there is a shell installer, Homebrew has a tap, and there is a Docker image plus an npm package. Pick whichever fits your existing tooling; the binary is the same.

bash
brew install ariga/tap/atlas

The curl installer is the alternative for machines without Homebrew.

bash
curl -sSf https://atlasgo.sh | sh

If you would rather not install anything globally, the Docker image is pulled directly.

bash
docker pull arigaio/atlas

Once the binary is on your path, the first useful command inspects an existing database and prints its schema. The README gives this example against a local Postgres instance.

bash
atlas schema inspect -u "postgres://localhost:5432/mydb"

You should see the tables, columns and constraints of that database rendered as HCL. That output is a reasonable starting point for a schema file, though you will want to edit it before treating it as the source of truth.

The next step applies a desired schema. Note the two URLs: one points at the target database, the other at a file, and a third points at the dev database Atlas uses for comparison.

bash
atlas schema apply \
  --url "postgres://localhost:5432/mydb" \
  --to file://schema.hcl \
  --dev-url "docker://postgres/16/dev"

Atlas prints the plan and asks for confirmation before executing, according to the README. If the dev container cannot start, the command fails before touching your target database, which is the safer failure mode.

Linting is the feature that changes review habits

Atlas ships with what the README describes as 50+ built-in analyzers. They inspect migration files rather than the live database, and they are grouped by the kind of risk they detect: destructive changes such as dropped tables or columns, data-dependent modifications such as adding a non-nullable column without a default, and database-specific hazards like table locks and table rewrites that can stall a busy table.

bash
atlas migrate lint --dev-url "docker://postgres/16/dev"

The dev-url appears here too. Linting is not a static text analysis; it uses the dev database to evaluate the migration in context, which is why the flag is required rather than optional. That design choice buys accuracy at the cost of a container dependency in CI.

The README also mentions custom policy rules for teams that want to encode their own constraints. That is the natural extension point: built-in analyzers cover general hazards, and custom rules cover the conventions specific to one organization.

Where Atlas is the wrong tool

The dev database requirement is the clearest limitation. Every apply, plan and lint operation that involves comparison needs a scratch database Atlas can reach. In a restricted CI runner without Docker, or against a managed database where you cannot create throwaway schemas, this becomes a configuration problem before it becomes a migration problem. The README documents the dev-url flag but does not describe a mode that removes the dependency.

There is also a conceptual cost. Declarative workflows assume the schema file is authoritative and that all changes flow through it. If your team routinely makes hotfix changes directly against production, the next diff will propose reverting them. Atlas will faithfully report the drift, but resolving it is a human decision, and the tool cannot tell you whether the drift was intentional.

Finally, the supported database list is broad but not universal. It covers PostgreSQL, MySQL, MariaDB, SQL Server, SQLite, ClickHouse, Redshift, Oracle, Snowflake, CockroachDB, TiDB, Databricks, Spanner, Aurora DSQL and Azure Fabric. If your database is not on that list, the comparison engine has nothing to work with.

Atlas compared with a hand-written migration runner

The obvious alternative is a conventional migration library in your application's language: a directory of numbered SQL or code files plus a command that applies unapplied ones in order. Flyway and Liquibase are the established names in that space; language-specific libraries such as golang-migrate or Alembic occupy the same niche.

The difference is where the plan comes from. A conventional runner executes what you wrote. Atlas computes what should be written, based on the gap between two states. That means fewer hand-authored files and less chance of a typo in a column definition, but it also means the generated SQL is a product of the tool's comparison logic rather than a human's intent. Teams that want to read every statement before it runs will still get that opportunity through the plan output, but they are reviewing generated code rather than authored code.

A second difference is scope. Conventional runners migrate tables. Atlas also manages roles, permissions and row-level security policies as code, and the README lists data management for seed and lookup data alongside the schema. That is a wider surface than most migration libraries attempt.

On integration, the README names a Kubernetes operator, a Terraform provider, GitHub Actions, GitLab CI and ArgoCD. Those are separate pieces you would wire up yourself with a conventional runner.

Licence, maintenance and upgrade cost

The repository is licensed Apache-2.0 according to the LICENSE file at the top level. That is a permissive licence, but it is worth reading the actual file rather than relying on the identifier, because projects sometimes carve out specific directories or integrations under different terms. Nothing in the repository's top-level layout indicates such a carve-out, but the obligation to check is yours.

The repository is not archived, and the last push was on 2026-09-20. Recent releases are v1.3.0 on 2026-08-02, v1.2.0 on 2026-04-10 and v1.1.0 on 2026-02-05, which is a cadence of roughly one minor release per quarter. The go.mod declares go 1.26.4, so building from source ties you to a recent Go toolchain.

Upgrade cost depends on which surface you use. The CLI is a single binary, so upgrading is a version bump in your CI image or Homebrew. The SDK and atlasexec packages are Go libraries, and depending on them directly means tracking their APIs across minor versions. The company behind the project also offers a cloud product; the README references cloud integration for IAM authentication and secrets management, and the documentation for those features lives on atlasgo.io rather than in the repository.

Editorial conclusion

Adopt Atlas if your schema already lives in a repository and you review changes through pull requests, particularly if you run several databases or want migration linting in CI. Do not adopt it if you need a migration runner that works without a dev database, or if your team will not maintain an HCL or SQL schema file as the source of truth. Before committing, verify which of the supported databases your version covers, confirm the dev-url container approach works in your CI network, and read the license file at the repository root rather than assuming Apache-2.0 covers every integration.

Frequently asked questions

How do I install Atlas on macOS or Linux?

The README lists a shell installer via curl and a Homebrew tap, plus a Docker image and an npm package. Homebrew users run brew install ariga/tap/atlas, and the shell installer is curl -sSf https://atlasgo.sh | sh.

Does Atlas need a dev database to work?

The README's apply and lint examples both pass a --dev-url flag pointing at a container, and the documentation describes it as the scratch database used for comparison. Without a reachable dev database, those commands cannot complete the comparison step.

Which databases does Atlas support?

The README lists PostgreSQL, MySQL, MariaDB, SQL Server, SQLite, ClickHouse, Redshift, Oracle, Snowflake, CockroachDB, TiDB, Databricks, Spanner, Aurora DSQL and Azure Fabric. Databases outside that list are not covered by the comparison engine.

What does Atlas migration linting check?

The README states there are 50+ built-in analyzers covering destructive changes like dropped tables or columns, data-dependent modifications such as adding a non-nullable column without a default, and database-specific risks including table locks and table rewrites. Custom policy rules can be defined on top of those.

Official sources

  1. ariga/atlas on GitHub
  2. License: Apache-2.0
  3. Project website
  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/ariga-atlas.svg)](https://hysenlabs.com/projects/ariga-atlas)