Golang Dependency Injection
samber/cc-skills-golang
Comprehensive guide for dependency injection (DI) in Golang.
Shows how to compose Go functions with fp-go v2 Pipe and Flow: point-free pipelines, predicates, the reader monad, do-notation and tests for pipelines.
$ npx skills add IBM/fp-go --skill fp-go-pipe-flow -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install IBM/fp-go fp-go-pipe-flow --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/IBM/fp-go.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/fp-go-pipe-flow .claude/skills/fp-go-pipe-flow && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "fp-go-pipe-flow" agent skill from https://github.com/IBM/fp-go/tree/main/skills/fp-go-pipe-flow into .claude/skills/fp-go-pipe-flow/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "fp-go-pipe-flow", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/IBM/fp-go/tree/main/skills/fp-go-pipe-flowType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add IBM/fp-go --skill fp-go-pipe-flow -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install IBM/fp-go fp-go-pipe-flow --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/IBM/fp-go.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/fp-go-pipe-flow .agents/skills/fp-go-pipe-flow && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "fp-go-pipe-flow" agent skill from https://github.com/IBM/fp-go/tree/main/skills/fp-go-pipe-flow into .agents/skills/fp-go-pipe-flow/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "fp-go-pipe-flow", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add IBM/fp-go --skill fp-go-pipe-flow -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install IBM/fp-go fp-go-pipe-flow --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/IBM/fp-go.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/fp-go-pipe-flow .cursor/skills/fp-go-pipe-flow && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "fp-go-pipe-flow" agent skill from https://github.com/IBM/fp-go/tree/main/skills/fp-go-pipe-flow into .cursor/skills/fp-go-pipe-flow/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "fp-go-pipe-flow", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/IBM/fp-go.git --path skills/fp-go-pipe-flow--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add IBM/fp-go --skill fp-go-pipe-flow -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install IBM/fp-go fp-go-pipe-flow --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/IBM/fp-go.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/fp-go-pipe-flow .gemini/skills/fp-go-pipe-flow && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "fp-go-pipe-flow" agent skill from https://github.com/IBM/fp-go/tree/main/skills/fp-go-pipe-flow into .gemini/skills/fp-go-pipe-flow/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "fp-go-pipe-flow", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install IBM/fp-go fp-go-pipe-flowInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add IBM/fp-go --skill fp-go-pipe-flow -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/IBM/fp-go.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/fp-go-pipe-flow .github/skills/fp-go-pipe-flow && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "fp-go-pipe-flow" agent skill from https://github.com/IBM/fp-go/tree/main/skills/fp-go-pipe-flow into .github/skills/fp-go-pipe-flow/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "fp-go-pipe-flow", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add IBM/fp-go --skill fp-go-pipe-flow -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install IBM/fp-go fp-go-pipe-flow --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/IBM/fp-go.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/fp-go-pipe-flow .opencode/skills/fp-go-pipe-flow && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "fp-go-pipe-flow" agent skill from https://github.com/IBM/fp-go/tree/main/skills/fp-go-pipe-flow into .opencode/skills/fp-go-pipe-flow/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "fp-go-pipe-flow", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
fp-go-pipe-flowShows how to compose Go functions with fp-go v2 Pipe and Flow: point-free pipelines, predicates, the reader monad, do-notation and tests for pipelines.
The skill covers composing functions with the fp-go v2 library for Go. Pipe threads a starting value through a sequence of functions, and Flow builds a reusable function that waits for its input. The rule of thumb is Pipe when you already have the value and Flow when you are building something reusable. Numbered variants run from Pipe1 to Pipe20 and Flow1 to Flow20, with nothing above 20. Imports must come from github.com/IBM/fp-go/v2, never the v1 path, and pipeline results go in named functions instead of package-level vars.
Further topics include point-free style, the Predicate and Endomorphism type aliases, the generic reader monad with Ask, Asks, Map and Chain, and do-notation with Do, Bind, ApS, Let and LetTo. Because fp-go is rare in training data, the agent should look up unfamiliar combinators through the fp-go MCP server instead of guessing, and run go build and go vet after writing code. An evals file ships with the skill. Lenses and context.Context are handled by the fp-go-lens and fp-go-context skills.
Read from SKILL.md and the folder at commit 1c4245d. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
goFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
fp-go Pipe and Flow loads about 3.5k tokens when it runs. Until then it costs about 159 tokens; SKILL.md has 851 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from IBM/fp-go at commit 1c4245d, republished under its Apache-2.0 licence (© IBM). 851 words, ~3,547 tokens.
.claude/skills/fp-go-pipe-flow/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.All imports must come from github.com/IBM/fp-go/v2, never from
github.com/IBM/fp-go (the v1 path).
fp-go is low-frequency in training data, so signatures are easy to misremember.
For any combinator not shown below, look it up via the fp-go MCP server's
search_examples / get_example tools (see the fp-go-mcp skill) instead of
guessing. After writing code, run go build ./... and go vet ./... and fix any
type-parameter or argument-order errors before presenting it.
Pipe takes an initial value and threads it through a sequence of functions.
Use it when you already have a value to start from.
import F "github.com/IBM/fp-go/v2/function"
// PipeN threads a value through N functions
result := F.Pipe3(initialValue, step1, step2, step3)The number suffix matches the number of transformation steps. Pipe1–Pipe20 and Flow1–Flow20 are generated; there is nothing above 20.
Flow composes N functions into a single function that awaits its input.
Use it to build reusable pipeline functions, especially as arguments to Map,
Chain, or TraverseArray.
// FlowN returns func(T0) TN
pipeline := F.Flow3(step1, step2, step3)
result := pipeline(initialValue)Rule of thumb: prefer Pipe when you have the starting value; use Flow
when you are building a reusable function.
Go does not eliminate dead variables, but unused functions are zero-cost.
Always wrap a Pipe/Flow result in a named function rather than storing it
in a package-level var.
// WRONG — var is allocated even if never called
var processUser = F.Flow2(getName, strings.ToUpper)
// CORRECT — zero cost until called; also more composable
func processUser() func(User) string {
return F.Flow2(getName, strings.ToUpper)
}Use var only for lenses and pre-bound combinator helpers (like lens.Get
assigned to a named getter), not for full pipeline results.
Avoid explicit argument names wherever a named combinator or Flow can express
the same thing.
// WRONG — explicit argument
func isAdult(u User) bool { return getAge(u) > 18 }
// CORRECT — point-free, returns typed Predicate
func isAdult() P.Predicate[User] {
return F.Flow2(getAge, N.MoreThan(18))
}| Type | Package | Meaning |
|---|---|---|
P.Predicate[A] | github.com/IBM/fp-go/v2/predicate | func(A) bool |
EM.Endomorphism[A] | github.com/IBM/fp-go/v2/endomorphism | func(A) A |
Use these as return types for functions that act as predicates or
self-transformations — they communicate intent and enable direct use in
combinators like A.Filter, A.Map, F.Ternary.
import (
F "github.com/IBM/fp-go/v2/function"
N "github.com/IBM/fp-go/v2/number"
P "github.com/IBM/fp-go/v2/predicate"
EM "github.com/IBM/fp-go/v2/endomorphism"
A "github.com/IBM/fp-go/v2/array"
)
// Predicate — point-free using N.MoreThan
func isAdult() P.Predicate[User] {
return F.Flow2(getAge, N.MoreThan(18))
}
// Endomorphism — self-transformation
func doubleAll() EM.Endomorphism[[]int] {
return A.Map[int, int](N.Mul(2))
}Prefer N.MoreThan, N.LessThan, N.Mul, N.Add etc. over inline
comparisons or arithmetic in lambdas:
N.MoreThan(18) // func(int) bool — x > 18
N.LessThan(100) // func(int) bool — x < 100
N.Mul(2) // func(int) int — x * 2
N.Add(1) // func(int) int — x + 1Only use the reader monad when the computation genuinely needs an environment
(context, config, DB, logger, etc.). For pure transformations that don't
need external input, use Flow or Pipe directly — no reader wrapping needed.
// WRONG — forces reader monad on a pure computation
func adultNames(users []User) RD.Reader[Env, string] {
return F.Pipe1(
RD.Of[Env](users),
RD.Map[Env](pureTransform),
)
}
// CORRECT — pure; no environment needed
func adultNames() func([]User) string {
return F.Flow2(
A.FilterMap(toAdultName()),
A.Intercalate(S.Monoid)(","),
)
}A.FilterMapWhen filtering and then extracting a field, combine both into a single pass
with A.FilterMap and O.FromPredicate:
import (
F "github.com/IBM/fp-go/v2/function"
A "github.com/IBM/fp-go/v2/array"
O "github.com/IBM/fp-go/v2/option"
N "github.com/IBM/fp-go/v2/number"
P "github.com/IBM/fp-go/v2/predicate"
S "github.com/IBM/fp-go/v2/string"
)
// isAdult — point-free predicate
func isAdult() P.Predicate[User] {
return F.Flow2(getAge, N.MoreThan(18))
}
// toAdultName — User -> Option[string]: Some(name) if adult, None otherwise
func toAdultName() func(User) O.Option[string] {
return F.Flow2(
O.FromPredicate(isAdult()), // User -> Option[User]
O.Map(getName), // Option[User] -> Option[string]
)
}
// adultNames — pure pipeline, no reader monad needed
func adultNames() func([]User) string {
return F.Flow2(
A.FilterMap(toAdultName()), // []User -> []string
A.Intercalate(S.Monoid)(","), // []string -> string
)
}The reader monad Reader[R, A] is func(R) A — a computation that reads
from an environment R and produces A. Only reach for it when the
computation needs to thread an environment (a config struct, a repository,
…). For context.Context plus IO and errors use context/readerioresult
(RIO) instead — see the fp-go-context skill.
import (
F "github.com/IBM/fp-go/v2/function"
RD "github.com/IBM/fp-go/v2/reader"
)
type Env struct {
Users map[string]User
}
// Leaf accessor (or a generated lens' .Get)
func getUsers(e Env) map[string]User { return e.Users }
// lookupUser is curried: func(id string) func(map[string]User) User
// Kleisli arrow: string -> Reader[Env, User], built from a pure projection
func fetchUser(id string) RD.Reader[Env, User] {
return RD.Asks(F.Flow2(getUsers, lookupUser(id)))
}reader.Map vs Full Pipe with Reader Operationsreader.Map inside Flow — when the step is pure and the environment
does not need to appear explicitly. This is the "abbreviation" pattern.Pipe with reader.Chain, reader.Bind, reader.ApS — when the
sequence needs the environment (e.g. calls another kleisli arrow) or when
do-notation makes the data flow clearer.// reader.Map inside Flow — no env name, clean point-free.
// NOTE: RD.Map returns an Operator over Reader values, so the PRECEDING step in the
// Flow must already produce a Reader. A plain func([]User) []string composed with
// RD.Map does not type-check.
func renderUsers() func(string) RD.Reader[Env, string] {
return F.Flow2(
fetchTeam, // string -> Reader[Env, []User]
RD.Map[Env](F.Flow2( // Reader[Env, []User] -> Reader[Env, string]
A.Map(getName),
A.Intercalate(S.Monoid)(","),
)),
)
}
// Pipe with reader monad — env access required
func enrichedUser(id string) RD.Reader[Env, EnrichedUser] {
return F.Pipe3(
fetchUser(id),
RD.Chain(fetchProfile),
RD.Chain(fetchPermissions),
RD.Map[Env](combineToEnriched),
)
}Do / Bind / ApS / LetDo-notation is the idiomatic way to assemble multiple reader (or IO/result)
computations into a named-field record. Always use it inside a Pipe.
import (
F "github.com/IBM/fp-go/v2/function"
L "github.com/IBM/fp-go/v2/optics/lens"
RD "github.com/IBM/fp-go/v2/reader"
)
// Lenses — generated (`// fp-go:Lens`) or built once with L.MakeLens.
// lens.Set already has the setter shape func(T) func(S) S — no hand-written setters.
var (
userIDLens = L.MakeLens(
func(s RequestState) string { return s.UserID },
func(s RequestState, v string) RequestState { s.UserID = v; return s },
)
profileLens = L.MakeLens(
func(s RequestState) Profile { return s.Profile },
func(s RequestState, v Profile) RequestState { s.Profile = v; return s },
)
permsLens = L.MakeLens(
func(s RequestState) Perms { return s.Perms },
func(s RequestState, v Perms) RequestState { s.Perms = v; return s },
)
)
// Kleisli arrows — named functions, never inline:
// fetchProfile: func(userID string) Reader[Env, Profile]
// fetchPerms: func(p Profile) Reader[Env, Perms]
// Pipeline — returned as a function, not a var
func buildRequestState(userID string) RD.Reader[Env, RequestState] {
return F.Pipe3(
RD.Do[Env](RequestState{}),
RD.LetTo[Env](userIDLens.Set, userID),
RD.Bind(profileLens.Set, F.Flow2(userIDLens.Get, fetchProfile)),
RD.Bind(permsLens.Set, F.Flow2(profileLens.Get, fetchPerms)),
)
}F.Flow2(lens.Get, kleisli) is the point-free way to feed one field of the
accumulated state into the next step.
Bind vs ApS vs Let| Combinator | When to use |
|---|---|
Bind(setter, kleisli) | Result depends on accumulated state (sequential) |
ApS(setter, reader) | Result is independent of other fields |
Let(setter, pureFunc) | Pure transformation of accumulated state, no reader needed |
LetTo(setter, value) | Attach a constant value to state |
Use ApS when values can be computed independently; Bind when a later step
depends on an earlier one. Mixing them in the same pipeline is normal. A Bind
whose Kleisli ignores the state (func(_ S) M[T] { return m }) is always an
ApS(setter, m).
Never access struct fields with inline functions inside a Pipe. Create a
lens (preferably generated with // fp-go:Lens, see the fp-go-lens skill)
or a named leaf accessor so the pipeline stays point-free.
import (
L "github.com/IBM/fp-go/v2/optics/lens"
)
var hostLens = L.MakeLens(
func(c Config) string { return c.Host },
func(c Config, v string) Config { c.Host = v; return c },
)
// Assign lens.Get to a named var — then pass it anywhere point-free
var getHost = hostLens.Get // func(Config) string
var getPort = portLens.Get // func(Config) intUse RD.ApSL(lens, reader) / RD.BindL(lens, kleisli) as do-notation variants
that take a lens directly instead of a setter function.
Generate a _test.go for every non-trivial pipeline or flow.
func TestAdultNames(t *testing.T) {
users := []User{{Name: "Alice", Age: 25}, {Name: "Bob", Age: 16}}
assert.Equal(t, "Alice", adultNames()(users))
}
func TestBuildRequestState(t *testing.T) {
env := Env{Users: map[string]User{"user-42": {ID: "user-42"}}}
state := buildRequestState("user-42")(env)
assert.Equal(t, "user-42", state.UserID)
}Flow/Pipe functions: call the returned function with a concrete
value and assert with assert.Equal.IOResult/ReaderIOResult: call the innermost IO thunk and compare
with R.Of(expected); run a ReaderIOResult with t.Context().These follow the canonical alias table in the fp-go skill.
import (
F "github.com/IBM/fp-go/v2/function"
A "github.com/IBM/fp-go/v2/array"
O "github.com/IBM/fp-go/v2/option"
E "github.com/IBM/fp-go/v2/either"
R "github.com/IBM/fp-go/v2/result"
IOR "github.com/IBM/fp-go/v2/ioresult"
RD "github.com/IBM/fp-go/v2/reader"
RIO "github.com/IBM/fp-go/v2/context/readerioresult"
L "github.com/IBM/fp-go/v2/optics/lens"
N "github.com/IBM/fp-go/v2/number"
S "github.com/IBM/fp-go/v2/string"
P "github.com/IBM/fp-go/v2/predicate"
EM "github.com/IBM/fp-go/v2/endomorphism"
)| Goal | Pattern |
|---|---|
| Thread a value through N steps | F.PipeN(value, f1, f2, …) |
| Build a reusable function | F.FlowN(f1, f2, …) |
| Point-free numeric predicate | F.Flow2(getField, N.MoreThan(n)) returning P.Predicate[T] |
| Filter+map in one pass | A.FilterMap(F.Flow2(O.FromPredicate(pred), O.Map(f))) |
| Lift a pure function into Reader | RD.Map[Env](pureFunc) |
| Chain kleisli arrows | RD.Chain(kleisliFunc) |
| Start do-notation block | RD.Do[Env](emptyStruct) |
| Add dependent field | RD.Bind(lens.Set, F.Flow2(otherLens.Get, kleisliFunc)) |
| Add independent field | RD.ApS(lens.Set, readerValue) |
| Add pure derived field | RD.Let[Env](lens.Set, F.Flow2(otherLens.Get, pureFunc)) |
| Lens getter in pipeline | var getX = xLens.Get |
| Do-notation with lens | RD.ApSL(lens, readerValue) |
| Access full environment | RD.Ask[Env]() |
| Access field of environment | RD.Asks(getX) |
Read a context.Context value | RIO.AskValue[V](key) → Option[V] (not ctx.Value(key).(V)) |
| Scope a value / timeout to a step | RIO.WithValue[A](key, v), RIO.WithTimeout[A](d) as the last Pipe step |
© IBM, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 1 other file in skills/fp-go-pipe-flow of IBM/fp-go.
Open the folder on GitHubat commit 1c4245d
fp-go Pipe and Flow next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| fp-go Pipe and Flow this skillIBM/fp-go | 2k | — | ~3.5k | Automated safety check: Pass | Apache-2.0 | |
| Golang Dependency Injectionsamber/cc-skills-golang | 3.4k | — | ~3.2k | Automated safety check: Pass | MIT | |
| Golang Samber Docontext-labs/whip | 1.1k | 1 repos | ~2.3k | Automated safety check: Pass | MIT | |
| Swiftui View RefactorDimillian/Skills | 4k | 5 repos | ~2k | Automated safety check: Pass | MIT | |
| RTK Rust Design Patternsrtk-ai/rtk | 83k | — | ~1.9k | Automated safety check: Pass | Apache-2.0 | |
| Architecture PatternsKartikLabhshetwar/better-shot | 2.4k | 2 repos | ~1.4k | Automated safety check: Pass | Custom licence |
samber/cc-skills-golang
Comprehensive guide for dependency injection (DI) in Golang.
context-labs/whip
Dependency injection in Go using samber/do — service containers, lifecycle, scopes, health checks, graceful shutdown, module organization.
Dimillian/Skills
Refactor and review SwiftUI view files with strong defaults for small dedicated subviews, MV-over-MVVM data flow, stable view trees, explicit dependency injection, and correct Observation usage.
rtk-ai/rtk
Describes seven Rust design patterns for the RTK CLI filter modules, with when to use each, RTK examples, and notes on when a pattern is overkill.
KartikLabhshetwar/better-shot
Deep dive into software architecture for macOS. An agent skill from KartikLabhshetwar/better-shot.
prisma/orm
Replaces a plain TypeScript union plus switch statements with frozen subclasses and a visitor interface when several places dispatch on the same variants.
IBM/fp-go
Covers handling Go's context.Context idiomatically in fp-go code: reading and scoping context through operators, timeouts, cancellation and converting ctx-first functions.
IBM/fp-go
Teaches an agent to write fp-go v2 services with the Effect type, carrying dependencies in its type parameter instead of in context.Context or parameters.
IBM/fp-go
Shows how to build composable, context-aware HTTP pipelines in Go using fp-go's ReaderIOResult monad instead of raw net/http calls.
IBM/fp-go
Generates or hand-writes composable lenses for the fp-go library so nested Go structs can be read and updated immutably.
IBM/fp-go
Adds logging to fp-go functional pipelines with Tap operators, entry and exit logs and error context, so that logging never changes the value or error flowing through.
IBM/fp-go
Configures and queries the fp-go MCP server so Claude Code, Claude Desktop or another MCP client can search fp-go's examples and skills directly.
Works with
Categories
Shows how to compose Go functions with fp-go v2 Pipe and Flow: point-free pipelines, predicates, the reader monad, do-notation and tests for pipelines. The skill covers composing functions with the fp-go v2 library for Go. Pipe threads a starting value through a sequence of functions, and Flow builds a reusable function that waits for its input.
fp-go Pipe and Flow fits situations like: writing point-free pipelines with fp-go v2; choosing between Pipe and Flow for a new function; refactoring nested calls or imperative Go into a pipeline; writing unit tests for fp-go pipelines.
Run `npx skills add IBM/fp-go --skill fp-go-pipe-flow -a claude-code`. Or copy the skill folder (skills/fp-go-pipe-flow in IBM/fp-go) into .claude/skills/fp-go-pipe-flow in your project. Claude Code loads it when a task matches its description.
Run `npx skills add IBM/fp-go --skill fp-go-pipe-flow -a codex`. Or copy the skill folder (skills/fp-go-pipe-flow in IBM/fp-go) into .agents/skills/fp-go-pipe-flow in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add IBM/fp-go --skill fp-go-pipe-flow -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/fp-go-pipe-flow, .gemini/skills/fp-go-pipe-flow, .github/skills/fp-go-pipe-flow and .opencode/skills/fp-go-pipe-flow in your project.
Going by SKILL.md and its folder, fp-go Pipe and Flow needs the command-line tools its instructions call (go). Our summary lists: A Go project that uses fp-go v2; The Go toolchain for go build and go vet.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
fp-go Pipe and Flow is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.5k tokens (SKILL.md is roughly 14k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with fp-go Pipe and Flow: Golang Dependency Injection (samber/cc-skills-golang, 3.4k stars), Golang Samber Do (context-labs/whip, 1.1k stars), Swiftui View Refactor (Dimillian/Skills, 4k stars) and RTK Rust Design Patterns (rtk-ai/rtk, 83k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
IBM (a GitHub organization, an official publisher) maintains it in IBM/fp-go, which has 2,029 GitHub stars. The repository holds 10 skills in this directory. The repository was last updated on October 7, 2026.
Source: IBM/fp-go on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.