Skip to content
Agentmart
Submit a tool

go-interface-design

Go interface design patterns: implicit interfaces, consumer-side definition, interface compliance verification, composition, the…

Skill by eduardo-sl

IndexedMIT★ 82
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/eduardo-sl-go-interface-design

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Go interface design patterns: implicit interfaces, consumer-side definition, interface compliance verification, composition, the accept-interfaces-return-structs principle, and common pitfalls. Use when designing interfaces, decoupling packages, defining contracts, reviewing interface usage, or refactoring for testability. Trigger examples: "design interface", "accept interfaces return structs", "interface compliance", "consumer-side interface", "interface composition". Not for: HTTP handler patterns (go-api-design), general review (go-code-review).

Use cases: design, backend, security

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/go-interface-design

Tools it pre-approves 7

From allowed-tools in SKILL.md: the agent may use these without asking you each time.

  • Read
  • Edit
  • Write
  • Glob
  • Grep
  • Bash(go:*)
  • Bash(gofmt:*)

What's inside

Skill name
go-interface-design
Description
Go interface design patterns: implicit interfaces, consumer-side definition, interface compliance verification, composition, the accept-interfaces-return-structs principle, and common pitfalls. Use when designing interfaces, decoupling packages, defining contracts, reviewing interface usage, or refactoring for testability. Trigger examples: "design interface", "accept interfaces return structs", "interface compliance", "consumer-side interface", "interface composition". Not for: HTTP handler patterns (go-api-design), general review (go-code-review).
License
MIT
Compatibility
Designed for Claude Code or similar AI coding agents working on Go projects. Requires the Go toolchain.
Allowed tools
Read, Edit, Write, Glob, Grep, Bash(go:*), Bash(gofmt:*)
Metadata
author: eduardo-sl · version: 1.2.1
Instructions
227 lines in SKILL.md · view on GitHub

Before installing

  • Pre-approves some shell commands

Files (2)

  • SKILL.md
  • embedding-and-assertions.md · references/

SKILL.md (first lines)

# Go Interface Design

Go interfaces are implicit. This is the single most important design feature
of the language, and most people coming from Java or C# get it wrong at first.

> Community default. A project skill or agent-config rule that explicitly
> supersedes `go-interface-design` takes precedence over this one.

Detailed reference material, loaded on demand:

- `references/embedding-and-assertions.md` — embedding vs named fields,
  interface-embedding test fakes, optional capabilities, sealed interfaces.

Read a reference file only when the summary below is not enough.

## 1. The Cardinal Rule: Define Interfaces at the Consumer

The consumer of a behavior defines the interface, NOT the provider:

```go
// ❌ Wrong — producer defines interface (Java thinking)
// package store
type UserStore interface {      // defined alongside implementation
    GetByID(ctx context.Context, id string) (*User, error)
    Create(ctx context.Context, user *User) error
    // ... 15 more methods
}

type PostgresStore struct { ... }
func (s *PostgresStore) GetByID(...) { ... }
func (s *PostgresStore) Create(...) { ... }

// ✅ Right — consumer defines what it needs
// package service
type UserReader interface {     // only what THIS service needs
    GetByID(ctx context.Context, id string) (*domain.User, error)
}

type UserService struct {
    store UserReader  // depends on narrow interface
}

// package store (no interface defined here)
type PostgresStore struct { db *sql.DB }
func (s *PostgresStore) GetByID(ctx context.Context, id string) (*domain.User, error) { ... }
func (s *PostgresStore) Create(ctx context.Context, user *domain.User) error { ... }

// PostgresStore satisfies service.UserReader implicitly — no declaration needed
```

Why this matters:
- Consumer depends only on what it uses (Interface Segregation Principle).
- Producer can add methods without breaking consumers.
- Testing requires only the methods the consumer calls.
- No import cycle: consumer doesn't import producer's package.

## 2. Keep Interfaces Small

The bigger the interface, the weaker the abstraction.

```go
// ✅ Good — focused, composable
type Reader interface {
    Read(p []byte) (n int, err error)
}

type Writer interface {
    Write(p []byte) (n int, err error)
}

type ReadWriter interface {
    Reader
    Writer
}

// ❌ Bad — kitchen sink interface
type FileManager interface {
    Read(path string) ([]byte, error)
    Write(path string, data []byte) error
    Delete(path string) error
    List(dir string) ([]string, error)
    Move(src, dst string) error
    Copy(src, dst string) error
    Stat(path string) (os.FileInfo, error)
    Watch(path string) (<-chan Event, error)
}
```

Guideline: 1-3 methods is ideal. If you need more, compose smaller interfaces.

## 3. Accept Interfaces, Return Structs

```go
// ✅ Good — accepts interface, returns concrete type
func NewUserService(store UserReader, logger Logger) *UserService {
    return &UserService{store: store, logger: logger}
}

// ❌ Bad — returns interface (hides the concrete type for no reason)
func NewUserService(store UserReader) UserServiceInterface {
    return &UserService{store: store}
}
```

Return a concrete type so callers get full access to the type's methods.
Returning an interface only makes sense when the function genuinely
returns different concrete types based on input (factory pattern).

## 4. Verify Interface Compliance at Compile Time

Use the blank identifier assignment to catch broken contracts early:

```go
// Verify *PostgresStore implements service.UserReader at compile time
var _ service.UserReader = (*PostgresStore)(nil)

// Verify LogHandler implements http.Handler
var _ http.Handler = (*LogHandler)(nil)

From eduardo-sl/go-agent-skills, MIT.

More from eduardo-sl/go-agent-skills

Signals

Stars
82
Forks
10
Open issues
0
Last commit (this folder)
Oct 14, 2026 (13 days ago)

From GitHub (fetched Oct 24, 2026).

Details

Version
1.2.1
License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from eduardo-sl

Cite this page

go-interface-design skill. Agent Mart. https://agentmart.dev/skills/eduardo-sl-go-interface-design (last updated 2026-10-24)