1 - Contributing

This is a rendered copy of the repository CONTRIBUTING.md for convenient access via the documentation site.

This is a rendered copy of the repository CONTRIBUTING.md for convenient access via the documentation site.

Overview

Go Micro welcomes contributions of all kinds: code, documentation, examples, and plugins.

Quick Start

git clone --depth 1 https://github.com/micro/go-micro.git
cd go-micro
go mod download
go test ./...

Process

  1. Fork and create a feature branch
  2. Make focused changes with tests
  3. Run linting and full test suite
  4. Open a PR describing motivation and approach

Commit Format

Use conventional commits:

feat(registry): add consul health check
fix(broker): prevent reconnect storm

Testing

Run unit tests:

go test ./...

Run race/coverage:

go test -race -coverprofile=coverage.out ./...

Plugins

Place new plugins under the appropriate interface directory (e.g. registry/consul/). Include tests and usage examples. Document env vars and options.

Documentation

Docs live in internal/website/docs/. Add new examples under internal/website/docs/examples/.

Help & Questions

Use GitHub Discussions or the issue templates. For general usage questions open a “Question” issue.

Full Guide

For complete details see the repository copy of the guide on GitHub.

2 - Roadmap

Go Micro is a framework for building agents and services in Go. An agent is a distributed system — it discovers services, calls them, holds state, and recovers from failure — so building an agent is b

Go Micro is a framework for building agents and services in Go. An agent is a distributed system — it discovers services, calls them, holds state, and recovers from failure — so building an agent is building a service. The roadmap has two jobs: make agentic development excellent, and make the developer experience around it excellent. Nothing else.

Where we are (v6)

The foundation is in place:

  • Services — register, discover, RPC, events; every endpoint is automatically an MCP tool.
  • Agents — a model with memory and tools that manages services, with plan, delegate, and guardrails (MaxSteps, LoopLimit, ApproveTool) built in, plus tool-execution middleware (WrapTool) and run metadata.
  • Flows — durable, event-driven workflows: ordered steps that checkpoint and resume after a crash.
  • Interop — the MCP gateway (services as tools) and the A2A gateway (agents as agents, both directions, including A2A streaming, push notifications, and multi-turn continuation), both generated from the registry; x402 for paid tools.
  • Secure by default — TLS verification on, state scoped per component.

Principles

These constrain everything below:

  1. Build into what people run, never a separate product. No hosted platform, no enterprise edition. Improvements go deeper into the framework, not beside it.
  2. CLI-first. The CLI is the experience. Any UI must be genuinely good and earn its place; bloat gets trimmed, not maintained.
  3. The getting-started flow is a contract. 0→1 (scaffold → run → call) and 0→hero (the ~10 steps to a working multi-agent system) must always work, and every change is checked against them.
  4. Interaction is as important as running. Talking to an agent, inspecting runs and history — end to end, not just “it starts.”
  5. Battle-tested. Works across every provider, fails safely, and is observable.

Now — hardening (“functional on every level”)

The priority is that what exists works everywhere, under real conditions.

  • Cross-provider conformance. Each of the seven providers implements its own tool-call loop; today only the mock and one live provider are exercised. A suite that runs the same agent scenario (tool-calling, multi-step, plan/delegate, guardrails) across every provider, gated on keys, on a schedule.
  • Failure & resilience. Provider timeouts, rate limits, and cancellation mid-run; deadline/context propagation through the agent loop; retry and backoff at the model call.
  • The getting-started contract. Define and CI-verify the 0→1 and 0→hero flows so they can’t silently break.

Next — agentic depth

  • Streaming. Broaden provider-backed ai.Stream coverage and keep chat plus A2A message/stream working end to end for real chat and long-task UX.
  • Agent observability. Wire the new RunInfo into OpenTelemetry spans so a run — steps, tool calls, delegation — is traceable. This is also what anyone running it in production will need.

Later

  • Memory management — summarization and retrieval (RAG) beyond a fixed buffer.
  • Human-in-the-loop — broaden pause/resume UX around input-required runs and approvals.
  • A2A — richer live-stream reconnection (tasks/resubscribe) and input-required handoffs.

Developer experience (ongoing)

  • The CLI inner loop — scaffold → run → chat → inspect (runs/history) → deploy, made seamless. This is the main lever for “dramatically improve the experience.”
  • UI discipline — keep only high-value, well-built surfaces; trim or cut the rest. The web UI should never be a worse version of the CLI.
  • Examples & a real-world build — a maintained example that builds something real with the framework, doubling as the 0→hero reference and continuous battle-testing.
  • Docs in lockstep — the getting-started guide tracks the code on every change.

How it’s sustained

The framework is the product. It’s funded by sponsorship from the people and companies who run it — not a hosted service, not an enterprise tier, not venture funding. The model is deliberate: keep refining the framework, aligned users adopt and depend on it, and that dependence funds the work. (See Bringing an Open Source Project Back from the Dead for why.)

3 - Powered by Go Micro Badge

Documentation for Get Badge. Show your support and let others know your project is built with Go Micro!

Markdown Badges

Dark Badge

Powered by Go Micro
[![Powered by Go Micro](https://img.shields.io/badge/Powered%20by-Go%20Micro-0366d6?style=for-the-badge&logo=go&logoColor=white)](https://go-micro.dev)

Light Badge

Powered by Go Micro
[![Powered by Go Micro](https://img.shields.io/badge/Powered%20by-Go%20Micro-00ADD8?style=flat&logo=go&logoColor=white)](https://go-micro.dev)

Compact Badge

Go Micro
[![Go Micro](https://img.shields.io/badge/Go-Micro-0366d6?style=flat-square)](https://go-micro.dev)

HTML Badges

Standard HTML Badge

Powered by Go Micro
<a href="https://go-micro.dev" target="_blank">
  <img src="https://img.shields.io/badge/Powered%20by-Go%20Micro-0366d6?style=for-the-badge&logo=go&logoColor=white" alt="Powered by Go Micro">
</a>

Custom SVG Badge

Powered by Go Micro
<a href="https://go-micro.dev" style="display:inline-block;text-decoration:none;">
  <svg width="160" height="32" xmlns="http://www.w3.org/2000/svg">
    <rect width="160" height="32" rx="6" fill="#0366d6"/>
    <text x="16" y="21" font-family="system-ui,-apple-system,sans-serif" font-size="13" font-weight="600" fill="white">
      Powered by Go Micro
    </text>
  </svg>
</a>

Usage

Add one of these badges to your README.md, documentation, or website footer to show that your project uses Go Micro.

Example README

# My Awesome Project

![Project Logo](logo.png)

[![Powered by Go Micro](https://img.shields.io/badge/Powered%20by-Go%20Micro-0366d6?style=for-the-badge&logo=go&logoColor=white)](https://go-micro.dev)

My project does amazing things using Go Micro microservices framework.

## Features
- Fast and scalable
- Built with Go Micro
- Production ready

Badge Guidelines

  • Link the badge to https://go-micro.dev to help others discover Go Micro
  • Use the badge prominently in your README
  • Consider adding it to your project website footer
  • Feel free to customize the colors to match your brand

Showcase Your Project

Built something cool with Go Micro? Open an issue to get featured on our homepage!

4 - Server (optional)

The Micro server is an optional web dashboard and authenticated API gateway for production environments. It provides a secure entrypoint for discovering and interacting with services that are already

Micro Server (Optional)

The Micro server is an optional web dashboard and authenticated API gateway for production environments. It provides a secure entrypoint for discovering and interacting with services that are already running (e.g., managed by systemd via micro deploy).

micro server does not build, run, or watch services. It only discovers services via the registry and provides a UI/API to interact with them.

micro server vs micro run

micro runmicro server
PurposeLocal developmentProduction dashboard
Builds servicesYesNo
Runs servicesYes (as child processes)No (discovers already-running services)
Hot reloadYesNo
AuthenticationYes (default admin/micro)Yes (default admin/micro)
ScopesYes (/auth/scopes)Yes (/auth/scopes)
DashboardFull gateway UI with auth, scopes, agentFull dashboard with API explorer, logs, user/token management
When to useDay-to-day developmentDeployed environments, shared servers

For local development, use micro run instead.

Install

Install the CLI which includes the server command:

go install go-micro.dev/v6/cmd/micro@latest

Run

Start the server:

micro server

Then open http://localhost:8080 and log in with the default admin account (admin/micro).

Features

  • Web Dashboard — Browse registered services, view endpoints, request/response schemas
  • API Gateway — Authenticated HTTP-to-RPC proxy at /api/{service}/{method}
  • JWT Authentication — All API endpoints require a Bearer token or session cookie
  • Token Management — Generate, view, copy, and revoke JWT tokens
  • User Management — Create, list, and delete users with bcrypt-hashed passwords
  • Endpoint Scopes — Restrict which tokens can call which endpoints via /auth/scopes
  • MCP Integration — AI agent playground and MCP tools, with scope enforcement
  • Logs & Status — View service logs and status (PID, uptime) from the dashboard

Typical Production Setup

After deploying services with micro deploy:

# On your server, start the dashboard
micro server

Services managed by systemd are discovered via the registry and appear in the dashboard automatically. The server provides the authenticated API and web UI for interacting with them.

When to use it

  • You have services running in production (via systemd or otherwise) and want a web UI
  • You need authenticated API access with JWT tokens
  • You want user management and token revocation
  • You’re running a shared environment where multiple people interact with services

For CLI usage details, see the CLI documentation on GitHub.

5 - Architecture Decision Records

Documentation of architectural decisions made in Go Micro, following the ADR pattern.

What are ADRs?

Architecture Decision Records (ADRs) capture important architectural decisions along with their context and consequences. They help understand why certain design choices were made.

Planned

Core Design

  • ADR-002: Interface-First Design
  • ADR-003: Default Implementations

Service Discovery

  • ADR-005: Registry Plugin Scope

Communication

  • ADR-006: HTTP as Default Transport
  • ADR-007: Content-Type Based Codecs

Configuration

  • ADR-008: Environment Variable Support

Status Values

  • Proposed: Under consideration
  • Accepted: Decision approved
  • Deprecated: No longer recommended
  • Superseded: Replaced by another ADR

Contributing

To propose a new ADR:

  1. Number it sequentially (check existing ADRs)
  2. Follow the structure of existing ADRs
  3. Include: Status, Context, Decision, Consequences, Alternatives
  4. Submit a PR for discussion
  5. Update status based on review

ADRs are immutable once accepted. To change a decision, create a new ADR that supersedes the old one.

5.1 - Adr 001 Plugin Architecture

Microservices frameworks need to support multiple infrastructure backends (registries, brokers, transports, stores). Different teams have different preferences and existing infrastructure.

Status

Accepted

Context

Microservices frameworks need to support multiple infrastructure backends (registries, brokers, transports, stores). Different teams have different preferences and existing infrastructure.

Hard-coding specific implementations:

  • Limits framework adoption
  • Forces migration of existing infrastructure
  • Prevents innovation and experimentation

Decision

Go Micro uses a pluggable architecture where:

  1. Core interfaces define contracts (Registry, Broker, Transport, Store, etc.)
  2. Multiple implementations live in the same repository under interface directories
  3. Plugins are imported directly and passed via options
  4. Default implementations work without any infrastructure

Structure

go-micro/
├── registry/          # Interface definition
│   ├── registry.go
│   ├── mdns.go       # Default implementation
│   ├── consul/       # Plugin
│   ├── etcd/         # Plugin
│   └── nats/         # Plugin
├── broker/
├── transport/
└── store/

Consequences

Positive

  • No version hell: Plugins versioned with core framework
  • Discovery: Users browse available plugins in same repo
  • Consistency: All plugins follow same patterns
  • Testing: Plugins tested together
  • Zero config: Default implementations require no setup

Negative

  • Repo size: More code in one repository
  • Plugin maintenance: Core team responsible for plugin quality
  • Breaking changes: Harder to evolve individual plugins independently

Neutral

  • Plugins can be extracted to separate repos if they grow complex
  • Community can contribute plugins via PR
  • Plugin-specific issues easier to triage

Alternatives Considered

Separate Plugin Repositories

Used by go-kit and other frameworks. Rejected because:

  • Version compatibility becomes user’s problem
  • Discovery requires documentation
  • Testing integration harder
  • Splitting community

Single Implementation

Like standard net/http. Rejected because:

  • Forces infrastructure choices
  • Limits adoption
  • Can’t leverage existing infrastructure

Dynamic Plugin Loading

Using Go plugins or external processes. Rejected because:

  • Complexity for users
  • Compatibility issues
  • Performance overhead
  • Debugging difficulty
  • ADR-002: Interface-First Design (planned)
  • ADR-005: Registry Plugin Scope (planned)

5.2 - Adr 004 Mdns Default Registry

Service discovery is critical for microservices. Common approaches:

Status

Accepted

Context

Service discovery is critical for microservices. Common approaches:

  1. Central registry (Consul, Etcd) - Requires infrastructure
  2. DNS-based (Kubernetes DNS) - Platform-specific
  3. Static configuration - Doesn’t scale
  4. Multicast DNS (mDNS) - Zero-config, local network

For local development and getting started, requiring infrastructure setup is a barrier. Production deployments typically have existing service discovery infrastructure.

Decision

Use mDNS as the default registry for service discovery.

  • Works immediately on local networks
  • No external dependencies
  • Suitable for development and simple deployments
  • Easily swapped for production registries (Consul, Etcd, Kubernetes)

Implementation

// Default - uses mDNS automatically
svc := micro.NewService("myservice")

// Production - swap to Consul
reg := consul.NewConsulRegistry()
svc := micro.NewService("myservice",
    micro.Registry(reg),
)

Consequences

Positive

  • Zero setup: go run main.go just works
  • Fast iteration: No infrastructure for local dev
  • Learning curve: Newcomers start immediately
  • Progressive complexity: Add infrastructure as needed

Negative

  • Local network only: mDNS doesn’t cross subnets/VLANs
  • Not for production: Needs proper registry in production
  • Port 5353: May conflict with existing mDNS services
  • Discovery delay: Can take 1-2 seconds

Mitigations

  • Clear documentation on production alternatives
  • Environment variables for easy swapping (MICRO_REGISTRY=consul)
  • Examples for all major registries
  • Health checks and readiness probes for production

Use Cases

Good for mDNS

  • Local development
  • Testing
  • Simple internal services on same network
  • Learning and prototyping

Need Production Registry

  • Cross-datacenter communication
  • Cloud deployments
  • Large service mesh (100+ services)
  • Require advanced features (health checks, metadata filtering)

Alternatives Considered

No Default (Force Configuration)

Rejected because:

  • Poor first-run experience
  • Increases barrier to entry
  • Users must setup infrastructure before trying framework

Static Configuration

Rejected because:

  • Doesn’t support dynamic service discovery
  • Manual configuration doesn’t scale
  • Doesn’t reflect real microservices usage

Consul as Default

Rejected because:

  • Requires running Consul for “Hello World”
  • Platform-specific
  • Adds complexity for beginners

Migration Path

Start with mDNS, migrate to production registry:

# Development
go run main.go

# Staging
MICRO_REGISTRY=consul MICRO_REGISTRY_ADDRESS=consul:8500 go run main.go

# Production (Kubernetes)
MICRO_REGISTRY=nats MICRO_REGISTRY_ADDRESS=nats://nats:4222 ./service

5.3 - Adr 009 Progressive Configuration

Microservices frameworks face a paradox:

Status

Accepted

Context

Microservices frameworks face a paradox:

  • Beginners want “Hello World” to work immediately
  • Production needs sophisticated configuration

Too simple: Framework is toy, not production-ready Too complex: High barrier to entry, discourages adoption

Decision

Implement progressive configuration where:

  1. Zero config works for development
  2. Environment variables provide simple overrides
  3. Code-based options enable fine-grained control
  4. Defaults are production-aware but not production-ready

Levels of Configuration

Level 1: Zero Config (Development)

svc := micro.NewService("hello")
svc.Run()

Uses defaults:

  • mDNS registry (local)
  • HTTP transport
  • Random available port
  • Memory broker/store

Level 2: Environment Variables (Staging)

MICRO_REGISTRY=consul \
MICRO_REGISTRY_ADDRESS=consul:8500 \
MICRO_BROKER=nats \
MICRO_BROKER_ADDRESS=nats://nats:4222 \
./service

No code changes, works with CLI flags.

Level 3: Code Options (Production)

reg := consul.NewConsulRegistry(
    registry.Addrs("consul1:8500", "consul2:8500"),
    registry.TLSConfig(tlsConf),
)

b := nats.NewNatsBroker(
    broker.Addrs("nats://nats1:4222", "nats://nats2:4222"),
    nats.DrainConnection(),
)

svc := micro.NewService("myservice",
    micro.Version("1.2.3"),
    micro.Registry(reg),
    micro.Broker(b),
    micro.Address(":8080"),
)

Full control over initialization and configuration.

Level 4: External Config (Enterprise)

cfg := config.NewConfig(
    config.Source(file.NewSource("config.yaml")),
    config.Source(env.NewSource()),
    config.Source(vault.NewSource()),
)

// Use cfg to initialize plugins with complex configs

Environment Variable Patterns

Standard vars for all plugins:

MICRO_REGISTRY=<type>              # consul, etcd, nats, mdns
MICRO_REGISTRY_ADDRESS=<addrs>     # Comma-separated
MICRO_BROKER=<type>
MICRO_BROKER_ADDRESS=<addrs>
MICRO_TRANSPORT=<type>
MICRO_TRANSPORT_ADDRESS=<addrs>
MICRO_STORE=<type>
MICRO_STORE_ADDRESS=<addrs>
MICRO_STORE_DATABASE=<name>
MICRO_STORE_TABLE=<name>

Plugin-specific vars:

ETCD_USERNAME=user
ETCD_PASSWORD=pass
CONSUL_TOKEN=secret

Consequences

Positive

  • Fast start: Beginners productive immediately
  • Easy deployment: Env vars for different environments
  • Power when needed: Full programmatic control available
  • Learn incrementally: Complexity introduced as required

Negative

  • Three config sources: Environment, code, and CLI flags can conflict
  • Documentation: Must explain all levels clearly
  • Testing: Need to test all configuration methods

Mitigations

  • Clear precedence: Code options > Environment > Defaults
  • Comprehensive examples for each level
  • Validation and helpful error messages

Validation Example

func (s *service) Init() error {
    if s.opts.Name == "" {
        return errors.New("service name required")
    }
    
    // Warn about development defaults in production
    if isProduction() && usingDefaults() {
        log.Warn("Using development defaults in production")
    }
    
    return nil
}

5.4 - Adr 010 Unified Gateway

Authors: Go Micro Team

Status: Accepted Date: 2026-02-11 Authors: Go Micro Team

Context

Previously, the go-micro CLI had two separate gateway implementations:

  1. micro run gateway (cmd/micro/run/gateway/) - Simple HTTP-to-RPC proxy for development
  2. micro server gateway (cmd/micro/server/) - Production gateway with authentication, web UI, and API documentation

This duplication created several problems:

  • Code maintenance: Gateway logic (HTTP-to-RPC translation, service discovery, health checks) was implemented twice
  • Feature parity: Improvements to one gateway didn’t automatically benefit the other
  • Complexity: New features (like MCP integration) would need to be implemented twice
  • Testing burden: Each gateway required separate testing

Decision

We unified the gateway implementation by:

  1. Extracting reusable gateway module (cmd/micro/server/gateway.go):

    • GatewayOptions struct for configuration
    • StartGateway() function that returns a *Gateway immediately
    • RunGateway() function that blocks until shutdown
    • Configurable authentication (enabled/disabled)
  2. Refactoring micro server:

    • Gateway logic remains in cmd/micro/server/
    • registerHandlers() now uses instance-specific *http.ServeMux instead of global mux
    • Authentication middleware is conditional based on GatewayOptions.AuthEnabled
    • Auth routes only register when authentication is enabled
  3. Updating micro run:

    • Removed duplicate gateway implementation (cmd/micro/run/gateway/)
    • Now calls server.StartGateway() with AuthEnabled: true
    • Retains process management and hot reload functionality
    • Same auth, scopes, and token management as micro server

Architecture

┌─────────────────────────────────────────────────────────────┐
│                     Unified Gateway                         │
│              (cmd/micro/server/gateway.go)                  │
│                                                             │
│  • HTTP → RPC translation                                  │
│  • Service discovery via registry                          │
│  • Web UI (dashboard, logs, API docs)                      │
│  • Health checks                                           │
│  • Configurable authentication                             │
│  • Endpoint scopes for access control                      │
│  • MCP tool integration with scope enforcement             │
└─────────────────────────────────────────────────────────────┘
           ▲                              ▲
           │                              │
    ┌──────┴──────┐              ┌────────┴────────┐
    │  micro run  │              │  micro server   │
    │             │              │                 │
    │  + Process  │              │  + Auth enabled │
    │    mgmt     │              │  + JWT tokens   │
    │  + Hot      │              │  + Scopes       │
    │    reload   │              │  + Production   │
    │  + Auth     │              │                 │
    │  + Scopes   │              │                 │
    └─────────────┘              └─────────────────┘

Usage

Development Mode (micro run)

# Start services with gateway (auth enabled, default admin/micro)
micro run

# Gateway provides:
# - HTTP API at /api/{service}/{endpoint}
# - Web dashboard at /
# - JWT authentication (admin/micro default)
# - Endpoint scopes at /auth/scopes

Production Mode (micro server)

# Start gateway with authentication
micro server --address :8080

# Gateway provides:
# - HTTP API at /api/{service}/{endpoint} (auth required)
# - Web dashboard with login
# - JWT-based authentication
# - User/token management UI
# - Endpoint scopes at /auth/scopes

Benefits

  1. Single Source of Truth: Gateway logic lives in one place
  2. Automatic Feature Propagation: New features (like MCP) added to the unified gateway benefit both commands
  3. Simplified Testing: Test gateway once, works everywhere
  4. Reduced Code Size: Eliminated ~300 lines of duplicate code
  5. Clear Separation:
    • micro server = API gateway (HTTP + future MCP)
    • micro run = Development tool (gateway + process management + hot reload)

Implementation Details

GatewayOptions

type GatewayOptions struct {
    Address     string        // Listen address (e.g., ":8080")
    AuthEnabled bool          // Enable JWT authentication
    Store       store.Store   // Storage for auth data
    Context     context.Context // Cancellation context
}

Starting the Gateway

// Non-blocking start
gw, err := server.StartGateway(server.GatewayOptions{
    Address:     ":8080",
    AuthEnabled: false,
})

// Blocking start
err := server.RunGateway(server.GatewayOptions{
    Address:     ":8080",
    AuthEnabled: true,
})

Authentication

When AuthEnabled: true:

  • Auth middleware checks JWT tokens on all requests
  • Auth routes are registered: /auth/login, /auth/logout, /auth/tokens, /auth/users
  • Web UI requires login
  • API endpoints require Authorization: Bearer <token> header

When AuthEnabled: false (dev mode):

  • No authentication middleware
  • Auth routes are not registered
  • All endpoints are publicly accessible

Consequences

Positive

  • Easier to add new features (only implement once)
  • Better code maintainability
  • Consistent behavior between development and production
  • Foundation for MCP integration

Negative

  • cmd/micro/run now depends on cmd/micro/server (acceptable for CLI tools)
  • Slightly more complex initialization in micro run (but cleaner overall)

Future Work

With unified gateway architecture, we can now add:

  1. MCP Integration: Add mcp.go to server package, both commands get MCP support
  2. GraphQL API: Single implementation serves both dev and prod
  3. gRPC Gateway: Expose services via gRPC alongside HTTP
  4. API Versioning: Consistent versioning strategy across all deployments

References

  • Original issue: Gateway duplication between micro run and micro server
  • Implementation: PR #XXX (gateway unification)
  • Related: ADR-001 (Plugin Architecture), ADR-009 (Progressive Configuration)