Multiplayer party games that bring people together through shared thinking.
- Go - Server
- templ - Type-safe HTML templates
- HTMX - Frontend interactivity (coming soon)
- Tailwind CSS - Styling
- PostgreSQL - Database
- Air - Hot reload for development
- Go 1.25+
- Docker (for PostgreSQL)
- Tailwind CSS CLI - download the standalone binary for your platform and add to PATH as
tailwindcss
# Copy environment config
cp .env.example .env.local
# Start PostgreSQL
make db-up
# Run migrations
make migrate
# Build CSS
make css
# Start dev server with hot reload
make devOpen http://localhost:3000 to see the app.
| Command | Description |
|---|---|
make dev |
Start server with hot reload |
make run |
Run server directly |
make build |
Build production binary |
make templ |
Generate templ templates |
make css |
Build Tailwind CSS |
make css-watch |
Watch and rebuild CSS |
make db-up |
Start PostgreSQL container |
make db-down |
Stop PostgreSQL container |
make migrate |
Run database migrations |
make clean |
Remove build artifacts |
mindmeld/
├── cmd/server/main.go # Server entrypoint
├── templates/ # templ templates (*.templ source files)
├── static/css/ # Tailwind CSS
├── tools.go # Pinned tool versions
├── Makefile # Build commands
├── .air.toml # Hot reload config
├── docker-compose.yml # Local dev PostgreSQL
└── Dockerfile # Production build
| File | Purpose | When to use |
|---|---|---|
docker-compose.yml |
Local Postgres only | make db-up for local dev with hot reload |
Dockerfile |
Production app build | DO App Platform, or test locally with docker build |
Why separate? Local dev runs Go directly with Air for hot reload. The Dockerfile is for production builds. Combining them would sacrifice hot reload for no benefit.
| Variable | Description |
|---|---|
DATABASE_URL |
PostgreSQL connection string |
PORT |
Server port (default: 8080) |
Trivia question generation can use OpenRouter when configured. If these vars are not set, the app falls back to the local question generator.
| Variable | Description |
|---|---|
OPEN_ROUTER_KEY |
Required for live AI question generation via OpenRouter |
AI_QUESTION_ASSIST_PROVIDER |
Optional explicit provider selector. Set to openrouter to force OpenRouter |
OPEN_ROUTER_MODEL |
Optional model override. Current default is google/gemini-3.1-pro-preview |
OPEN_ROUTER_HTTP_REFERER |
Optional but recommended app/site URL sent to OpenRouter |
OPEN_ROUTER_TITLE |
Optional display name sent to OpenRouter. Defaults to Mindmeld |
Local example:
AI_QUESTION_ASSIST_PROVIDER=openrouter
OPEN_ROUTER_KEY=your-openrouter-key
OPEN_ROUTER_MODEL=google/gemini-3.1-pro-preview
OPEN_ROUTER_HTTP_REFERER=http://localhost:3000
OPEN_ROUTER_TITLE=MindmeldDeploys via Dockerfile. The Dockerfile handles all code generation (templ, sqlc, Tailwind) at build time, so generated files are not committed to git.
Test the Docker build locally:
# Build the image
docker build -t mindmeld .
# Run it (with local Postgres via docker-compose)
make db-up
docker run -p 8080:8080 -e DATABASE_URL="postgres://mindmeld:mindmeld@host.docker.internal:5432/mindmeld" mindmeldDO App Platform setup:
- Connect your GitHub repo
- DO auto-detects the Dockerfile
- Add a managed Postgres database
- Set
DATABASE_URLenv var (auto-injected from managed Postgres) - If you want live AI trivia generation in production, set:
OPEN_ROUTER_KEYAI_QUESTION_ASSIST_PROVIDER=openrouter(optional, but explicit)OPEN_ROUTER_MODEL=google/gemini-3.1-pro-previewif you want to pin the current defaultOPEN_ROUTER_HTTP_REFERER=https://your-production-domainOPEN_ROUTER_TITLE=Mindmeld
- HTTP Port:
8080
If OPEN_ROUTER_KEY is not configured in production, trivia AI assist still works through the built-in local fallback generator.
Run migrations against production DB after deploy (run goose directly to avoid .env.local override):
go run github.com/pressly/goose/v3/cmd/goose -dir migrations postgres "your-prod-connection-string" up