# Spawn
### The Database Build System.
[](LICENSE)
[](https://docs.spawn.dev)
**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
[](https://docs.spawn.dev/getting-started/install/)
Or simply:
```bash
# 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:**
1. **Edit in Place:** Keep your functions in `components/`. Edit them there. Get perfect Git diffs.
2. **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`.
3. **Compile to SQL:** Spawn compiles your templates and pinned components into standard SQL transactions.
> See it in action in the [Tutorial](https://docs.spawn.dev/getting-started/magic/).
---
## 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](https://docs.spawn.dev/getting-started/magic/) | [Templating](https://docs.spawn.dev/reference/templating/)
### ๐งช Integration Testing Framework
Spawn includes a native testing harness designed for SQL.
- **Macros:** Use [Minijinja](https://github.com/mitsuhiko/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 `expected` file.
> Docs: [Tutorial: Testing](https://docs.spawn.dev/getting-started/magic/) | [Test Macros](https://docs.spawn.dev/recipes/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.
```toml
# spawn.toml
[databases.prod]
command = {
kind = "provider",
provider = ["gcloud", "compute", "ssh", "--dry-run", ...],
append = ["psql", ...]
}
```
> Docs: [Manage Databases](https://docs.spawn.dev/guides/manage-databases/) | [Configuration](https://docs.spawn.dev/reference/config/)
---
## 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`_
```sql
CREATE OR REPLACE FUNCTION get_full_name(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`_
```sql
BEGIN;
CREATE TABLE users (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.
```toml
# migrations/20260101-add-users/lock.toml
pin = "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](https://docs.spawn.dev/reference/ci-cd/)
**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](https://docs.spawn.dev/reference/roadmap) for detailed tracking)_
---
## Documentation
Full documentation, recipes, and configuration guides are available at:
### [๐ docs.spawn.dev](https://docs.spawn.dev)
## Contributing
We welcome contributions! Please read [CONTRIBUTING.md](CONTRIBUTING.md) before opening a PR. Note that this project requires signing a CLA.