Skip to main content
The Go React Scaffold provides a streamlined development workflow using Make commands, Air for live reload, and organized project structure.

Prerequisites

Ensure you have the following installed:
  • Go 1.21 or later
  • Make (usually pre-installed on macOS/Linux)
  • Air for live reload (optional, auto-prompted)

Makefile Commands

All backend development commands are run from the backend/ directory. The Makefile provides the following targets:

Build

make build
Compiles the Go application to a binary named main in the current directory.
  • Command executed: go build -o main main.go
  • Output: ./main executable
  • Default target: Running make alone executes make build

Run

make run
Runs the application directly without creating a binary.
  • Command executed: go run main.go
  • Useful for quick testing
  • No build artifacts created
  • Application starts on port defined in PORT env var
Expected output:
Pinged your deployment. You successfully connected to MongoDB!

Live Reload (Watch)

make watch
Starts Air for automatic rebuilding and reloading when files change. This is the recommended way to run the application during development. Features:
  • Detects changes to .go, .tpl, .tmpl, .html, .templ files
  • Automatically rebuilds using make build
  • Restarts the application
  • Excludes test files and temporary directories
  • Logs build errors to build-errors.log
Auto-installation: If Air is not installed, the command will prompt you to install it:
Go's 'air' is not installed on your machine. Do you want to install it? [Y/n]
Manual Air installation:
go install github.com/cosmtrek/air@latest

Test

make test
Runs all tests in the tests/ directory.
  • Command executed: go test ./tests -v
  • Verbose output enabled (-v flag)
The project currently has no tests. When adding tests, create them in the backend/tests/ directory following Go’s testing conventions.

Docker Services

# Start MongoDB and other services
make docker-run

# Stop services
make docker-down
See Docker Setup for detailed information.

Clean

make clean
Removes the compiled binary.
  • Command executed: rm -f main
  • Use after builds to clean up artifacts

Air Configuration

The project includes .air.toml configuration for customized live reload behavior:
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"

[build]
  bin = "./main"
  cmd = "make build"
  delay = 1000
  exclude_dir = ["assets", "tmp", "vendor", "testdata"]
  exclude_regex = ["_test.go", ".*_templ.go"]
  include_ext = ["go", "tpl", "tmpl", "html", "templ"]
  kill_delay = "0s"
  log = "build-errors.log"
Key settings:
  • Uses make build for compilation
  • 1 second delay before rebuild
  • Excludes test files and generated templ files
  • Logs errors to build-errors.log
  • Watches .go and template files

Typical Development Flow

  1. Start services:
    cd backend
    make docker-run
    
  2. Start the application with live reload:
    make watch
    
  3. Make code changes - Air automatically rebuilds and restarts
  4. Run tests:
    # In another terminal
    make test
    
  5. Clean up:
    make docker-down
    make clean
    

Project Structure

Understanding the structure helps with development:
backend/
├── main.go           # Entry point, server setup
├── auth/             # Authentication handlers & JWT
├── users/            # User models and logic
├── configs/          # Database & environment config
│   ├── db.go         # MongoDB connection
│   └── env.go        # Environment variables
├── integrations/     # External API integrations
│   ├── paypack.go    # Payment gateway
│   ├── useplunk.go   # Email service
│   └── telegram-bot.go # Notifications
├── utils/            # Utility functions
├── tests/            # Test files
├── Makefile          # Development commands
├── .env              # Environment variables (create from .env.example)
├── .air.toml         # Air configuration
└── go.mod            # Go dependencies

Running Specific Tests

When you add tests, you can run specific test files or functions:
# Run tests in a specific package
go test ./auth -v

# Run a specific test function
go test ./auth -run TestUserLogin -v

# Run all tests with coverage
go test ./... -cover

# Generate coverage report
go test ./... -coverprofile=coverage.out
go tool cover -html=coverage.out

Code Formatting

Always format code before committing:
# Format all Go files
gofmt -w .

# Or use goimports (better, organizes imports too)
go install golang.org/x/tools/cmd/goimports@latest
goimports -w .

Dependency Management

Manage Go modules:
# Add a new dependency (automatically updates go.mod)
go get github.com/some/package

# Update dependencies
go get -u ./...

# Tidy up go.mod and go.sum
go mod tidy

# Verify dependencies
go mod verify

# View dependency graph
go mod graph

Environment Setup

  1. Copy environment template:
    cp .env.example .env
    
  2. Configure required variables:
    APP_ENV=development
    MONGODB_URI=mongodb://localhost:27017
    PORT=8080
    SESSION_KEY=$(openssl rand -base64 32)
    
  3. Start development:
    make docker-run
    make watch
    
See Environment Variables for complete configuration reference.

Debugging

Using Delve Debugger

Install Delve:
go install github.com/go-delve/delve/cmd/dlv@latest
Debug the application:
dlv debug main.go
Set breakpoints:
(dlv) break main.main
(dlv) break auth.HandleUserLogin
(dlv) continue

Log Debugging

The application uses standard Go logging:
import "log"

log.Printf("Debug: %+v", variable)
log.Fatalf("Fatal error: %v", err)  // Exits application
View Air build errors:
tail -f build-errors.log

Common Issues

Port Already in Use

Change the PORT in your .env file:
PORT=8081

Module Import Errors

Run:
go mod tidy

Air Not Rebuilding

Check:
  1. .air.toml exists and is valid
  2. File extensions match include_ext
  3. Directory not in exclude_dir
  4. Check build-errors.log for build failures

Database Connection Failed

Ensure:
  1. Docker services are running: docker ps
  2. MONGODB_URI is correct in .env
  3. MongoDB is accessible: mongosh mongodb://localhost:27017

Performance Tips

  1. Use live reload instead of manual rebuilding
  2. Keep dependencies minimal - review go.mod regularly
  3. Enable connection pooling for database clients
  4. Use context timeouts for database operations
  5. Profile your application:
    go test -cpuprofile cpu.prof -memprofile mem.prof -bench .
    go tool pprof cpu.prof
    

Git Workflow

Before committing:
# Format code
gofmt -w .

# Run tests
make test

# Clean build artifacts
make clean

# Stage and commit
git add .
git commit -m "feat: your feature description"
Never commit:
  • .env files (should be in .gitignore)
  • Build artifacts (main binary)
  • Temporary files (tmp/ directory)
  • Log files (build-errors.log)

Next Steps

Build docs developers (and LLMs) love