Go Cursor Rules: AI-Powered Development Best Practices

Cursor rules for Go development enforcing idiomatic patterns, modern Go 1.21+ features, and clean code principles with AI assistance for production-ready code.

Overview

Professional cursor rules for Go development that enforce idiomatic patterns and best practices. These rules help AI assistants generate clean, efficient, and maintainable Go code with proper context and documentation. Whether you're building web services, CLI tools, or concurrent systems, these rules ensure your Go code follows community standards.

Note:

Enforces Go idioms, modern Go 1.21+ features, and context-aware code generation for production-ready development.

Looking for rules in other languages? Check out our Python cursor rules, Rust cursor rules, or browse all language-specific cursor rules.

Rules Configuration

---
description: Enforces best practices for Go development, focusing on context-aware code generation, modern patterns, and maintainable architecture. Provides comprehensive guidelines for writing clean, efficient, and secure Go code with proper context.
globs: **/*.go
---
# Go Best Practices

You are an expert in Go programming and related technologies.
You understand modern Go development practices, architectural patterns, and the importance of providing complete context in code generation.

### Context-Aware Code Generation
- Always provide complete package context including imports and package declarations
- Include relevant configuration files (go.mod, go.sum) when generating projects
- Generate complete function signatures with proper parameters and return values
- Include comprehensive GoDoc comments explaining the purpose, parameters, and return values
- Provide context about the package's role in the larger system architecture
- Follow proper package organization and module structure

### Code Style and Structure
- Follow Go style guide and clean code principles
- Structure code in logical packages following domain-driven design
- Implement proper separation of concerns (handlers, services, repositories)
- Use modern Go features (generics, error wrapping, context) appropriately
- Maintain consistent code formatting using gofmt
- Use proper interface design and composition
- Implement proper error handling with custom error types
- Use proper logging with structured data

### Type System and Interfaces
- Use proper type definitions and interfaces
- Implement proper interface segregation
- Use proper type assertions and type switches
- Implement proper custom types and methods
- Use proper type embedding and composition
- Implement proper type constraints with generics
- Use proper type aliases when appropriate
- Implement proper type safety patterns

### Testing and Quality
- Write comprehensive unit tests with proper test context
- Include integration tests for critical paths
- Use proper table-driven tests
- Implement proper test helpers and utilities
- Include performance tests for critical components
- Maintain high test coverage for core business logic
- Use proper test data factories
- Implement proper test doubles
- Use proper test organization with test packages

### Security and Performance
- Implement proper input validation and sanitization
- Use secure authentication and token management
- Configure proper CORS and CSRF protection
- Implement rate limiting and request validation
- Use proper caching strategies
- Optimize memory usage and garbage collection
- Implement proper error handling and logging
- Use proper data validation and sanitization
- Implement proper access control

### API Design
- Follow RESTful principles with proper HTTP methods
- Use proper status codes and error responses
- Implement proper versioning strategies
- Document APIs using OpenAPI/Swagger
- Include proper request/response validation
- Implement proper pagination and filtering
- Use proper serialization and deserialization
- Implement proper rate limiting
- Use proper API authentication

### Concurrency and Parallelism
- Use proper goroutine patterns
- Implement proper channel communication
- Use proper sync primitives
- Implement proper context cancellation
- Use proper worker pools
- Implement proper error handling in goroutines
- Use proper resource cleanup
- Implement proper backpressure
- Use proper concurrent data structures

### Build and Deployment
- Use proper module management
- Implement proper CI/CD pipelines
- Use Docker for containerization
- Configure proper environment variables
- Implement proper logging and monitoring
- Use proper deployment strategies
- Implement proper backup strategies
- Use proper monitoring tools
- Implement proper error tracking

### Examples

```go
// Package user provides user-related operations.
// It handles user management and authentication.
package user

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"log"
)

// UserService handles user-related operations.
type UserService struct {
	apiClient APIClient
	cache     Cache
	logger    *log.Logger
}

// NewUserService creates a new UserService instance.
func NewUserService(apiClient APIClient, cache Cache, logger *log.Logger) *UserService {
	if logger == nil {
		logger = log.Default()
	}
	return &UserService{
		apiClient: apiClient,
		cache:     cache,
		logger:    logger,
	}
}

// FindUserByEmail finds a user by their email address.
//
// Parameters:
//   - ctx: context for cancellation and timeouts
//   - email: the email address to search for
//
// Returns:
//   - *User: the user if found
//   - error: any error that occurred
func (s *UserService) FindUserByEmail(ctx context.Context, email string) (*User, error) {
	// Check cache first
	cachedUser, err := s.cache.Get(ctx, fmt.Sprintf("user:%s", email))
	if err == nil && cachedUser != "" {
		var user User
		if err := json.Unmarshal([]byte(cachedUser), &user); err == nil {
			return &user, nil
		}
	}

	// Fetch from API
	user, err := s.apiClient.GetUser(ctx, email)
	if err != nil {
		s.logger.Printf("Failed to find user by email: %v", err)
		return nil, fmt.Errorf("failed to find user by email: %w", err)
	}

	// Cache the result
	if user != nil {
		userJSON, err := json.Marshal(user)
		if err == nil {
			_ = s.cache.Set(ctx, fmt.Sprintf("user:%s", email), string(userJSON))
		}
	}

	return user, nil
}

// Tests for UserService functionality.
func TestUserService_FindUserByEmail(t *testing.T) {
	tests := []struct {
		name          string
		email         string
		cacheResponse string
		apiResponse   *User
		apiError      error
		wantUser      *User
		wantError     bool
	}{
		{
			name:          "user found in cache",
			email:         "[email protected]",
			cacheResponse: `{"id":1,"email":"[email protected]"}`,
			wantUser:      &User{ID: 1, Email: "[email protected]"},
		},
		{
			name:      "user found via API",
			email:     "[email protected]",
			apiResponse: &User{ID: 1, Email: "[email protected]"},
			wantUser:  &User{ID: 1, Email: "[email protected]"},
		},
		{
			name:      "user not found",
			email:     "[email protected]",
			apiResponse: nil,
			wantUser:  nil,
		},
		{
			name:      "API error",
			email:     "[email protected]",
			apiError:  errors.New("API error"),
			wantError: true,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Setup
			ctx := context.Background()
			apiClient := &mockAPIClient{
				getUserResponse: tt.apiResponse,
				getUserError:   tt.apiError,
			}
			cache := &mockCache{
				getResponse: tt.cacheResponse,
			}
			service := NewUserService(apiClient, cache, nil)

			// Execute
			user, err := service.FindUserByEmail(ctx, tt.email)

			// Verify
			if tt.wantError {
				if err == nil {
					t.Error("expected error, got nil")
				}
				return
			}

			if err != nil {
				t.Errorf("unexpected error: %v", err)
				return
			}

			if !reflect.DeepEqual(user, tt.wantUser) {
				t.Errorf("got user %v, want %v", user, tt.wantUser)
			}
		})
	}
}

Key Features

📦

Complete Code Context

Full package context, imports, and comprehensive GoDoc comments included automatically

🚀

Modern Go Features

Generics, error wrapping, context handling, and Go 1.21+ patterns

Testing Built-In

Automatic generation of table-driven tests with proper test structure

🔒

Security First

Input validation, secure authentication, and proper error handling

📐

Idiomatic Patterns

Follows Go idioms and community standards with gofmt formatting

Concurrency Support

Proper goroutine patterns, channels, and context cancellation

Installation

1

Choose Your IDE

Select the appropriate file path based on your development environment.

2

Create the Rules File

Create the cursor rules file in your project:

Create file: .cursor/rules/go.mdc

3

Add the Rules Configuration

Copy the rules configuration below into your newly created file.

4

Start Coding

Your AI assistant will now follow Go best practices automatically.

Use Cases

Web Services

RESTful APIs, gRPC services, and microservices with proper architecture

CLI Tools

Command-line applications with proper flag parsing and user interaction

Concurrent Systems

High-performance concurrent applications with goroutines and channels

Cloud Native Apps

Containerized applications with Kubernetes integration and cloud services

Standards Reference

StandardDescriptionEnforcement
Go IdiomsCommunity-standard patterns and practicesRequired for all code
Type SafetyStrict type usage and interfacesRequired for all types
GoDocComprehensive documentation commentsRequired for public APIs
TestingTable-driven tests with coverageAuto-generated with code
Error HandlingExplicit error returns and wrappingBuilt into patterns
ConcurrencySafe goroutine and channel usageEnforced via structure

Note:

Combine these rules with golangci-lint and staticcheck for maximum code quality enforcement.

Best Practices

Code Organization

  • Handlers manage HTTP requests
  • Services contain business logic
  • Repositories manage data access
  • Models represent domain entities

Error Handling

  • Always check and handle errors explicitly
  • Wrap errors with context using fmt.Errorf
  • Use custom error types for specific cases
  • Return errors as the last return value

Concurrency Patterns

  • Use contexts for cancellation and timeouts
  • Close channels when done writing
  • Use sync.WaitGroup for goroutine coordination
  • Avoid sharing memory, communicate via channels

Note:

These rules work with any Go project but are optimized for web services and CLI tools. Adjust patterns as needed for your specific use case. For TypeScript projects, see our TypeScript cursor rules, or explore best practices for cursor rules.