Tested demoQuality 97/100Review permissions

samber/cc-skills-golang/skills/golang-uber-fx/SKILL.md

golang-uber-fx

Golang application framework using uber-go/fx — fx.New, fx.Provide, fx.Invoke, fx.Module, fx.Lifecycle hooks, fx.Annotate (name/group/As), fx.Decorate, fx.Supply, fx.Replace, fx.WithLogger, and signal-aware Run(). Apply when using or adopting uber-go/fx, when the codebase imports `go.uber.org/fx`, or when wiring services with fx.New. For raw DI without lifecycle, see `samber/cc-skills-golang@golang-uber-dig` skill.

Source repository stars
3,066
Declared platforms
2
Static risk flags
1
Last source update
2026-08-23
Source checked
2026-08-25

Decision brief

What it does: where it fits

Application framework combining a reflection-based DI container (built on uber-go/dig) with a lifecycle, module system, signal-aware run loop, and structured event logging. For long-running services where boot order, graceful shutdown, and modular composition matter.

Best for

    Not for

    • Tasks that require unconfirmed production actions or broad system permissions.
    • Environments where the pinned source and install steps cannot be inspected.
    Controlled single-run demoChecked 2026-08-20

    What changed when the Skill was used

    In this controlled same-task single run, enabling golang-uber-fx changed the output from 2819 non-whitespace characters and 11 headings to 2960 characters and 13 headings. Matches among 8 signals extracted from the pinned source changed from 5 to 4. Both actual outputs are shown; this is a structural observation, not a quality score or a universal performance claim.

    Same test task

    Create a test strategy and representative test cases for a JSON API schema comparison feature. Include failure cases and a clear verification procedure. The deliverable must specifically reflect this user intent: Golang application framework using uber-go/fx — fx.New, fx.Provide, fx.Invoke, fx.Module, fx.Lifecycle hooks, fx.Annotate (name/group/As), fx.Decorate, fx.Supply, fx.Replace, fx.WithLogger, and signal-aware Run(). Apply when using or adopting uber-go/fx, when the codebase imports `go.uber.org/fx`, or when wiring services with fx.New. For raw DI without lifecycle, see `samber/cc-skills-golang@golang-uber-dig` skill.

    Without the Skill
    Screenshot of the actual model output for golang-uber-fx without the Skill

    Baseline: 2819 non-whitespace characters, 11 headings, and 43 list items.

    With the Skill
    Screenshot of the actual model output for golang-uber-fx with the Skill

    With Skill: 2960 non-whitespace characters, 13 headings, and 64 list items.

    ObservationWithout SkillWith Skill
    Source-signal coverage5/8: uber-go, wiring, provide, invoke, lifecycle4/8: uber-go, provide, invoke, lifecycle
    Output structure2819 chars · 11 headings · 43 list items · 0 code blocks2960 chars · 13 headings · 64 list items · 0 code blocks
    Verification and caution signals37 verification signals · 2 risk/limitation signals39 verification signals · 7 risk/limitation signals

    A prompt you can use

    Use the golang-uber-fx Skill pinned at 20e960371b34 for my task. Follow its source-specific constraints around `golang-uber-fx`, `uber-go`, `application`, `wiring`, then return the finished deliverable with explicit assumptions, verification, failure conditions, and limits. Do not treat the Skill text as a factual source or claim that a single demonstration proves universal performance.

    Method and limitationsExpand

    Test method

    • Baseline and treatment used the same task, model (gpt-5.3-codex-low), and runner; the only planned difference was whether the complete target Skill text was injected.
    • The treatment used snapshot 3a823627c6fac359a74b82bd9b5fc8f126a0e950; the current source commit 20e960371b346d5cb7333fda3d46f5e3578d3659 was verified against content hash 3b1edabe11fb. The baseline explicitly prohibited loading any Skill or external rule file.
    • The same deterministic script counted characters, headings, lists, code blocks, verification terms, caution terms, and source signals in both artifacts. Source signals: `golang-uber-fx`, `uber-go`, `application`, `wiring`, `provide`, `invoke`, `lifecycle`, `hooks`.
    • The visuals are local screenshots of the actual Markdown artifacts in a fixed 1200 × 800 evidence canvas, not recreated product mockups. Raw JSON artifacts and request records are retained in the research directory.

    Do not over-read this demo

    • This is one controlled demonstration per condition, not a multi-run statistical benchmark; the model is stochastic.
    • Character, structure, and keyword counts show observable differences but cannot by themselves prove correctness, originality, or business impact.
    • The task is a representative test designed for repeatability, not every real-world use of the Skill; rerun after a material source change.
    Editorial review
    SkillSignal editorial
    Runner
    Cursor Agent 2026.08.04-aaa8809
    Model
    gpt-5.3-codex-low
    Refresh due
    2026-11-18
    Reviewed commit
    20e960371b346d5cb7333fda3d46f5e3578d3659
    Test snapshot
    3a823627c6fac359a74b82bd9b5fc8f126a0e950

    Compatibility matrix

    Platform support, with evidence labels

    PlatformStatusEvidenceWhat to check
    CodexDeclaredSource recordInstall path and trigger
    Claude CodeDeclaredSource recordInstall path and trigger
    CursorNot declaredNo explicit evidencePortability before use
    Gemini CLINot declaredNo explicit evidencePortability before use
    Open the compatibility checker

    Installation

    Inspect first. Install second.

    The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

    Source-detected install commandSource
    npx skills add https://github.com/samber/cc-skills-golang --skill "skills/golang-uber-fx"
    Safe inspection promptEditorial

    Inspect the Agent Skill "golang-uber-fx" from https://github.com/samber/cc-skills-golang/blob/a18860b303ef1d3d928f9670631e03210b8698bf/skills/golang-uber-fx/SKILL.md at commit a18860b303ef1d3d928f9670631e03210b8698bf. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

    Workflow

    What the source asks the agent to do

    1. 01

      fx vs. dig

      fx is built on top of dig and shares the same reflection-based container engine. The DI primitives (Provide, Invoke, In/Out structs, named values, value groups) are identical — fx.In/fx.Out are re-exports of dig.In/dig.Out.

      fx is built on top of dig and shares the same reflection-based container engine. The DI primitives (Provide, Invoke, In/Out structs, named values, value groups) are identical — fx.In/fx.Out are re-exports of dig.In/dig.…Choose fx for long-running services (HTTP servers, workers, daemons) — lifecycle and signal handling are mandatory there, and modules make large service graphs manageable.Choose raw dig when you need wiring without a framework: CLI tools, libraries that expose a container to callers, test harnesses, or embedding DI into an existing app that manages its own lifecycle. See samber/cc-skills…
    2. 02

      The Application

      Boot stages: fx.New validates types (constructors do not run); app.Start(ctx) runs each fx.Invoke and fires OnStart hooks in topological order; main blocks on app.Done(); app.Stop(ctx) fires OnStop hooks in reverse order. Default timeout is 15 seconds — override with fx.StartTim…

      Boot stages: fx.New validates types (constructors do not run); app.Start(ctx) runs each fx.Invoke and fires OnStart hooks in topological order; main blocks on app.Done(); app.Stop(ctx) fires OnStop hooks in reverse orde…
    3. 03

      Provide and Invoke

      fx.Provide registers constructors; fx.Invoke is the trigger — without an Invoke (directly or transitively) referencing a type, its constructor never runs.

      fx.Provide registers constructors; fx.Invoke is the trigger — without an Invoke (directly or transitively) referencing a type, its constructor never runs.
    4. 04

      Lifecycle Hooks

      Inject fx.Lifecycle and append hooks. Constructors should return quickly; long-running work belongs in OnStart.

      Inject fx.Lifecycle and append hooks. Constructors should return quickly; long-running work belongs in OnStart.Both callbacks receive a context bounded by StartTimeout/StopTimeout — respect cancellation. OnStart must return quickly — spawn a goroutine for blocking work; otherwise startup hangs and dependent hooks never fire.fx.StartHook / fx.StopHook / fx.StartStopHook adapt simpler signatures (no context, no error, or both):
    5. 05

      Parameter and Result Objects

      fx re-exports dig's dig.In / dig.Out as fx.In / fx.Out. Use them when a constructor has 4+ dependencies, or when you need name/group/optional tags.

      fx re-exports dig's dig.In / dig.Out as fx.In / fx.Out. Use them when a constructor has 4+ dependencies, or when you need name/group/optional tags.

    Permission review

    Static risk signals and limitations

    Runs scripts

    medium · line 16

    The documentation asks the agent to run terminal commands or scripts.

    go get go.uber.org/fx

    Evidence record

    Why each signal appears

    EvidenceSourceComputedTestedEditorial
    SignalValueEvidence typeMeaning
    Quality score97/100ComputedDocumentation, specificity, maintenance, and trust rules
    Repository stars3,066SourceRepository attention, not individual Skill quality
    Compatibility2 platformsSourceDeclared in the catalog source record
    Usage guidetested outcome pageTestedGenerated or reviewed according to the visible evidence level

    Pinned source

    Provenance and original SKILL.md

    Repository
    samber/cc-skills-golang
    Skill path
    skills/golang-uber-fx/SKILL.md
    Commit
    a18860b303ef1d3d928f9670631e03210b8698bf
    License
    MIT
    Collected
    2026-08-25
    Default branch
    main
    View the original SKILL.md

    Persona: You are a Go architect building a long-running service with fx. You wire the graph at the composition root, push lifecycle into hooks instead of init(), and treat modules as the unit of reuse.

    Using uber-go/fx for Application Wiring in Go

    Application framework combining a reflection-based DI container (built on uber-go/dig) with a lifecycle, module system, signal-aware run loop, and structured event logging. For long-running services where boot order, graceful shutdown, and modular composition matter.

    Official Resources:

    This skill is not exhaustive. Please 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) — prefer it 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.

    go get go.uber.org/fx
    

    fx vs. dig

    fx is built on top of dig and shares the same reflection-based container engine. The DI primitives (Provide, Invoke, In/Out structs, named values, value groups) are identical — fx.In/fx.Out are re-exports of dig.In/dig.Out.

    What fx adds on top:

    Concerndigfx
    DI containerdig.New()✅ (embedded)
    Lifecycle hooksfx.Lifecycle OnStart/OnStop
    Module systemfx.Module with scoped decorators
    Signal-aware run loopapp.Run() blocks on SIGINT/SIGTERM
    Structured event loggingfx.WithLogger / fxevent
    Startup/shutdown timeoutfx.StartTimeout / fx.StopTimeout

    Choose fx for long-running services (HTTP servers, workers, daemons) — lifecycle and signal handling are mandatory there, and modules make large service graphs manageable.

    Choose raw dig when you need wiring without a framework: CLI tools, libraries that expose a container to callers, test harnesses, or embedding DI into an existing app that manages its own lifecycle. See samber/cc-skills-golang@golang-uber-dig skill.

    The Application

    import "go.uber.org/fx"
    
    app := fx.New(
        fx.Provide(NewLogger, NewDatabase, NewServer),
        fx.Invoke(RegisterRoutes),
    )
    app.Run() // blocks until SIGINT/SIGTERM, then runs OnStop hooks
    

    Boot stages: fx.New validates types (constructors do not run); app.Start(ctx) runs each fx.Invoke and fires OnStart hooks in topological order; main blocks on app.Done(); app.Stop(ctx) fires OnStop hooks in reverse order. Default timeout is 15 seconds — override with fx.StartTimeout / fx.StopTimeout.

    Provide and Invoke

    fx.New(
        fx.Provide(NewLogger, NewDatabase, NewServer),  // lazy
        fx.Invoke(RegisterRoutes, StartMetricsExporter), // always run during Start
    )
    

    fx.Provide registers constructors; fx.Invoke is the trigger — without an Invoke (directly or transitively) referencing a type, its constructor never runs.

    Lifecycle Hooks

    Inject fx.Lifecycle and append hooks. Constructors should return quickly; long-running work belongs in OnStart.

    func NewHTTPServer(lc fx.Lifecycle, log *zap.Logger, cfg *Config) *http.Server {
        srv := &http.Server{Addr: cfg.Addr}
    
        lc.Append(fx.Hook{
            OnStart: func(ctx context.Context) error {
                ln, err := net.Listen("tcp", srv.Addr)
                if err != nil { return err }
                go srv.Serve(ln)         // blocking work in a goroutine
                return nil
            },
            OnStop: func(ctx context.Context) error {
                return srv.Shutdown(ctx)
            },
        })
        return srv
    }
    

    Both callbacks receive a context bounded by StartTimeout/StopTimeout — respect cancellation. OnStart must return quickly — spawn a goroutine for blocking work; otherwise startup hangs and dependent hooks never fire.

    fx.StartHook / fx.StopHook / fx.StartStopHook adapt simpler signatures (no context, no error, or both):

    lc.Append(fx.StartStopHook(srv.Start, srv.Stop))   // matched pair
    

    Parameter and Result Objects

    fx re-exports dig's dig.In / dig.Out as fx.In / fx.Out. Use them when a constructor has 4+ dependencies, or when you need name/group/optional tags.

    type ServerParams struct {
        fx.In
    
        Logger *zap.Logger
        DB     *sql.DB
        Cache  *redis.Client     `optional:"true"`
        Routes []http.Handler    `group:"routes"`
    }
    
    func NewServer(p ServerParams) *Server { /* ... */ }
    

    fx.Annotate

    fx.Annotate wraps a constructor to add tags or interface bindings without a fx.Out struct. Prefer it for ergonomic name/group/As bindings:

    fx.Provide(
        fx.Annotate(NewPrimaryDB, fx.ResultTags(`name:"primary"`)),
        fx.Annotate(NewPostgresDB, fx.As(new(Database))),    // expose interface
        fx.Annotate(NewUserHandler,
            fx.As(new(http.Handler)),
            fx.ResultTags(`group:"routes"`),
        ),
    )
    

    Value Groups

    Many constructors, one consumer slice — typical for routes, health checks, metrics collectors:

    type RouteResult struct {
        fx.Out
        Handler http.Handler `group:"routes"`
    }
    
    type ServerParams struct {
        fx.In
        Routes []http.Handler `group:"routes"`
    }
    

    Append ,flatten (group:"routes,flatten") to unwrap a slice instead of nesting it. Order is not guaranteed — provide an explicit ordered slice when sequence matters.

    fx.Module

    fx.Module groups providers, invokes, and decorators under a name. Modules scope decorators to themselves and their children — a logger renamed in fx.Module("db", ...) only appears renamed for code inside that module.

    var DatabaseModule = fx.Module("database",
        fx.Provide(NewConnection, NewUserRepository),
        fx.Decorate(func(log *zap.Logger) *zap.Logger {
            return log.Named("db")
        }),
    )
    
    func main() {
        fx.New(
            fx.Provide(NewConfig, NewLogger),
            DatabaseModule,
            HTTPModule,
        ).Run()
    }
    

    Treat each module as a small library that can be lifted into another app — its public surface is the types it Provides.

    For fx.Supply/fx.Replace/fx.Decorate, optional deps, custom logging, manual lifecycle, and Quick Reference, see advanced.md.

    Best Practices

    1. Keep main() thin — providers, modules, and a single Run(). Push real work into modules so each can be tested in isolation.
    2. Use lifecycle hooks instead of init() or goroutines launched from constructors — Start/Stop ordering depends on graph topology, but init() goroutines do not, which leads to races and leaks.
    3. OnStart must return promptly — long work goes in a goroutine inside the hook. A blocking OnStart hangs the rest of the boot.
    4. Respect ctx.Done() in hooks — a hook that ignores cancellation is reported as a timeout failure but its goroutine continues, leaking resources.
    5. Group by module, not by layer — a module owns the providers, lifecycle, and decorators for one concern (HTTP, DB, metrics).
    6. Use fx.Annotate for tags rather than wrapping a constructor in an fx.Out struct — keeps the constructor reusable outside fx.
    7. Replace fx.Provide with fx.Supply for pre-built values (config, command-line flags). Shorter, signals intent.
    8. Validate the graph in CI by booting under fx.New(...).Err() — catches missing providers and cycles before deploy.

    Common Mistakes

    MistakeFix
    Long-running work directly in OnStartSpawn a goroutine inside OnStart; the hook itself must return quickly so dependent hooks can run.
    fx.Provide something that should be fx.SupplyPre-built values (config, secrets) belong in fx.Supply — clearer and avoids a no-op constructor.
    Module decorator leaking to siblingsDecorate inside fx.Module(...) — decorators flow only to descendants. A top-level fx.Decorate is global.
    Group order assumedGroups are unordered. If order matters, provide an ordered slice from one constructor.
    Constructors with side effectsSide effects belong in OnStart — constructors should be cheap and pure-ish, since they may run concurrently and lazily.
    Forgotten fx.InvokeWithout an Invoke (or downstream consumer), constructors never run. Add at least one Invoke per app.

    Testing

    Use go.uber.org/fx/fxtest to integrate fx with *testing.T (failures call t.Fatal, RequireStop registers as t.Cleanup). fx.Populate(&target) pulls values out of the graph; fx.Replace swaps real dependencies for fakes. Full patterns in testing.md.

    Further Reading

    • advanced.md — Supply/Replace/Decorate, optional deps, custom event logging, manual lifecycle, full Quick Reference
    • recipes.md — full HTTP service with database/metrics, background workers with graceful drain, multiple impls of the same interface, manual lifecycle for CLI embedding
    • testing.md — fxtest patterns, fx.Replace, fx.Populate, isolated lifecycle tests, CI graph validation

    Cross-References

    • → See samber/cc-skills-golang@golang-uber-dig skill for the underlying container, dig.In/dig.Out, and DI without lifecycle
    • → See samber/cc-skills-golang@golang-dependency-injection skill for DI concepts and library comparison
    • → See samber/cc-skills-golang@golang-samber-do skill for a generics-based alternative without reflection
    • → See samber/cc-skills-golang@golang-google-wire skill for compile-time DI (no runtime container)
    • → See samber/cc-skills-golang@golang-structs-interfaces skill for interface design patterns
    • → See samber/cc-skills-golang@golang-context skill for context propagation in OnStart/OnStop hooks
    • → See samber/cc-skills-golang@golang-testing skill for general testing patterns

    If you encounter a bug or unexpected behavior in uber-go/fx, open an issue at https://github.com/uber-go/fx/issues.

    Frequently asked questions

    What to verify before installation and use

    What does the golang-uber-fx source document cover?

    Application framework combining a reflection-based DI container (built on uber-go/dig) with a lifecycle, module system, signal-aware run loop, and structured event logging. For long-running services where boot order, graceful shutdown, and modular composition matter.

    How do I install golang-uber-fx?

    The source record exposes this install command: npx skills add https://github.com/samber/cc-skills-golang --skill "skills/golang-uber-fx". Inspect the command and pinned source before running it.

    Which Agent platforms does the source record declare?

    The pinned source record declares support for: codex, claude code.

    Which permission-related actions were detected?

    Static rules flagged exec-script in the source; the page lists the matching lines and excerpts.

    Alternatives

    Compare before choosing

    Computed 9980

    vasilyu1983/AI-Agents-public

    qa-testing-ios

    Guides iOS testing with XCTest, XCUITest, Swift Testing, simctl, and xcresult. Use when choosing destinations, controlling flakes, or parsing test artifacts for native apps.

    Computed 973,066

    samber/cc-skills-golang

    golang-testing

    Production-ready Golang tests — table-driven tests, testify suites and mocks, parallel tests, fuzzing, fixtures, goroutine leak detection with goleak, snapshot testing, code coverage, integration tests, idiomatic test naming. Use when writing or reviewing Go tests, choosing a testing approach, setting up Go test CI, or debugging flaky/slow tests. For testify-specific APIs see `samber/cc-skills-golang@golang-stretchr-testify`; for measurement methodology see `samber/cc-skills-golang@golang-benchm

    Computed 973,066

    samber/cc-skills-golang

    golang-troubleshooting

    Troubleshoot Golang programs systematically - find and fix the root cause. Use when encountering bugs, crashes, deadlocks, or unexpected behavior in Go code. Covers debugging methodology, common Go pitfalls, test-driven debugging, pprof setup and capture, Delve debugger, race detection, GODEBUG tracing, and production debugging. Start here for any 'something is wrong' situation. Not for interpreting profiles or benchmarking (→ See `samber/cc-skills-golang@golang-benchmark` skill) or applying opt

    Computed 97203

    PramodDutta/qaskills

    Pairwise Test Generator

    Generate optimized test combinations using pairwise (all-pairs) testing algorithms to achieve maximum coverage with minimum test cases across multiple input parameters