# Wild Workouts: a Go DDD example you can run and refactor

> ThreeDotsLabs/wild-workouts-go-ddd-example is a teaching application for DDD, Clean Architecture and CQRS in Go, built as a serverless Google Cloud Run and Firebase project. It is best read as a refactoring series with runnable code, not as a starter template.

**ThreeDotsLabs/wild-workouts-go-ddd-example** — Go DDD example application. Complete project to show how to apply DDD, Clean Architecture, and CQRS by practical refactoring.

- Repository: https://github.com/ThreeDotsLabs/wild-workouts-go-ddd-example
- Website: https://threedots.tech
- Stars: 6,462 · Forks: 587
- Language: Go
- License: MIT
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/threedotslabs-wild-workouts-go-ddd-example

## What Wild Workouts is for, and who it is not for

Wild Workouts is an example Go project that exists to demonstrate domain-driven design by refactoring. The README describes it as an "example Go DDD" project created to show how to build Go applications that are easy to develop and maintain over the long term, and it states plainly that the refactoring process is in progress. That framing matters more than any feature list: the repository is a companion to a series of articles, and each article is tied to a release tag, from v1.0 for the initial serverless setup through v2.7 for running the test suite in the CI/CD pipeline.

The domain is a training scheduler. Trainers publish availability, users book sessions, and the code is split into trainer, trainings and users services, each with its own HTTP or gRPC entry point. If you are learning how a Go codebase moves from a tangled first version to separated layers, the release tags give you checkpoints to diff. If you want a library to drop into an existing service, this is the wrong repository. It is an application, not a framework.

## How the Go DDD project structure is actually laid out

The top-level layout separates contracts, code, infrastructure and frontend. The README lists api/ for OpenAPI and gRPC definitions, docker/ for Dockerfiles, internal/ for application code, terraform/ for infrastructure, web/ for the JavaScript frontend, and Taskfile.yml for deployment and development tasks. The go.mod declares the module as github.com/ThreeDotsLabs/wild-workouts-go-ddd-example and targets Go 1.25.0, with oapi-codegen registered as a tool dependency, which fits the OpenAPI-first workflow implied by the api/ directory.

Running the project means running several processes. docker-compose.yml defines the name wild-workouts and services including web, trainer-http, trainer-grpc, trainings-http and users-http. The trainer service is started twice from the same image, distinguished by the SERVER_TO_RUN environment variable set to http or grpc, and the SERVICE variable set to trainer or trainings. Ports are bound to localhost: 8080 for the web frontend, 3000 for trainer-http, 3010 for trainer-grpc and 3001 for trainings-http. Each application service loads .env and depends on a firestore service, so the data layer is Firestore rather than a database you host yourself. That is the central architectural constraint: the example teaches DDD patterns on top of a managed Google backend, and the composition root is wired accordingly.

## Running it locally with docker-compose up

The README's local instructions are one command. From the repository root, the Compose file builds the web image and the application image, mounts internal/ into the container, and starts the services against the firestore container.

```bash
docker-compose up
```

The README shows the expected output: the web container compiles and reports "App running at: - Local: http://localhost:8080/". It also warns that the development build is not optimized and that a production build requires yarn build. Because the services read .env, that file has to be present before the stack starts; the repository ships .env, .env.test and .env.e2e at the top level.

For deployment, the README points at the terraform directory and a make target that prompts for parameters.

```bash
cd terraform/
make
```

The prompts ask for project, user, billing_account, region (default europe-west1) and firebase_location (default europe-west). After the run, the README says you must enable the Email/Password provider in the Firebase console at https://console.firebase.google.com/u/0/project/[your-project]/authentication/providers, and notes that the subscription plan can be downgraded to Spark, which the README calls completely free and sufficient for running the project.

## Where the example gets in your way

The dependency on Firestore and Firebase Authentication is the biggest practical limitation. The README's own article list includes a piece titled "You should not build your own authentication. Let Firebase do it for you", so the authentication boundary is deliberately delegated to a managed service. If your organization cannot use Firebase, or if you need to run the whole thing offline without a Google project, the local Compose stack still expects a firestore container and the deployed path expects a billing account. You will be adapting infrastructure, not just reading code.

Status is the second issue. The last release is v2.7, dated 2021-04-01, and it is described as running the test suite in the CI/CD pipeline. The README says more articles are on the way and that the refactoring process is in progress, so any layer you copy may be mid-refactor. Treat the tagged releases as the stable reference points and the master branch as work in progress. Finally, the README does not document rollback for the Terraform deployment, so if you deploy to a real Google Cloud project, plan teardown yourself.

## How it differs from a general-purpose Go DDD template

A generic Go DDD template gives you folders and interfaces and lets you choose the infrastructure. Wild Workouts makes the opposite trade: it commits to a concrete stack, Google Cloud Run plus Firebase plus Firestore plus Terraform, and shows the DDD and CQRS patterns inside that stack. The value is in seeing decisions made rather than listed. The cost is that the patterns are entangled with the platform, so extracting the domain layer means replacing Firestore repositories and the Firebase auth middleware.

If you want the patterns without the platform, a project like the Go standard library's own examples or a lighter hexagonal-architecture sample will teach the same layering with fewer moving parts. What Wild Workouts adds that those usually lack is the refactoring narrative: the releases map to articles, and the articles explain why a change was made. That is a different kind of learning material, closer to a guided diff than to a scaffold.

## Licence and the cost of keeping up

The repository is MIT licensed, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. That is a permissive licence, but it covers the example code only; the Google Cloud services the project deploys to are billed separately, and the README notes the Firebase plan is set to Blaze by default, with Spark described as free and sufficient. Check the current terms of those services yourself, since the README does not restate them.

Upgrade cost is mostly about drift. The module targets Go 1.25.0, and the dependency list in go.mod is dominated by indirect entries plus oapi-codegen as a tool, so regenerating API code is part of the workflow rather than an optional extra. Because the last release is v2.7 from 2021-04-01, you should expect to update dependencies and re-verify the Terraform before deploying. The README does not describe a migration path between releases, so diffs between tags are the documentation.

## Conclusion

Adopt Wild Workouts if you want to read Go code that shows DDD, Clean Architecture and CQRS being introduced step by step, and you are willing to run it with docker-compose up before judging the structure. Do not adopt it as a production skeleton: the README calls the refactoring process in progress, the last release is v2.7 from 2021-04-01, and the application depends on Firestore, Firebase Auth and Cloud Run. Before committing, verify that the .env file and the Firestore dependency in docker-compose.yml match your own infrastructure plans, and check whether the article series has moved past the CQRS step you intend to copy.

## FAQ

### How do I run Wild Workouts locally?

The README gives one command, docker-compose up, run from the repository root. The web frontend then reports App running at http://localhost:8080/, and the application services start against the firestore container using the .env file.

### Does Wild Workouts require a Google Cloud project?

The README's deployment path uses the terraform directory and a make target that prompts for a Google Cloud project, billing account, region and Firebase location, then asks you to enable the Email/Password provider in the Firebase console. The local docker-compose stack also depends on a firestore service.

### What is the licence for wild-workouts-go-ddd-example?

The repository is MIT licensed. That covers the example code; the Google Cloud and Firebase services it deploys to are separate and the README notes the Firebase plan is set to Blaze by default, with Spark described as free and sufficient.

## Sources

- [License: MIT](https://github.com/ThreeDotsLabs/wild-workouts-go-ddd-example/blob/master/LICENSE)
- [Project website](https://threedots.tech)
- [README](https://github.com/ThreeDotsLabs/wild-workouts-go-ddd-example/blob/master/README.md)
- [Releases](https://github.com/ThreeDotsLabs/wild-workouts-go-ddd-example/releases)
- [ThreeDotsLabs/wild-workouts-go-ddd-example on GitHub](https://github.com/ThreeDotsLabs/wild-workouts-go-ddd-example)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/threedotslabs-wild-workouts-go-ddd-example
