Cursor Rules for Go: Packages, Errors, and Tests

A practical rule set for Go projects in Cursor, covering package boundaries, error handling, concurrency patterns, and test commands. Adapt each template to your project and record the team decisions that make them specific in fenbs.

Updated 4 min read

Cursor rules for a Go project tell the assistant which packages exist, how errors travel through the code, which concurrency patterns are approved, and how to run and write tests. Go has strong conventions in the standard library, but every project adds its own choices on top: a custom error type, a specific HTTP router, a preferred way to structure handlers. Without rules, the assistant defaults to what it has seen most often, which may not match your project. fenbs helps teams record the decisions that make their Go conventions specific, so every connected assistant starts from the agreed starting point.

The templates below are starting points. Replace the package names, import paths, and tool names with your actual project values before using them. A rule that references internal/errors only helps if that is where your error types live.

Package structure and boundaries

Go's internal/ convention gives you a way to enforce package boundaries at the compiler level, but the assistant still needs to know which internal packages exist and which ones a given context should import from. A structure rule prevents the assistant from creating new packages in the wrong place or importing across a boundary you intended to be one-directional.

Package structure rule
Project layout:
- cmd/: main packages, one per binary
- internal/: private packages not importable outside this module
  - internal/domain: core types and interfaces, no infrastructure imports
  - internal/service: business logic, imports from domain only
  - internal/storage: database access, implements domain interfaces
  - internal/api: HTTP handlers, imports from service only
- pkg/: reusable packages safe to import externally

Do not import internal/storage from internal/service directly.
Use the interfaces defined in internal/domain.

Error handling

Go error handling is idiomatic but has many valid patterns: sentinel errors, error types, wrapped errors with %w, and custom error interfaces. An assistant that switches between patterns within the same codebase makes the code inconsistent and harder to test. A rule naming your chosen approach keeps new code consistent with existing code.

Error handling rule
Errors:
- Define error types in internal/errors/errors.go
- Wrap errors with context: fmt.Errorf("doing X: %w", err)
- Check error types with errors.Is and errors.As, not string matching
- Return errors from functions; do not panic except in main() init
- Log errors at the boundary where they leave the system (api layer)
  Do not log the same error at multiple levels

Concurrency patterns

Go's goroutines and channels make concurrent code easy to write and easy to get wrong. An assistant that spawns goroutines without the project's established patterns for cancellation, error propagation, and cleanup can introduce subtle leaks. A concurrency rule names the patterns your project uses so the assistant matches them.

Concurrency rule
Concurrency:
- Always accept a context.Context as the first argument in long-running functions
- Use context cancellation to stop goroutines; do not rely on channel closes alone
- Prefer errgroup (golang.org/x/sync/errgroup) for coordinating multiple goroutines
- Never use a goroutine without a clear ownership and cleanup path
- Race detector: run go test -race ./... before committing concurrent code

Testing conventions

Go's built-in testing package is minimal, and projects add their own structure: table-driven tests, testify assertions, mock generation tools, integration test tags. A rule that names your actual setup prevents the assistant from writing tests in a style that does not match the rest of the test suite.

Test conventions rule
Tests:
- Use the standard testing package; add testify/assert for assertions
- Write table-driven tests for functions with multiple input cases
- File naming: match the source file with _test.go suffix
- Tag integration tests with //go:build integration
- Run unit tests: go test ./...
- Run with race detector: go test -race ./...
- Mocks: generate with mockery; keep generated files in mocks/
How fenbs helps

Keep your Go rule set where every assistant reads it

Add your approved Go rules to fenbs Skills and prompts alongside the decisions that shaped them. When the team adopts a new error pattern or switches mock generators, update the entry once and every connected assistant starts the next session from the current approach. fenbs does not run Go commands — it keeps the shared instructions your team has agreed on.

Create a free account

Free for one person · No credit card · Works with Claude, ChatGPT, Cursor and more

How to do this with fenbs

  1. Create a free account and add a project for your Go module.
  2. Add a skill or prompt for each rule area: package structure, error handling, concurrency, and testing. Keep each rule short — two to five specific instructions work better than a long explanation.
  3. Record the key team decisions in Decisions and rules: why you chose your error type approach, why the project uses or avoids a particular concurrency pattern. These give the assistant context that the rule file alone cannot provide.
  4. When a team member proposes changing a convention — switching from a custom error type to wrapped stdlib errors, for example — record the open decision in fenbs before updating the rule files.
  5. Connect your AI tools from Integrations so they read the current rules before starting work on the codebase.

What a rule file cannot do in a Go project

A Cursor rule tells the assistant how to write new code. It does not prevent it from importing a package if the import is syntactically valid; the compiler enforces that. It does not run the linter or the test suite — you need to do that yourself. Rules work best as reminders for the decisions a person made, not as enforcement mechanisms.

Project-specific business rules — which API endpoints exist, what the expected response format is, which third-party service is the approved payment provider — belong in your project notes in fenbs, not in a language rule file. See the cursor rules for AI projects article for how to combine coding rules with project context.

Go's built-in tooling deserves a mention in your rules. go vet catches common mistakes, and golangci-lint covers a wider range of static checks. Reference your project's lint configuration in a rule rather than duplicating each check. A rule that says "run go vet and golangci-lint before considering a change complete" is more maintainable than a rule that lists every individual check by name.

When the team upgrades the Go version, review the rule files for advice that may have changed. Features available in a newer version may warrant a rule update, and patterns now handled by the language itself may no longer need an explicit instruction. A brief review after any dependency update keeps the rules accurate without letting them accumulate outdated guidance. A rule that names a function removed in the new standard library is worse than no rule at all.

Context propagation is one of the areas where Go projects diverge most from each other. Some pass context only to I/O-bound operations; others thread it through every function. A rule that says "context.Context is always the first argument in any function that calls the network, a database, or a long-running operation" makes the team's decision clear to the assistant. If your project uses a request-scoped logger or trace ID stored in context values, name the key type and where it is set, so the assistant does not introduce a different approach that conflicts with the existing pattern.

Questions people ask.

Should I put Go rules in a .cursorrules file or in .cursor/rules/?

Either works. The .cursor/rules/ directory lets you use multiple rule files with glob patterns to scope each one. A single .cursorrules file is simpler for small projects. Whichever you choose, keep it in version control so teammates see the same rules.

What Go conventions are worth writing rules for?

Focus on conventions that prevent real mistakes: which error type to use, how to handle context cancellation, which packages can import from which, and where new files should go. Skip conventions your linter already enforces.

Should I include the Go version in a Cursor rule?

Yes, if you use features specific to a recent version or if the project must stay on a particular version for compatibility reasons. Mention the go version and any relevant constraints about upgrading.

How do I write rules for a project using Go generics?

Include a short note about where generics are used and where they should be avoided. If your project has a policy — for example, only use generics in the pkg/ layer — add that as a rule. Generic patterns vary enough across projects that a rule specific to yours is more useful than a general one.

More in Prompts and skills for AI work

All Prompts and skills for AI work articles

Start with one thing.

Free for one person · No credit card · Works with Claude, ChatGPT, Cursor and more

There is nothing to set up first. Write one line and you’ve started.