Improving DX by moving inline migrations into versioned SQL files

Starting today, I want to spend some time improving the developer experience of Uploy so the project becomes easier to maintain as it grows…

The first thing I worked on was extracting the inline migrations into proper versioned SQL files using the 3rd party package goose. You can see the changes in this commit.

Before this change, migrations were executed automatically when I ran the Go server with go run main.go. That was still fine in the early stage because it was convenient… but over time it started to feel a bit too coupled. Running the app server and running database migrations are related, but they are not really the same responsibility.

So I separated them.

Now the migration flow is more explicit. Instead of depending on server startup, I can just run make migrate-up whenever I want to apply schema changes. It feels cleaner, more predictable, and easier to reason about, especially if later I want different environments or deployment steps.

This was a small DX improvement on the surface, but I think it matters. One insight I keep noticing in this project is that early convenience can quietly turn into maintenance friction later. Moving migrations into versioned SQL files gives the project a clearer structure, and I think that will help a lot as Uploy keeps growing.

© 2026 Wahyu Syahputra. All rights reserved.