Skip to content
Santekno.com | Level Up Your Engineering Skills
EN
📖 0%
16 Sep 2026 · 27 min read ·Article 46 / 208
Go

Cursor IDE for Golang: Setup .cursorrules, Composer, and Agent Mode

A complete guide to using Cursor IDE for Golang development. Optimal .cursorrules setup, Composer multi-file editing, Agent Mode, and a daily workflow for Go developers.

IH
Ihsan Arif
Writer at Santekno · Backend Engineer

Cursor for Golang: Composer, Agent Mode, and .cursorrules

Doing the Cursor IDE setup for Golang correctly changes how a developer interacts with AI — not as a chat assistant beside the editor, but as a native part of the IDE itself. A fork of the very mature VS Code, Cursor adds a deeply integrated AI layer. For Go developers who don’t want to leave the IDE workflow, Cursor is a very compelling choice.


06.1 What Makes Cursor Unique

Cursor is not VS Code with Copilot — it’s a re-architecture of VS Code with AI as a first-class citizen. The comparison below highlights the fundamental difference between bolting on an AI plugin and redesigning the IDE around AI.

text
 1VS Code + Copilot:
 2  Existing IDE → add an AI plugin
 3  AI works in a "side channel" — suggestions, a separate chat window
 4  Context is very limited (only the currently open file)
 5
 6Cursor:
 7  IDE redesigned with AI as native
 8  Composer: AI can edit the ENTIRE project at once
 9  Context: the whole codebase via RAG indexing
10  .cursorrules: persistent project memory
11  Agent Mode: AI that can run commands, browse docs, iterate

It’s this architectural difference that makes Cursor feel different in daily Go development practice: its AI has context for the whole codebase, not just the file currently open.


06.2 Setup Cursor for a Go Project

Before you’re productive, Cursor needs to be set up with the correct Go tooling. The steps below guide you from installing the binary to verifying that gopls is working.

bash
 1# Install Cursor from cursor.sh
 2# Cursor is a standalone binary, no VS Code install required
 3
 4# Open a Go project:
 5cursor /path/to/santekno-shop
 6
 7# Cursor auto-detects:
 8# - go.mod (Go project)
 9# - Installs Go extension recommendations
10# - Indexes the codebase for RAG
11
12# Set up the Go language server:
13# Cmd+Shift+P → "Go: Install/Update Tools" → install gopls, dlv, etc.
14
15# Verify Go support:
16# Open a .go file → hover a variable → type info appears = gopls working

The final check — hovering a variable shows type info — confirms gopls is active; without it, Cursor’s navigation and suggestion features won’t be optimal.


06.3 .cursorrules: Project Memory in Cursor

.cursorrules is the CLAUDE.md equivalent in Cursor, placed at the project root as memory the AI reads on every interaction. The template below shows the contents of a comprehensive .cursorrules for a Go project — architecture, error handling, types, dependencies, and a list of prohibitions.

markdown
  1# .cursorrules — Santekno Shop Go Project
  2
  3## Project Overview
  4Santekno Indonesia B2C e-commerce.
  5Stack: Go 1.22 | Echo v4 | PostgreSQL (pgx/v5) | Redis | Kafka
  6
  7## Architecture (STRICT — never violate)
  8Clean Architecture layers:
  9  handler → usecase → repository → domain
 10
 11Layer rules:
 12- handler: only import usecase interfaces
 13- usecase: only import domain + repository interfaces  
 14- repository: implement interfaces, only import domain + DB drivers
 15- domain: zero external imports
 16
 17```go
 18// WRONG — layer violation:
 19// In usecase file:
 20import "github.com/santekno/santekno-shop/internal/repository/postgres" // FORBIDDEN
 21
 22// CORRECT — interface at consumer side:
 23// In usecase package:
 24type OrderRepository interface {
 25    GetByIDAndUserID(ctx context.Context, id, userID uuid.UUID) (*Order, error)
 26}
 27```
 28
 29## Error Handling (FOLLOW EXACTLY)
 30
 31```go
 32// Repository not-found → return nil, nil:
 33if err == pgx.ErrNoRows {
 34    return nil, nil  // NEVER return error for not-found
 35}
 36
 37// Error wrapping:
 38if err != nil {
 39    return nil, fmt.Errorf("packageName.FunctionName: %w", err)  
 40    // Include both package AND function name
 41}
 42
 43// Usecase not-found handling:
 44if order == nil {
 45    return ErrOrderNotFound  // domain error, NOT wrapped
 46}
 47```
 48
 49## Types (CRITICAL)
 50
 51```go
 52// Monetary: int64 cents ONLY
 53type Order struct {
 54    TotalIDR int64  // 50000 = Rp 500.00
 55}
 56// NEVER: float64, decimal, float32
 57
 58// IDs: uuid.UUID
 59type Order struct {
 60    ID uuid.UUID
 61}
 62// NEVER: string IDs
 63
 64// Context: always first parameter
 65func Execute(ctx context.Context, input Input) error
 66```
 67
 68## External Dependencies (exact import paths)
 69
 70```
 71github.com/jackc/pgx/v5              # PostgreSQL
 72github.com/redis/go-redis/v9         # Redis
 73github.com/labstack/echo/v4          # HTTP
 74go.uber.org/mock/gomock              # Mocking
 75github.com/stretchr/testify/suite    # Test suites
 76github.com/google/uuid               # UUIDs
 77github.com/confluentinc/confluent-kafka-go/v2  # Kafka
 78```
 79
 80## Testing Standards
 81
 82```go
 83// Suite structure:
 84type CancelOrderSuite struct {
 85    suite.Suite
 86    ctrl     *gomock.Controller
 87    mockRepo *mock.MockOrderRepository
 88    uc       *usecase.CancelOrderUseCase
 89}
 90
 91// Test naming: TestSubject_Scenario_ExpectedResult
 92// Example: TestCancelOrder_PendingWithinWindow_Success
 93```
 94
 95## NEVER do these
 96
 97```go
 98result, _ := op()          // NEVER ignore error
 99return err                 // NEVER no-context return
100var price float64          // NEVER float for money
101func f(id string)          // NEVER string for UUID IDs
102```
103
104## Go 1.22 Only
105No features from Go 1.23+: no range-over-func, no iter.Seq, no slices.Collect

The more concrete the WRONG/CORRECT examples in .cursorrules, the more consistently Cursor follows the team’s conventions — this file is a write-once investment that pays off in every Composer session.


06.4 Composer: Cursor’s Killer Feature for Go

Composer (Cmd+I or Ctrl+I) is Cursor’s superpower: an AI that can edit dozens of files at once. The prompt below shows the first use case — implement one complete feature by listing every file that must be created or changed.

text
 1Composer prompt:
 2──────────────────────────────────────────
 3Implement the CancelOrder feature in Santekno Shop.
 4
 5Spec (ACs to satisfy):
 6- DELETE /orders/:id with JWT auth
 7- Only PENDING orders can be cancelled
 8- Cancel window: 30 minutes
 9- Restore stock atomically within a transaction
10- Response: 204 No Content
11- Error codes: ORDER_NOT_FOUND, ORDER_NOT_CANCELLABLE, CANCEL_WINDOW_EXPIRED
12
13Files to create/modify:
141. internal/domain/order/entity.go — add CanBeCancelled() method
152. internal/domain/order/errors.go — add ErrCancelWindowExpired if missing
163. internal/usecase/order/cancel_order.go — create new
174. internal/usecase/order/cancel_order_test.go — create new with testify/suite
185. internal/repository/postgres/order_repository.go — add CancelWithStockRestore
196. internal/delivery/http/handler/order_handler.go — add CancelOrder handler
207. internal/delivery/http/router/router.go — add route
21
22Follow the patterns from the existing create_order.go.
23──────────────────────────────────────────

The key to an effective prompt is listing the files explicitly and referencing existing patterns — Cursor then produces a unified diff for all seven files that you can review per file. The second use case is refactoring across the codebase; the prompt below changes the error handling pattern across the entire usecase directory.

text
 1Composer prompt:
 2──────────────────────────────────────────
 3Refactoring: Update all error handling in internal/usecase/
 4from the old pattern to the new pattern.
 5
 6OLD pattern (change this):
 7  return err
 8  return nil, err
 9
10NEW pattern (make it this):
11  return fmt.Errorf("usecaseName.methodName: %w", err)
12  return nil, fmt.Errorf("usecaseName.methodName: %w", err)
13
14Rules:
15- Use the actual package name (cancelOrder, createOrder, etc.)
16- Use the actual method name (Execute, Validate, etc.)
17- Don't change test files
18- Don't change the repository layer (different pattern there)
19──────────────────────────────────────────

Including explicit rules about what must not change (test files, repository layer) prevents Composer from making excessive changes. The third use case is generating boilerplate from an existing pattern; the prompt below replicates the Order domain structure for the Product domain.

text
 1Composer prompt:
 2──────────────────────────────────────────
 3Generate a CRUD usecase for the Product domain.
 4Follow EXACTLY the pattern from the existing Order domain.
 5
 6Order domain reference files:
 7- internal/domain/order/entity.go
 8- internal/usecase/order/create_order.go  
 9- internal/usecase/order/get_order.go
10- internal/repository/postgres/order_repository.go
11
12Product domain specs:
13- Product entity: ID, SKU, Name, Price (int64 cents), Stock (int), CategoryID
14- Use cases: CreateProduct, GetProduct, ListProducts, UpdateProduct
15- Repository: Create, GetByID, GetBySKU, List (with pagination), Update
16──────────────────────────────────────────

By pointing to concrete reference files, Cursor produces a new domain that’s consistent with the project’s conventions instead of guessing the structure from scratch.


06.5 Agent Mode: Autonomous Task Execution

Agent Mode gives Cursor the ability to browse documentation, run terminal commands, and make decisions based on output. The sequence below illustrates how Agent Mode closes the implement-build-test-fix loop autonomously.

go
 1// Agent Mode example: Implement and test a feature
 2
 3// Prompt in Agent Mode:
 4// "Implement CancelOrder and verify with tests"
 5
 6// Agent sequence:
 7// 1. Read existing code to understand patterns
 8// 2. Write implementation
 9// 3. Run: go build ./... → check compile errors
10// 4. Fix compile errors
11// 5. Run: go test ./internal/usecase/order/... -v
12// 6. Fix failing tests
13// 7. Run: go test -race ./internal/usecase/order/...
14// 8. Fix race conditions if any
15// 9. Report: "Implementation complete, all tests pass"

The ability to run commands and iterate from their output makes Agent Mode suitable for well-defined tasks. Another example is a dependency upgrade; the flow below shows the Agent tracing the changelog through to verifying the build.

text
 1Agent Mode:
 2"Upgrade pgx from v5.5.0 to v5.7.0"
 3
 4Agent:
 51. Browse: github.com/jackc/pgx/releases (check changelog)
 62. Identify breaking changes (e.g., method signatures that changed)
 73. Update go.mod
 84. Run: go mod tidy
 95. Run: go build ./... → find compile errors
106. Fix each compile error
117. Run: go test ./...
128. Report summary

Agent Mode is safest for tasks with clear completion criteria, like a dependency upgrade, where success can be verified automatically through build and test.


06.6 Inline Chat (Cmd+K): Quick In-Place Edits

For more focused edits without opening Composer, Inline Chat (Cmd+K) edits the selected code directly. The example below shows how a single repository function is fixed in place.

go
 1// Select function → Cmd+K:
 2
 3func (r *orderRepository) GetByIDAndUserID(
 4    ctx context.Context,
 5    orderID uuid.UUID,
 6    userID uuid.UUID,
 7) (*domain.Order, error) {
 8    // ... existing implementation
 9}
10
11// Inline prompt:
12// "Add context timeout of 5 seconds and improve error messages"
13
14// Cursor edits in-place, no need to open Composer

Inline Chat is ideal for surgical changes to one function — faster than Composer when the scope is only the block you’re highlighting.


06.7 RAG and @Mentions

Cursor indexes the whole codebase via RAG, but you can steer the context more precisely with @mentions. The list below summarizes the most useful reference syntax in a Go workflow.

bash
 1# @file — reference a specific file
 2"Implement GetProductBySKU following the pattern in @order_repository.go"
 3
 4# @folder — reference a directory
 5"Review all files in @internal/usecase/order/ for error handling consistency"
 6
 7# @docs — reference documentation  
 8"Implement following the @docs/architecture.md guidelines"
 9
10# @web — browse external documentation
11"Implement pgx v5 batch insert following the @web docs"
12
13# Codebase search
14"Find all places that use float64 for monetary values"

Explicit references with @file or @folder are far more reliable than relying on RAG to guess the relevant context — use them when accuracy matters.


06.8 .cursorignore: Optimize RAG

RAG quality depends on what gets indexed. The .cursorignore file below excludes artifacts and generated files so retrieval stays focused on production code.

bash
 1# .cursorignore — exclude files from indexing
 2
 3# Build artifacts
 4**/bin/
 5**/dist/
 6**/.idea/
 7**/.vscode/
 8
 9# Generated files (don't index, they pollute RAG)
10**/*.pb.go
11**/mock_*.go  
12**/*_gen.go
13
14# Test fixtures and testdata
15**/testdata/
16**/fixtures/
17
18# Vendor
19**/vendor/
20
21# CI/CD artifacts
22**/coverage.out
23**/coverage.html

Excluding generated files (mocks, protos) from RAG indexing makes code retrieval more accurate for production code, because the AI is no longer distracted by machine-generated boilerplate.


06.9 Cursor Settings for Go Development

The right workspace settings make Cursor behave idiomatically for Go. The configuration below sets lint, format, test flags, and the default model.

json
 1// .cursor/settings.json
 2{
 3  "cursor.general.gitIgnorePatterns": true,
 4  "cursor.composer.context": "smart",
 5  
 6  // Go-specific
 7  "go.lintTool": "golangci-lint",
 8  "go.lintOnSave": "workspace",
 9  "go.formatTool": "goimports",
10  "go.testFlags": ["-v", "-race"],
11  "go.coverageDecorator": {
12    "type": "highlight"
13  },
14  
15  // AI model preference
16  "cursor.general.defaultModel": "claude-3-5-sonnet-20241022"
17}

Setting go.testFlags with -race and go.formatTool to goimports ensures each save automatically enforces the same standards as CI, so AI output aligns with the project conventions immediately.


06.10 Cursor Model Selection: Pick the Right One

Cursor supports many models, and choosing the right one per task saves both time and cost. The guide below maps each model to the kind of work it’s best suited for.

text
 1claude-3-5-sonnet:
 2  Best for: complex features, architecture decisions, debugging
 3  Speed: moderate
 4  Cost: moderate (included in Cursor Pro)
 5
 6claude-3-haiku:
 7  Best for: simple tasks, quick edits, test generation from a template
 8  Speed: fast
 9  Cost: low
10
11gpt-4o:
12  Best for: general coding, documentation
13  Speed: fast
14
15cursor-1 (Cursor's own model):
16  Best for: autocomplete, inline suggestions
17  Speed: very fast
18  Trained specifically on coding tasks

Use Sonnet for complex tasks and cursor-1/Haiku for autocomplete and lightweight edits — matching the model to task complexity is the easiest way to keep things responsive.


06.11 Cursor Workflow for Daily Go Development

Cursor is most productive when used with a clear daily rhythm. The snippet below sketches the morning session: planning and complex implementation through Composer.

bash
 1# Open Cursor, open the project
 2# Read .specify/features/ or the backlog
 3# Open Composer (Cmd+I):
 4
 5"Today I'll implement the GetOrdersByCustomer endpoint.
 6Read the spec at .specify/features/get-orders-by-customer/spec.md
 7and build an implementation plan before we start coding.
 8List all files that will be affected."
 9
10# Composer: builds the plan
11# Review the plan
12# Approve and execute

Starting the day with spec-based planning ensures the implementation is directed. Moving into midday, the rhythm shifts to iteration and verification as below.

bash
1# Composer or inline chat for refinement:
2Cmd+K → "Add error handling for the case where a product is no longer active"
3
4# Agent Mode for verification:
5"Run the tests and fix all failing tests"
6
7# Check test coverage:
8# Cmd+Shift+P → "Go: Toggle Test Coverage"

Midday is the time for fast iteration: focused edits with Cmd+K and automatic verification with Agent Mode. Toward the afternoon, focus shifts to review and consistency as in the snippet below.

bash
1# Inline chat for cleanup:
2# Select code → Cmd+K → "Improve comments, add godoc for exported functions"
3
4# Composer for a consistency check:
5"Review all files changed today for:
61. Error handling consistency
72. Test coverage gaps
83. CLAUDE.md compliance"

Closing the day with a Composer consistency check ensures all of that day’s changes are uniform before they go into a PR.


06.12 Cursor for Go Testing: Special Tips

Cursor is very strong at generating tests. The prompt below produces a comprehensive test suite with testify/suite and gomock, mapping each AC to a test case.

text
 1Composer:
 2"Generate a complete test suite for CancelOrderUseCase using testify/suite + gomock.
 3
 4Cover:
 5AC1: Happy path — PENDING order within 30 minutes
 6AC2: Order not found or not owned by the user  
 7AC3: Order not PENDING
 8AC4: Cancel window expired (> 30 minutes)
 9AC5: Atomic cancel fails (simulated DB error)
10EC1: Concurrent cancel (mock behavior)
11
12Use table-driven tests for ACs with similar setup.
13Refer to create_order_test.go for the suite structure pattern."

Mapping each AC to a test case explicitly makes Cursor produce complete coverage, not just the happy path. For concurrent scenarios, the prompt below directs Cursor to write a race integration test.

go
1// Cursor is very good at generating race condition tests:
2// "Write an integration test (//go:build integration) that verifies
3// that concurrent cancel requests on the same order produce only
4// one success. Use sync.WaitGroup to
5// simulate concurrent requests."

A concurrent test like this is important to validate atomicity, and Cursor with a .cursorrules that includes concurrency rules produces a solid skeleton. Finally, benchmark tests help measure performance; the prompt below asks for them.

go
1// "Generate a benchmark test for CancelOrderUseCase.Execute:
2// - BenchmarkCancelOrder_Happy path
3// - BenchmarkCancelOrder_WithDBLatency (simulate 10ms latency)
4// Use a proper testing.B, with b.ResetTimer() after setup."

A benchmark with b.ResetTimer() after setup ensures the measurement only covers the code under test, not the setup cost — a detail often forgotten but remembered by Cursor when asked explicitly.


06.13 Strengths and Weaknesses: Summary

After dissecting its features, it’s important to weigh Cursor honestly. Its main strengths for Go development:

Excellent visual diff — see exactly what changes before approving

Composer for multi-file — implement a feature that touches 7 files in one operation

Solid RAG — context-aware suggestions based on the whole codebase

Familiar IDE experience — VS Code compatible, all extensions work

Flat-rate pricing — $20/month without worrying about token usage

Model switching — swap models per task without restarting the IDE

On the flip side, there are weaknesses to be aware of:

Context retention — .cursorrules is sometimes “forgotten” in long sessions, more inconsistent than CLAUDE.md

Go idiom quality — occasionally generates code that needs cleanup (float64 for money, errors without wrapping)

No native SDD — no built-in spec-first workflow (must be done manually with Composer prompts)

Resource intensive — Cursor is heavier than VS Code, needs more RAM

In short, Cursor wins on the visual experience and multi-file editing, but loses to Claude Code on context consistency and Go idiom quality — a trade-off that decides when to use each.


06.14 Cursor vs Claude Code: When to Use Each

Because the two are often used together, it’s important to know when to pick which. The guide below separates the tasks best suited for Cursor from those best suited for Claude Code.

text
 1Use Cursor for:
 2✅ Implementing a feature that touches many files (Composer)
 3✅ Visually reviewing changes before applying
 4✅ Refactoring with a clear scope
 5✅ Daily coding inside the IDE
 6✅ A predictable budget (flat-rate)
 7
 8Use Claude Code for:
 9✅ Complex planning and reasoning
10✅ Deep debugging (race conditions, deadlocks)
11✅ SDD workflow (read spec, plan, implement, verify)
12✅ Architecture discussions
13✅ Long autonomous sessions with verification
14
15Best strategy: Cursor for 80% of daily coding + Claude Code for 20% of complex tasks

This 80/20 split is a widely used pattern: Cursor handles the majority of daily coding, while Claude Code is reserved for tasks that need deep reasoning.


06.15 Tips & Gotchas

💡 Tip 1: Always commit before large Composer operations. A checkpoint makes experimentation risk-free.

bash
1git add -A
2git commit -m "checkpoint before AI refactoring"
3# Now Composer can experiment freely
4# If the result is unsatisfactory: git reset --hard

With a checkpoint commit, large-scale Composer operations become reversible — a bad result is simply reset without losing work.

💡 Tip 2: Use “Accept” selectively, not “Accept All”. For changes across many files, review each file before accepting; Cursor shows a per-file diff — take advantage of it.

💡 Tip 3: @-mention for more precise context. Referencing specific lines is far more effective than the ambiguous “follow existing patterns”, for example: "Implement the cancellation logic following the pattern in @create_order.go lines 45-80".

💡 Tip 4: Use YOLO mode very carefully. YOLO mode (auto-execute without confirmation) suits test environments that can be reset, tasks that are clear and reversible, and developers already very familiar with AI output. Don’t use it on production-adjacent tasks.

⚠️ Gotcha 1: .cursorrules scope. A .cursorrules at the root directory only applies to that project; if you open a different folder, .cursorrules isn’t carried over. Make sure this file is always present at the root of the project you’re working on.

⚠️ Gotcha 2: Composer context can miss important files. Composer doesn’t always include every relevant file; if the output is inaccurate, name the context files explicitly, e.g. "Implement X. Use this as reference: @internal/usecase/order/create_order.go".

⚠️ Gotcha 3: Model billing in Cursor Pro. Cursor Pro ($20/month) includes “unlimited” usage but has a fair-use policy; for very heavy usage (>100 Composer requests/day) there may be throttling, and the Business plan ($40) is aimed at heavy enterprise usage.

⚠️ Gotcha 4: RAG indexing takes time for large codebases. A codebase over 100K lines can take 5-15 minutes for initial indexing; during this process RAG suggestions are less accurate, so wait for indexing to finish before starting an intensive session.


06.16 Cursor for Common Go Scenarios

Theory becomes clear through concrete examples. The first scenario is implementing a repository with pgx/v5; the prompt below asks for an atomic cancel-plus-restore-stock operation in a single transaction.

text
 1Composer prompt:
 2"Implement a PostgreSQL repository for CancelOrder.
 3Use the pgx/v5 pool (not pgxpool separately).
 4Use the pattern from @order_repository.go GetByID as a template.
 5Must support an atomic operation: cancel order + restore stock in one transaction.
 6
 7Required signature:
 8CancelWithStockRestore(ctx context.Context, orderID uuid.UUID) error
 9
10Transaction pattern: begin → cancel order → restore stock per item → commit
11Rollback if any step fails."

With a prompt that specifies the signature and transaction pattern, Cursor produces the implementation below — note the defer rollback and consistent error wrapping.

go
 1func (r *orderRepository) CancelWithStockRestore(
 2    ctx context.Context,
 3    orderID uuid.UUID,
 4) error {
 5    tx, err := r.pool.Begin(ctx)
 6    if err != nil {
 7        return fmt.Errorf("orderRepo.CancelWithStockRestore: begin tx: %w", err)
 8    }
 9    defer tx.Rollback(ctx) // no-op after commit
10
11    // Step 1: Update order status to CANCELLED
12    cancelledAt := time.Now().UTC()
13    tag, err := tx.Exec(ctx, `
14        UPDATE orders 
15        SET status = 'cancelled', cancelled_at = $1, updated_at = $1
16        WHERE id = $2 AND status = 'pending'
17    `, cancelledAt, orderID)
18    if err != nil {
19        return fmt.Errorf("orderRepo.CancelWithStockRestore: update order: %w", err)
20    }
21    if tag.RowsAffected() == 0 {
22        return fmt.Errorf("orderRepo.CancelWithStockRestore: order not found or not pending")
23    }
24
25    // Step 2: Restore stock for each item
26    rows, err := tx.Query(ctx, `
27        SELECT product_id, quantity FROM order_items WHERE order_id = $1
28    `, orderID)
29    if err != nil {
30        return fmt.Errorf("orderRepo.CancelWithStockRestore: query items: %w", err)
31    }
32    defer rows.Close()
33
34    for rows.Next() {
35        var productID uuid.UUID
36        var quantity int
37        if err := rows.Scan(&productID, &quantity); err != nil {
38            return fmt.Errorf("orderRepo.CancelWithStockRestore: scan item: %w", err)
39        }
40        if _, err := tx.Exec(ctx, `
41            UPDATE products SET stock = stock + $1 WHERE id = $2
42        `, quantity, productID); err != nil {
43            return fmt.Errorf("orderRepo.CancelWithStockRestore: restore stock: %w", err)
44        }
45    }
46    if err := rows.Err(); err != nil {
47        return fmt.Errorf("orderRepo.CancelWithStockRestore: rows: %w", err)
48    }
49
50    if err := tx.Commit(ctx); err != nil {
51        return fmt.Errorf("orderRepo.CancelWithStockRestore: commit: %w", err)
52    }
53    return nil
54}

This output shows the correct pattern: a defer rollback that becomes a no-op after commit, a step-by-step transaction, full error wrapping, and a RowsAffected check to ensure only pending orders are cancelled. The second scenario is generating middleware; the prompt below asks for a JWT auth middleware for Echo.

text
1Composer:
2"Implement a JWT auth middleware for Echo v4.
3Use github.com/golang-jwt/jwt/v5.
4Set user_id (uuid.UUID) into the echo context.
5Return 401 with {"error": "UNAUTHORIZED"} if the token is invalid.
6Use the error response pattern from @order_handler.go."

Referencing the existing error response pattern ensures the new middleware is consistent with the rest of the handlers. The third scenario is generating a table-driven test; the prompt below defines the input and cases to cover.

text
 1Composer:
 2"Generate a table-driven test for ValidateOrderInput.
 3Test with testify/suite.
 4Cover: valid input, empty fields, invalid UUID, negative price.
 5
 6Input struct:
 7type CreateOrderInput struct {
 8    CustomerID uuid.UUID
 9    Items      []OrderItem
10    AddressID  uuid.UUID
11}
12
13Use subtests: s.Run(tc.name, func() { ... })"

Specifying the test cases and subtest structure explicitly makes Cursor produce a test that’s organized and easy to extend.


06.17 Cursor Keyboard Shortcuts for Go Developers

Mastering shortcuts speeds up the workflow significantly. The list below summarizes the most frequently used Cursor and gopls shortcuts in Go development.

text
 1Cmd+I (Ctrl+I)         → Open Composer (primary AI interface)
 2Cmd+K (Ctrl+K)         → Inline edit (edit the selected code)
 3Cmd+L (Ctrl+L)         → Open Chat (ask without editing a file)
 4Cmd+Shift+P            → Command palette (all VS Code commands)
 5
 6Go-specific (via gopls):
 7F12                    → Go to definition
 8Shift+F12              → Find all references
 9Cmd+Shift+I            → Implement interface (if the cursor is on an interface)
10Cmd+.                  → Quick fix (auto-import, etc.)
11Alt+Shift+F            → Format file (go fmt via goimports)
12
13Test running:
14Cmd+Shift+T            → Run test in the current file
15Cmd+Shift+R            → Run test at cursor
16F5                     → Start debugging (Delve)
17
18Navigation:
19Cmd+P                  → File search
20Cmd+Shift+F            → Global search (search across all files)
21Cmd+G                  → Go to line

The three core AI shortcuts — Cmd+I (Composer), Cmd+K (inline), Cmd+L (chat) — are the most frequently used; memorizing just these already speeds up the majority of your daily interactions with Cursor.


06.18 Cursor Integration with the Git Workflow

Cursor integrates tightly with git to make AI sessions safe and traceable. The flow below shows the pattern of checkpoint before, review during, and verify after a Composer session.

bash
 1# Pre-Composer: always checkpoint
 2git add -A && git stash
 3# Or:
 4git add -A && git commit -m "checkpoint before AI session $(date)"
 5
 6# During the Composer session:
 7# Cursor shows a unified diff before applying
 8# Review each file → Accept or Reject per-file
 9
10# Post-Composer verification:
11go build ./...
12go test -race ./...
13git diff HEAD  # see all changes after accept all
14
15# If the result is unsatisfactory:
16git reset --hard HEAD  # back to checkpoint
17# Or:
18git stash pop  # restore stash
19
20# A good branch strategy for AI sessions:
21git checkout -b feat/cancel-order
22# All AI changes go into this branch
23# PR to main with proper review

Running all AI changes in a separate branch with a checkpoint at the start makes every Composer session fully reversible and ready to be reviewed through a proper PR.


06.19 Cursor Composer: The Most Effective Patterns for Go

After intensive use, a few Composer patterns prove the most consistent at producing the best output for Go. The first pattern is template-based generation, which is far more effective than a bare “implement CRUD”.

text
1"Generate a [NewDomain] domain following EXACTLY the pattern from [ExistingDomain].
2Files to create:
31. internal/domain/[newdomain]/entity.go — copy structure from order/entity.go
42. internal/domain/[newdomain]/errors.go — copy structure from order/errors.go
53. internal/usecase/[newdomain]/create_[newdomain].go — from create_order.go
64. [etc.]
7
8Reference files: [src file list]"

Giving Cursor an explicit template from an existing domain reduces guesswork and keeps the structure consistent. The second pattern is layer-by-layer with verification, where Cursor stops and shows the diff for each layer.

text
 1Composer session:
 2
 3"Implement the CancelOrder feature. Work layer by layer:
 4
 5Step 1: internal/domain/order/entity.go — add CanBeCancelled() method
 6[done, user reviews diff]
 7
 8Step 2: internal/usecase/order/cancel_order.go — implement usecase
 9[done, user reviews diff]
10
11Step 3: internal/repository/postgres/order_repository.go — add CancelWithStockRestore
12[done, user reviews diff]
13
14Step 4: internal/delivery/http/handler/order_handler.go — add handler
15Step 5: router update
16
17After each step, show me only that step's changes before proceeding."

Forcing a per-layer review prevents changes from piling up into a giant diff that’s hard to verify. The third pattern is constraint-first, which explicitly limits what may be changed.

text
1"Implement CancelOrder with the following constraints (very important):
2- DO NOT change files other than those listed
3- DO NOT add error handling not in the spec
4- DO NOT change test files
5- Use EXACTLY the package paths from .cursorrules
6
7Files that may be changed: [list]"

Stating constraints up front is the most reliable way to prevent Composer from making excessive changes outside the scope you want.


06.20 .cursorrules: Differences from CLAUDE.md

Although their function is the same, .cursorrules and CLAUDE.md are effective with different writing styles. The comparison below shows the same content expressed in two styles.

text
 1CLAUDE.md style (more structured):
 2
 3## Error Handling
 4Repository not-found: return nil, nil
 5Error wrap: fmt.Errorf("pkg.Method: %w", err)
 6
 7.cursorrules style (more conversational, because the LLM reads this differently):
 8
 9When implementing error handling in Go:
10- Repository not-found ALWAYS returns (nil, nil) — never an error
11- All error wraps MUST use fmt.Errorf("package.Method: %w", err) pattern
12- Example:
13  ```go
14  if errors.Is(err, pgx.ErrNoRows) {
15      return nil, nil
16  }
17  return nil, fmt.Errorf("orderRepo.GetByID: %w", err)
text
1The point: .cursorrules is more effective with prose plus examples, while CLAUDE.md is more effective with structured headers — match the style to the tool, don't just copy the same content over.
2
3---
4
5## 06.21 Cursor Agent Mode: Best Practices
6
7Agent Mode differs from Composer because it's fully autonomous. The guide below summarizes the difference along with best practices for using it safely on a Go project.

Composer: Multi-file editing approved per step Agent Mode: Fully autonomous, can:

  • Browse the web for docs
  • Run terminal commands
  • Iterate based on errors
  • Edit multiple files without approval

Best practices for Agent Mode on a Go project:

  1. Use ONLY for well-defined tasks: “Implement and test CancelOrder, all layers” Not: “Improve the codebase quality”

  2. Set explicit constraints: “Only change internal/usecase/order/ and internal/domain/order/”

  3. Always review the result when done: git diff → review all changes go test ./… → verify they still pass

  4. YOLO mode very carefully: Only for low-risk tasks (documentation, test generation) Not for production business logic

text
1The key to using Agent Mode safely is a well-defined task, explicit file constraints, and a mandatory review with `git diff` plus `go test` when it's done.
2
3---
4
5## 06.22 Cursor for a Go Monorepo
6
7Cursor works well for a Go monorepo with a few configuration techniques. The guide below summarizes layered .cursorrules, .cursorignore, and cross-service references.

Setup for a monorepo:

  1. Root .cursorrules with universal rules

  2. Per-service .cursorrules (in subfolders) for service-specific rules (Cursor reads the most local one first)

  3. .cursorignore to exclude files from indexing: **/vendor/ **/.pb.go ← generated proto files **/mock_.go ← generated mocks

  4. Explicit @file for cross-service context: “@file order-service/internal/domain/order/entity.go @file notification-service/internal/consumer/order_consumer.go Verify the event contract compatibility between the two”

  5. Workspace settings (cursor settings per workspace): { “cursor.indexingOptions”: { “excludePatterns”: ["/testdata/", “/*.sql”], “maxFileSizeKB”: 500 } }

text
1The combination of layered .cursorrules (universal at root, specific per service) and explicit @file for cross-service context is an effective way to keep Cursor accurate in a large monorepo.
2
3---
4
5## 06.23 Debugging with Cursor
6
7Cursor offers several debugging flows you can choose from depending on the situation. The list below summarizes the three main flows along with notes for race conditions in Go.

Flow 1: Error-driven (most common)

  1. Paste the error into Composer/Chat
  2. “@workspace how do I resolve this?”
  3. Cursor analyzes + proposes a fix + applies

Flow 2: Test-first debugging

  1. Write a failing test
  2. “Make this test pass: @internal/usecase/order/cancel_order_test.go”
  3. Cursor implements

Flow 3: Trace-based

  1. “Trace this request from handler to database: POST /orders/:id/cancel”
  2. Cursor generates a (mental) sequence diagram and traces the code
  3. Identifies where the issue occurs

For race conditions in Go: “Here’s the output of go test -race: [paste output] @file [relevant files] Analyze and fix the race condition” Cursor + a .cursorrules that includes concurrency rules = a decent result but not as good as Claude Code

text
1For most bugs, the error-driven flow is enough; but for complex race conditions, Cursor gives a decent result while Claude Code remains superior in depth of analysis.
2
3---
4
5## 06.24 Cost Analysis of Cursor for Teams
6
7Cost is a real consideration when adopting Cursor for a team. The breakdown below compares Cursor's per-individual and per-team pricing against Claude Code.

Cursor pricing breakdown for a Go team:

Individual developer: Cursor Pro: $20/month Includes: 500 fast requests/month (Claude Sonnet) Unlimited slow requests (slower model)

Team of 5: Cursor Business: $40/dev/month = $200/month total Includes: admin controls, usage tracking

vs Claude Code for the same team: Moderate usage: $50/dev = $250/month Heavy usage: $80/dev = $400/month

Cursor advantage: predictable and cheaper for medium-heavy users

Cursor limitation: no per-project billing If one project is large with many Composer sessions = can hit the limit

text
 1Cursor's advantage is a predictable flat cost that's cheaper for medium-heavy usage, with the trade-off of no per-project billing, which can be a constraint on very intensive projects.
 2
 3---
 4
 5## 06.25 Comparison: Cursor vs Other Tools for Go
 6
 7To close out the evaluation, the table below lines up Cursor against Claude Code and Copilot per task type, complete with a winner for each row.
 8
 9| Task | Cursor | Claude Code | Copilot | Winner |
10|------|--------|-------------|---------|--------|
11| Multi-file implement | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | Cursor |
12| Go idiom quality | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | Claude |
13| Visual diff | ⭐⭐⭐⭐⭐ | ❌ | ❌ | Cursor |
14| Context retention | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | Claude |
15| Inline suggestions | ⭐⭐⭐⭐ | ❌ | ⭐⭐⭐⭐⭐ | Copilot |
16| PR review automation | ❌ | ❌ | ⭐⭐⭐⭐⭐ | Copilot |
17| Cost predictability | ✅ $20 flat | ❌ Variable | ✅ $10 flat | Copilot |
18| Large refactoring | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | Cursor |
19| SDD workflow | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ | Claude |
20
21This table confirms there's no single winner: Cursor leads in multi-file and visual diff, Claude Code in Go idiom and SDD, Copilot in inline suggestions and PR automation — confirmation that a multi-tool strategy is often the best answer.
22
23---
24
25## 06.26 Summary
26
27Cursor is the best choice for Go developers who are comfortable with a VS Code-based IDE, do multi-file editing often, need visual diff before applying changes, and want predictable flat-rate pricing. The IDE familiarity also makes team adoption easier than a CLI.
28
29Its main weaknesses — context retention that trails CLAUDE.md and a more manual SDD workflow — can be mitigated with an excellent .cursorrules (referencing existing patterns), pairing with Claude Code for planning and spec work, and explicit @file references for important context.
30
31For the best of both worlds, make Cursor your primary IDE for 80% of daily coding and Claude Code for the 20% of tasks that need deep reasoning. In the next article, we discuss a third tool with a very different strength: GitHub Copilot with Chat, Completions, and Workspace.
32
33




Related Articles

💬 Comments