Forge is a comprehensive Go framework and CLI tool for building production-ready microservices with standardized patterns.
Forge consists of two repositories:
- forge (
github.com/dosanma1/forge) - Reusable Go library with standardized patterns - forge-cli (
github.com/dosanma1/forge-cli) - CLI tool for scaffolding and code generation
git clone https://github.com/dosanma1/forge-cli
cd forge-cli
make installForge requires several tools to be installed depending on which features you want to use:
Bazel - Build system
- macOS:
brew install bazelisk - Linux:
wget https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-amd64 chmod +x bazelisk-linux-amd64 sudo mv bazelisk-linux-amd64 /usr/local/bin/bazel
- Windows:
choco install bazeliskor download from releases
Skaffold - Development & deployment orchestration
- macOS:
brew install skaffold - Linux:
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64 chmod +x skaffold sudo mv skaffold /usr/local/bin
- Windows:
choco install skaffoldor download from releases
Docker - Container runtime
- macOS: Download Docker Desktop for Mac
- Linux:
curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh
- Windows: Download Docker Desktop for Windows
Helm - Kubernetes package manager
- macOS:
brew install helm - Linux:
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash - Windows:
choco install kubernetes-helm
kubectl - Kubernetes CLI
- macOS:
brew install kubectl - Linux:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" chmod +x kubectl sudo mv kubectl /usr/local/bin/ - Windows:
choco install kubernetes-cli
Go - Go programming language
Node.js - JavaScript runtime (includes npm)
- macOS:
brew install node - Linux:
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - sudo apt-get install -y nodejs - Windows: Download installer from nodejs.org
Google Cloud SDK - For GKE, Cloud Run, and GCR
- macOS:
brew install --cask google-cloud-sdk - Linux:
curl https://sdk.cloud.google.com | bash exec -l $SHELL
- Windows: Download installer from cloud.google.com/sdk
After installation:
gcloud auth login
gcloud auth configure-dockerFirebase CLI - For Firebase deployments
- All platforms:
npm install -g firebase-tools
After installation:
firebase loginAngular CLI - For Angular applications
npm install -g @angular/cliNestJS CLI - For NestJS services
npm install -g @nestjs/cliprotoc - Protocol buffer compiler
- macOS:
brew install protobuf - Linux:
sudo apt-get install -y protobuf-compiler
- Windows: Download from protobuf releases
OR buf - Modern protobuf tool (recommended alternative)
- macOS:
brew install bufbuild/buf/buf - Linux:
curl -sSL "https://github.com/bufbuild/buf/releases/latest/download/buf-$(uname -s)-$(uname -m)" -o /usr/local/bin/buf chmod +x /usr/local/bin/buf - Windows: Download from buf releases
Kind - Kubernetes in Docker
- macOS:
brew install kind - Linux:
curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64 chmod +x ./kind sudo mv ./kind /usr/local/bin/kind
- Windows:
choco install kind
Install all tools at once on macOS:
# Essential tools
brew install bazelisk skaffold helm kubectl go node
# Docker Desktop (manual installation required)
# Download from https://www.docker.com/products/docker-desktop
# Cloud tools
brew install --cask google-cloud-sdk
npm install -g firebase-tools
# Framework CLIs
npm install -g @angular/cli @nestjs/cli
# Protocol buffers
brew install protobuf
# OR
brew install bufbuild/buf/buf
# Local Kubernetes
brew install kind
# Authenticate with cloud providers
gcloud auth login
gcloud auth configure-docker
firebase login# Essential tools
# Bazel
wget https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-amd64
chmod +x bazelisk-linux-amd64
sudo mv bazelisk-linux-amd64 /usr/local/bin/bazel
# Skaffold
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64
chmod +x skaffold
sudo mv skaffold /usr/local/bin
# Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Helm
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/
# Go (visit go.dev/dl for latest version)
wget https://go.dev/dl/go1.21.5.linux-amd64.tar.gz
sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.21.5.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
# Node.js
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt-get install -y nodejs
# Cloud tools
curl https://sdk.cloud.google.com | bash
exec -l $SHELL
npm install -g firebase-tools
# Framework CLIs
npm install -g @angular/cli @nestjs/cli
# Protocol buffers
sudo apt-get install -y protobuf-compiler
# Kind
curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
# Authenticate
gcloud auth login
gcloud auth configure-docker
firebase loginAfter installation, verify all tools are available:
bazel version
skaffold version
docker --version
helm version
kubectl version --client
go version
node --version
npm --version
gcloud --version
firebase --version
ng version
nest --version
protoc --version # or: buf --version
kind version# Interactive mode
forge new
# With options
forge new my-project \
--github-org=mycompany \
--docker-registry=gcr.io/mycompany \
--gcp-project=my-gcp-projectcd my-project
forge generate service user-service
cd backend/services/user-service
go mod tidy
go run main.goimport "github.com/dosanma1/forge/pkg/http"
// Create router
router := http.NewRouter()
// Add middleware
router.Use(http.LoggingMiddleware(logger))
router.Use(http.RecoveryMiddleware(logger))
// Register routes
router.GET("/users", getUsersHandler)
router.POST("/users", createUserHandler)
// Route groups
v1 := router.Group("/api/v1")
v1.GET("/users/:id", getUserHandler)
// Start server
router.Start(":8080")import "github.com/dosanma1/forge/pkg/log"
// Create logger
logger := log.NewLogger("my-service", log.LevelInfo)
// Log with context
logger.Info("User created", "user_id", userID)
logger.Error("Failed to create user", "error", err)
// Add logger to context
ctx = log.ToContext(ctx, logger)
// Retrieve from context
logger = log.FromContext(ctx)import (
"github.com/dosanma1/forge/pkg/database"
"gorm.io/gorm"
)
// Generic repository pattern
type User struct {
gorm.Model
Name string
Email string
}
type UserRepository struct {
database.BaseRepository[User]
}
func NewUserRepository(db *gorm.DB) *UserRepository {
return &UserRepository{
BaseRepository: database.NewBaseRepository[User](db),
}
}
// Use repository
repo := NewUserRepository(db)
users, err := repo.FindAll(ctx)
user, err := repo.FindByID(ctx, 1)
err = repo.Create(ctx, &user)import "github.com/dosanma1/forge/pkg/observability"
// Initialize tracer
tracer := observability.NewTracer("my-service", "1.0.0")
defer tracer.Shutdown(ctx)
// Create spans
ctx, span := tracer.StartSpan(ctx, "operation-name")
defer span.End()
// Add events and errors
span.AddEvent("Processing started")
span.RecordError(err)import "github.com/dosanma1/forge/pkg/auth"
// JWT middleware
validator := &MyTokenValidator{}
router.Use(auth.JWTMiddleware(validator, logger))
// Role-based access
router.Use(auth.RequireRole("admin"))
// Get user from context
user := auth.UserFromContext(ctx)import "github.com/dosanma1/forge/pkg/config"
// Environment-based config
cfg := config.NewEnvConfig("MYSERVICE")
// Get values with defaults
port := cfg.GetInt("PORT", 8080)
debug := cfg.GetBool("DEBUG", false)
timeout := cfg.GetDuration("TIMEOUT", time.Second*30)
hosts := cfg.GetStringSlice("HOSTS", []string{"localhost"})import "github.com/dosanma1/forge/pkg/testing"
func TestAPI(t *testing.T) {
// Create test server
server := testing.NewTestServer(router)
defer server.Close()
// Make requests
resp := server.GET("/api/users")
// Assertions
testing.AssertStatusCode(t, resp, 200)
testing.AssertJSON(t, resp, map[string]interface{}{
"count": 10,
})
}
// Table-driven tests
tests := []testing.TestCase{
{
Name: "Valid input",
Input: "test",
Expected: true,
},
{
Name: "Invalid input",
Input: "",
Expected: false,
},
}
testing.RunTableTests(t, tests, func(tc testing.TestCase) {
result := validate(tc.Input.(string))
assert.Equal(t, tc.Expected, result)
})Create a new workspace:
forge new my-project
forge new my-project --github-org=mycompanyGenerate a Go microservice:
forge generate service user-service
forge g service payment-serviceGenerate an Angular application:
forge generate frontend admin-appClean build artifacts and caches:
# Clean project caches (.forge, .angular) and run bazel clean --expunge
forge clean --cache
# Deep clean including global caches (with confirmation)
forge clean --deepAdd HTTP handler to a service:
forge add handler user-service /api/usersAdd middleware to a service:
forge add middleware user-service auth
forge add middleware user-service loggingmy-project/
├── forge.json # Workspace configuration
├── backend/
│ └── services/
│ └── user-service/
│ ├── main.go
│ ├── go.mod
│ ├── Dockerfile
│ └── README.md
├── frontend/
│ └── projects/
│ └── admin-app/
├── infra/
│ ├── helm/
│ └── cloudrun/
├── shared/ # Shared libraries
└── docs/
{
"version": "1",
"workspace": {
"name": "my-project",
"forgeVersion": "1.0.0",
"github": {
"org": "mycompany"
},
"docker": {
"registry": "gcr.io/mycompany"
},
"gcp": {
"projectId": "my-gcp-project"
},
"kubernetes": {
"namespace": "production"
}
},
"projects": {
"user-service": {
"name": "user-service",
"type": "go-service",
"root": "backend/services/user-service",
"tags": ["backend", "service"]
}
}
}go- Go microservicenestjs- NestJS microserviceangular- Angular application
Forge locks framework versions in forge.json to ensure consistent, reproducible builds across your team and CI/CD pipelines.
When you create a new workspace, Forge initializes locked versions in forge.json:
{
"workspace": {
"toolVersions": {
"angular": "21.0.2",
"go": "1.23.4",
"nestjs": "11.1.9",
"node": "24.11.1",
"bazel": "7.4.1"
}
}
}- Stability - Prevents
@latestfrom introducing breaking changes unexpectedly - Bazel Compatibility - Ensures framework versions work with Bazel build rules
- Team Consistency - Everyone builds with same versions
- Reproducibility - Builds work identically 6 months later
Forge uses Dependabot to monitor your project dependencies:
- Dependabot creates PRs for
go.modandpackage.jsonupdates - Review and merge Dependabot PRs after testing
- Manually sync versions to
forge.jsontoolVersionssection - Run
forge buildto validate compatibility
See Version Compatibility Matrix for tested combinations.
Forge uses project-local caches (like Angular's .angular/cache/):
# Clean project caches and Bazel artifacts
forge clean --cache
# Deep clean (includes global caches: ~/.cache/bazel, ~/go/pkg/mod/cache, ~/.npm)
forge clean --deepCaches are stored in:
.forge/cache/- Template cache (gitignored).angular/cache/- Angular build cache (gitignored)~/.cache/bazel- Bazel global cache
- Standardization - One way to do things, consistently across all services
- Simplicity - Use standard library when possible, minimal dependencies
- Type Safety - Leverage Go generics for type-safe patterns
- Observability - Built-in logging, tracing, and metrics
- Developer Experience - Fast, intuitive CLI with sensible defaults
See the examples/ directory in the forge repository for complete working examples.
cd forge-cli
go build -o forge cmd/forge/main.go
./forge --help# Test forge library
cd forge
go test ./...
# Test forge-cli
cd forge-cli
go test ./...Current version: 1.0.0
MIT License - see LICENSE file for details
