My Go Project Starter Kit

Been thinking about my default Go project setup. Here’s what I’m settling on.

The Stack

Database: sqlc

Tests: gotests

Router: TBD

Why sqlc

-- queries.sql
-- name: GetUser :one
SELECT * FROM users WHERE id = $1;

-- name: ListUsers :many
SELECT * FROM users ORDER BY created_at DESC;

Generate Go code:

sqlc generate

Get type-safe functions:

user, err := queries.GetUser(ctx, userID)
users, err := queries.ListUsers(ctx)

No reflection, no ORM complexity. Just plain SQL and generated Go.

Why gotests

# Generate tests for a function
gotests -w -all myfile.go

Creates table-driven test templates:

func TestMyFunc(t *testing.T) {
    tests := []struct {
        name string
        args args
        want want
    }{
        // TODO: Add test cases
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            // test code
        })
    }
}

Saves me from typing the same structure every time.

What About Go Wire?

Looked into Wire for dependency injection. Conclusion: too complicated for most projects.

Good for:

Overkill for:

I’ll stick with simple constructors:

func NewServer(db *sql.DB, logger *log.Logger) *Server {
    return &Server{
        db:     db,
        logger: logger,
    }
}

Manual DI is fine for 90% of projects.

The Template Plan

Thinking about creating a go-starter repo with:

Not done yet, but that’s the idea.

For now, these tools (sqlc + gotests) are my go-to for new projects.