Spawn
The Database Build System.
Stop treating your database like a script runner. Start treating it like a codebase.
I like to lean heavily on the database. I don't like tools that abstract away the raw power of databases like PostgreSQL. Spawn is designed for developers who want to use the full breadth of modern database features: Functions, Views, Triggers, RLS -- while keeping the maintenance nightmares to a minimum.
Spawn introduces Components, Compilation, and Reproducibility to SQL migrations.
Installing
Or simply:
# Install (macOS/Linux)
|
The Philosophy
Standard migration tools (Flyway, dbmate) are great at running scripts, but bad at managing code. When you update a complex function, you have to copy-paste the code into a new file, which is cumbersome, makes your Git history messy, and makes code reviews more challenging.
Spawn works differently:
- Edit in Place: Keep your functions in
components/. Edit them there. Get perfect Git diffs. - Pin in Time: When you create a migration, Spawn snapshots your components in an efficient git-like storage, referenced per-migration via their
lock.toml. - Compile to SQL: Spawn compiles your templates and pinned components into standard SQL transactions.
See it in action in the Tutorial.
Key Features
๐ฆ Component System (CAS)
Store reusable SQL snippets (views, functions, triggers) in a dedicated folder. When you create a migration, spawn migration pin creates a content-addressable snapshot of the entire tree.
- Result: Old migrations never break, because they point to the snapshot of the function from 2 years ago, not the version in your folder today.
Docs: Tutorial: Components | Templating
๐งช Integration Testing Framework
Spawn includes a native testing harness designed for SQL.
- Macros: Use Minijinja macros to create reusable data factories (
{{ create_user('alice') }}). - Ephemeral DBs: Tests can run against temporary database copies (
WITH TEMPLATE) for speed. - Diff-Based Assertions: Tests pass if the output matches your
expectedfile.
Docs: Tutorial: Testing | Test Macros
๐ Zero-Abstractions
Spawn wraps psql. If you can do it in Postgres, you can do it in Spawn.
- No ORM limitations.
- No waiting for the tool to support a new Postgres feature.
- Full support for
\gset,\copy, and other psql meta-commands.
โ๏ธ Cloud Native
Connecting to production databases can be configured to use all your standard commands. You just need to provide it with a valid psql pipe.
Spawn supports Provider Commands -- configure it to use gcloud, aws, or az CLIs to resolve the connection or SSH tunnel automatically.
# spawn.toml
[]
= {
kind = "provider",
= ["gcloud", "compute", "ssh", "--dry-run", ...],
= ["psql", ...]
}
Docs: Manage Databases | Configuration
A Quick Look
Here is how you handle a changing database function in Spawn without breaking history.
1. Create a Component (Your Source of Truth)
components/users/full_name.sql
(first text, last text)
RETURNS text AS $$
BEGIN
-- V1 Logic: Simple concatenation
RETURN first || ' ' || last;
END;
$$ LANGUAGE plpgsql IMMUTABLE;
2. Write a Migration (Import, don't Copy)
migrations/20260101-add-users/up.sql
BEGIN;
(id serial, first text, last text);
-- Import the logic to generate names
{% include 'users/full_name.sql' %}
COMMIT;
3. Pin It (The Magic)
Run spawn migration pin. Spawn calculates the hash of full_name.sql and locks this migration to that specific version.
# migrations/20260101-add-users/lock.toml
= "a1b2c3d4..." # ๐ This migration will ALWAYS use the V1 logic.
4. Evolve It
Next year, when you decide to include Middle Initials, you simply update components/users/full_name.sql and create a new migration. The old migration remains locked to the V1 logic forever. Zero copy-pasting.
Roadmap
Spawn is currently in Public Beta. The core features are stable and production-ready.
Currently Supported:
- โ Core Migration Management (Init, New, Apply)
- โ Component Pinning & CAS
- โ Minijinja Templating
- โ Testing Framework (Run, Expect, Compare)
- โ Database Tracking & Advisory Locks
- โ CI/CD Integration
What's Next:
- ๐ Rollback Support: Optional down scripts for reversible migrations.
- ๐ Additional Engines: Native PostgreSQL driver, MySQL, and more.
- ๐ Multi-Tenancy: First-class support for schema-per-tenant migrations.
- ๐ Drift Detection: Compare expected vs actual database state.
- ๐ External Data Sources: Better support for data from files, URLs, and scripts in templates.
- ๐ Plugin System: Custom extensions for engines, data sources, and workflows.
(See Roadmap for detailed tracking)
Documentation
Full documentation, recipes, and configuration guides are available at:
๐ docs.spawn.dev
Contributing
We welcome contributions! Please read CONTRIBUTING.md before opening a PR. Note that this project requires signing a CLA.