Project Structure

your-project/
├── api.yaml                 # Endpoint definitions (source of truth)
├── api/
│   └── index.go             # Vercel serverless entry point
├── cmd/
│   ├── gofire/main.go       # CLI tool
│   └── server/main.go       # Local server entry point
├── config/
│   ├── env.go               # Environment config
│   └── version.go           # Version constant
├── handlers/                # Or pkg/handler with gofire gen --handlers-dir pkg/handler
│   ├── registry.go          # Register/Get; handlers auto-register via init()
│   ├── health.go            # Built-in health handler
│   ├── root.go              # Built-in root page
│   └── *.go                 # Generated handler stubs
├── cache/
│   ├── cache.go             # Cache interface
│   └── upstash.go           # Upstash Redis implementation
├── middleware/
│   └── firebase.go          # Firebase Auth middleware
├── server/                  # Or pkg/server with gofire gen --server-dir pkg/server
│   └── server.go            # Chi router (generated by gofire gen)
├── internal/
│   ├── scaffold/            # Code generation engine
│   └── yaml/                # api.yaml parser
├── vercel.json
├── .env.example
└── go.mod

Handler registry

Generated handlers call init() { Register("Name", Name) } so they are auto-registered. The server loads api.yaml at startup and wires routes via handlers.Get(name). For custom handlers with dependency injection, call handlers.Register("MyHandler", myHandler) before the server starts.

Custom layouts

Add to .gofire.yaml (project root) or api.yaml. Then gofire gen uses these paths without flags:

output:
  serverDir: pkg/server
  handlersDir: pkg/handler

Resolution: CLI flags > .gofire.yaml > api.yaml output > default. See CLI reference.