Skip to main content
skill CX Codex

golang-google-wire — Claude Code skill: Go DI and install

Helps wire Go dependency graphs with google/wire at compile time. Use it when adding or changing Wire providers and injectors.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add samber/cc-skills-golang --skill golang-google-wire -a claude-code
Open on GitHub

What golang-google-wire does

This skill covers compile-time DI with google/wire: reusable provider sets built with wire.NewSet, graph assembly through wire.Build, explicit interface bindings with wire.Bind, and struct or value providers such as wire.Struct, wire.Value, wire.InterfaceValue, and wire.FieldsOf. It also handles cleanup functions and the generated wire_gen.go file.

An injector uses the //go:build wireinject tag so its stub is left out of the binary while the generated implementation is compiled. Without that tag, both function definitions can reach the build and cause a compile error. Go and the wire command are required; run wire ./... after graph changes to catch missing dependencies before the application starts.

What it helps with

  • build a Go dependency graph at compile time
  • bind an interface to a concrete provider with wire.Bind
  • group providers into reusable wire.NewSet definitions
  • set up an injector file with the wireinject build tag
  • chain cleanup functions through application initialization

Example prompts for the agent

  • Review this Go dependency graph with google/wire and identify missing providers.
  • Create wire.NewSet definitions for the configuration, database, and services, then bind the interface with wire.Bind.
  • Check the injector files and run wire ./... to regenerate wire_gen.go.

How to install golang-google-wire

1Skills CLI (Vercel)

npx skills add samber/cc-skills-golang --skill golang-google-wire -a claude-code

2Manually: put the files in place

~/.claude/skills/golang-google-wire/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/golang-google-wire/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about golang-google-wire

How do I install golang-google-wire in Claude Code?

Run npx skills add samber/cc-skills-golang --skill golang-google-wire -a claude-code, then use ~/.claude/skills/golang-google-wire/SKILL.md.

What does golang-google-wire do?

It guides compile-time dependency injection with google/wire, including providers, sets, interface bindings, injector files, and generated wire_gen.go without a runtime container or reflection.

What happens without //go:build wireinject?

The injector stub and generated function can be compiled together. That causes a compile error because the function is defined twice.

Source text

SKILL.md · MIT
---
name: golang-google-wire
description: "Compile-time dependency injection in Golang using google/wire — wire.NewSet, wire.Build, wire.Bind (interface→concrete), wire.Struct, wire.Value, wire.InterfaceValue, wire.FieldsOf, cleanup functions, //go:build wireinject injector files, and generated wire_gen.go. Apply when using or adopting google/wire, when the codebase imports `github.com/google/wire`, or when wiring an application graph at compile time via `wire.Build`. For runtime DI with reflection, see `samber/cc-skills-golang@golang-uber-dig` skill."
user-invocable: true
license: MIT
compatibility: Designed for Claude Code, Codex or similar harness, and for projects using Golang.
metadata:
  author: samber
  version: "1.1.2"
  openclaw:
    emoji: "🪡"
    homepage: https://github.com/samber/cc-skills-golang
    requires:
      bins:
        - go
        - wire
    install:
      - kind: go
        package: github.com/google/wire/cmd/wire@latest
        bins: [wire]
    skill-library-version: "0.7.0"
allowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*) Bash(git:*) Agent WebFetch mcp__context7__resolve-library-id mcp__context7__query-docs Bash(wire:*) Bash(godig:*) Bash(gopls:*) LSP mcp__gopls__*
paths:
  - "**/*.go"
---

**Persona:** You are a Go architect using wire for compile-time DI. You let the compiler catch missing dependencies, treat `wire_gen.go` as committed source, and re-run `wire ./...` after every graph change.

**Dependencies:**

- wire: `go install github.com/google/wire/cmd/wire@latest`

# Using google/wire for Compile-Time Dependency Injection in Go

Code-generation DI toolkit. Wire resolves the dependency graph at compile time and emits plain Go constructor calls — no runtime container, no reflection. Errors appear when you run `wire ./...`, not at first request.

Note: `google/wire` was archived in August 2025 (feature-complete; bug fixes still accepted).

**Official Resources:** [pkg.go.dev](https://pkg.go.dev/github.com/google/wire) · [github.com/google/wire](https://github.com/google/wire) · [User Guide](https://github.com/google/wire/blob/main/docs/guide.md) · [Best Practices](https://github.com/google/wire/blob/main/docs/best-practices.md)

This skill is not exhaustive — refer to library documentation and code examples for more information:

- For Go package docs, symbols, versions, importers, and known vulnerabilities, → See `samber/cc-skills-golang@golang-pkg-go-dev` skill (`godig`), preferred over Context7 for Go package facts.
- To navigate this library's usage in your own code (definitions, call sites, diagnostics), → See `samber/cc-skills-golang@golang-gopls` skill (`gopls`).
- Context7 remains a fallback for docs not indexed on pkg.go.dev.

```bash
go get -tool github.com/google/wire/cmd/wire@latest
go get github.com/google/wire
```

## wire vs. Runtime DI

| Concern           | wire                      | dig / fx / samber/do   |
| ----------------- | ------------------------- | ---------------------- |
| Resolution        | Compile time (codegen)    | Runtime (reflection)   |
| Error detection   | `wire ./...` fails        | First `Invoke`/startup |
| Runtime container | None — plain Go calls     | Present                |
| Lifecycle hooks   | Not built in              | fx: OnStart/OnStop     |
| Generated files   | `wire_gen.go` (committed) | None                   |

For lifecycle, lazy loading, and a full matrix see `samber/cc-skills-golang@golang-dependency-injection`.

## Providers

A provider is any Go function — inputs are dependencies, outputs are provided types. Three return forms:

```go
func NewConfig() *Config                          { return &Config{Addr: ":8080"} }
func NewDB(cfg *Config) (*sql.DB, error)          { return sql.Open("postgres", cfg.DSN) }
func NewRedis(cfg *Config) (*redis.Client, func(), error) { // cleanup chained in reverse order
    c := redis.NewClient(&redis.Options{Addr: cfg.RedisAddr})
    return c, func() { c.Close() }, nil
}
```

## Provider Sets

`wire.NewSet` groups providers for reuse. Sets can reference other sets.

```go
// infra/wire.go
var InfraSet = wire.NewSet(
    NewConfig,
    NewDB,
    NewRedis,
)

// service/wire.go
var ServiceSet = wire.NewSet(
    NewUserRepo,
    NewUserService,
    wire.Bind(new(UserStore), new(*UserRepo)), // interface binding
)
```

Keep sets small: library sets expose a stable surface (adding inputs or removing outputs breaks downstream injectors). One set per package is a useful default.

## Injectors and `//go:build wireinject`

The injector file declares the initialization function. Wire generates its body into `wire_gen.go` and replaces the stub.

```go
//go:build wireinject

package main

import "github.com/google/wire"

// Wire generates the body of this function.
func InitApp() (*App, func(), error) {
    wire.Build(InfraSet, ServiceSet, NewApp)
    return nil, nil, nil // replaced by codegen
}
```

The `//go:build wireinject` tag prevents the stub from being compiled into the binary — only `wire_gen.go` (which has no such tag) makes it through `go build`. Without this tag, both files define the same function, causing a compile error.

Alternative syntax when a dummy return is inconvenient:

```go
func InitApp() (*App, func(), error) {
    panic(wire.Build(InfraSet, ServiceSet, NewApp))
}
```

## Interface Bindings

Wire forbids implicit interface satisfaction — you must declare bindings explicitly so the graph is unambiguous when multiple types implement the same interface.

```go
var Set = wire.NewSet(
    NewPostgresUserRepo,
    wire.Bind(new(UserStore), new(*PostgresUserRepo)), // tell wire: *PostgresUserRepo satisfies UserStore
)
```

Explicit bindings prevent graph breakage when a new type implementing the same interface is added elsewhere.

## Struct Providers and Values

`wire.Struct` fills struct fields from the graph without a manual constructor. Tag fields `wire:"-"` to exclude them.

```go
wire.Struct(new(Server), "Logger", "DB") // inject named fields
wire.Struct(new(Server), "*")            // inject all non-excluded fields
wire.Value(Foo{X: 42})                   // constant expression (no fn calls / channels)
wire.InterfaceValue(new(io.Reader), os.Stdin) // interface-typed literal
wire.FieldsOf(new(Config), "DSN", "Addr")    // promote struct fields as graph nodes
```

See [advanced.md](references/advanced.md) for the `wire:"-"` exclusion tag and `wire.FieldsOf` details.

## Disambiguating Duplicate Types

Wire forbids two providers for the same type. Wrap the underlying type in distinct named types so each has exactly one provider:

```go
type PrimaryDSN string
type ReplicaDSN string
```

## Full Application Example

```go
// wire.go — injector, excluded from binary via build tag
//go:build wireinject

package main

func InitApp() (*App, func(), error) {
    wire.Build(config.ConfigSet, infra.InfraSet, service.ServiceSet, NewApp)
    return nil, nil, nil
}

// main.go
func main() {
    app, cleanup, err := InitApp()
    if err != nil { log.Fatal(err) }
    defer cleanup()
    app.Run()
}
```

Wire generates `wire_gen.go` (plain Go, committed, DO NOT EDIT). For a full example with per-package sets, cleanup-heavy graphs, and generated output, see [recipes.md](references/recipes.md).

## Codegen Workflow

```bash
wire ./...           # regenerate all injectors in the module
wire check ./...     # validate graph without regenerating (fast CI check)
```

Run `wire ./...` after every constructor signature change. Add `//go:generate go run github.com/google/wire/cmd/wire` to injector files so `go generate ./...` also works. Commit `wire_gen.go` — it must stay in sync for CI builds.

## Best Practices

1. Never edit `wire_gen.go` — it is overwritten on every `wire ./...` run. Treat it as a build artifact that happens to be committed; source of truth is the provider and injector files.
2. Always add `//go:build wireinject` to injector files — omitting it causes duplicate-symbol compile errors because both the stub and the generated file define the same function.
3. Use named types to distinguish values of the same underlying type — wire enforces one provider per type; named types like `type DSN string` let you have `PrimaryDSN` and `ReplicaDSN` coexist.
4. Keep library provider sets minimal and backward-compatible — adding new required inputs breaks downstream injectors; removing outputs does too. Introduce only newly-created types in the same release.
5. Return `(T, func(), error)` from cleanup providers and let wire chain them — wire generates the correct reverse-order cleanup and handles partial failures (if construction fails midway, only already-built cleanups run).
6. Keep injector files focused — one function per file, one package import at a time. Fat injectors with dozens of `wire.Build` arguments are hard to reason about; delegate to per-package sets.

## Common Mistakes

| Mistake | Fix |
| --- | --- |
| Editing `wire_gen.go` manually | Never edit it. Change providers or injectors and re-run `wire ./...`. |
| Missing `//go:build wireinject` | Add the tag as the very first line of every injector file. |
| Two providers returning `*sql.DB` | Wrap with a named struct type: `type PrimaryDB struct { *sql.DB }` — Wire does not distinguish pointer type aliases. |
| Injecting an interface without `wire.Bind` | Add `wire.Bind(new(MyInterface), new(*MyImpl))` to the provider set. |
| Forgetting to re-run `wire ./...` after changes | Run wire before `go build`; add it to `go generate` or a Makefile target. |
| Calling `cleanup()` without guarding for nil | Wire returns nil cleanup on construction error; guard with `if cleanup != nil { defer cleanup() }`. |

## Testing

Wire generates plain Go constructors, so unit tests use manual injection — no container to clone or reset. For testing patterns (test injectors swapping real providers for fakes, CI stale-check for `wire_gen.go`), see [testing.md](references/testing.md).

## Further Reading

- [advanced.md](references/advanced.md) — cleanup chains, multiple injectors, set nesting, error catalogue, codegen flags, quick reference
- [recipes.md](references/recipes.md) — HTTP server, multi-injector build, cleanup-heavy graph, CLI embedding
- [testing.md](references/testing.md) — test injectors, fake bindings, CI stale check

## Cross-References

- → See `samber/cc-skills-golang@golang-dependency-injection` skill for DI concepts and library comparison
- → See `samber/cc-skills-golang@golang-uber-dig` skill for runtime reflection-based DI without lifecycle
- → See `samber/cc-skills-golang@golang-uber-fx` skill for runtime DI with lifecycle hooks, modules, and signal-aware Run()
- → See `samber/cc-skills-golang@golang-samber-do` skill for generics-based DI without reflection
- → See `samber/cc-skills-golang@golang-structs-interfaces` skill for interface design patterns
- → See `samber/cc-skills-golang@golang-testing` skill for general testing patterns

If you encounter a bug or unexpected behavior in google/wire, open an issue at <https://github.com/google/wire/issues>.

© samber · MIT · samber/cc-skills-golang

Similar skills

All skills for Programming languages →

From the same set44

The whole set →
golang-swagger Adds guidance for OpenAPI and Swagger docs in Go through annotations and spec generation. Useful when documenting handlers or reviewing an existing API. CX Codex +1 37,100installs golang-spf13-cobra Skill for spf13/cobra, the Go library for building command trees, validating arguments, parsing flags, and generating shell completion. Use it when building or extending a CLI application in Go. CX Codex +1 37,100installs golang-graphql Builds and reviews GraphQL APIs in Go using gqlgen or graphql-go. It assists with schema design, resolver architecture, and query batching to prevent N+1 issues. CX Codex +1 37,000installs golang-spf13-viper Configures the spf13/viper Go library with strict precedence, flag bindings, environment variables, and struct decoding. CX Codex +1 36,800installs golang-uber-fx Skill for uber-go/fx — a dependency injection framework with lifecycle hooks, module system, and graceful shutdown. Useful if your project already uses fx or you're migrating to it for long-running services. CX Codex +1 36,600installs golang-uber-dig This skill helps wire Go application dependencies with uber-go/dig. Use it when registering constructors and resolving an application graph at startup. CX Codex +1 36,600installs golang-how-to The skill picks the Go skills a task needs and loads them together. Useful when you write a service, chase a panic, or set up a project. CX Codex +1 36,200installs golang-pkg-go-dev Queries Go package docs, API signatures, examples, and CVEs via godig and pkg.go.dev. Inspects external dependencies directly in agent chat. CX Codex +1 11,800installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor