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
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
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)
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
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
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
-
Start services:
cd backend
make docker-run
-
Start the application with live reload:
-
Make code changes - Air automatically rebuilds and restarts
-
Run tests:
# In another terminal
make test
-
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
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
-
Copy environment template:
-
Configure required variables:
APP_ENV=development
MONGODB_URI=mongodb://localhost:27017
PORT=8080
SESSION_KEY=$(openssl rand -base64 32)
-
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:
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:
Common Issues
Port Already in Use
Change the PORT in your .env file:
Module Import Errors
Run:
Air Not Rebuilding
Check:
.air.toml exists and is valid
- File extensions match
include_ext
- Directory not in
exclude_dir
- Check
build-errors.log for build failures
Database Connection Failed
Ensure:
- Docker services are running:
docker ps
MONGODB_URI is correct in .env
- MongoDB is accessible:
mongosh mongodb://localhost:27017
- Use live reload instead of manual rebuilding
- Keep dependencies minimal - review
go.mod regularly
- Enable connection pooling for database clients
- Use context timeouts for database operations
- 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