RTK Rust Design Patterns
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.
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.
$ npx skills add IBM/fp-go --skill fp-go-effect -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install IBM/fp-go fp-go-effect --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-effect .claude/skills/fp-go-effect && 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-effect" agent skill from https://github.com/IBM/fp-go/tree/main/skills/fp-go-effect into .claude/skills/fp-go-effect/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "fp-go-effect", 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-effectType 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-effect -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install IBM/fp-go fp-go-effect --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-effect .agents/skills/fp-go-effect && 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-effect" agent skill from https://github.com/IBM/fp-go/tree/main/skills/fp-go-effect into .agents/skills/fp-go-effect/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "fp-go-effect", 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-effect -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install IBM/fp-go fp-go-effect --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-effect .cursor/skills/fp-go-effect && 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-effect" agent skill from https://github.com/IBM/fp-go/tree/main/skills/fp-go-effect into .cursor/skills/fp-go-effect/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "fp-go-effect", 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-effect--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-effect -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install IBM/fp-go fp-go-effect --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-effect .gemini/skills/fp-go-effect && 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-effect" agent skill from https://github.com/IBM/fp-go/tree/main/skills/fp-go-effect into .gemini/skills/fp-go-effect/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "fp-go-effect", 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-effectInstalls 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-effect -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-effect .github/skills/fp-go-effect && 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-effect" agent skill from https://github.com/IBM/fp-go/tree/main/skills/fp-go-effect into .github/skills/fp-go-effect/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "fp-go-effect", 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-effect -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-effect --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-effect .opencode/skills/fp-go-effect && 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-effect" agent skill from https://github.com/IBM/fp-go/tree/main/skills/fp-go-effect into .opencode/skills/fp-go-effect/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "fp-go-effect", 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-effectTeaches 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.
The skill explains Effect[C, A] from the fp-go v2 effect package, where the type parameter C carries long-lived dependencies such as repositories, database and HTTP clients, configuration and tool registries, while context.Context keeps request-scoped data such as cancellation and trace IDs. Rules follow from that split: declare the narrowest C per function, never store dependencies in the context or a global, and Provide once at startup and RunSync per request so the compiler checks the wiring.
It also covers designing capability interfaces (XxxDeps with getters, MakeXxxDeps and AsXxxDeps), narrowing and widening them with Local, lifting ordinary Go functions and methods with Eitherize, Eitherize1, Asks and FromIdiomatic, building dependencies with an Effect, and testing with fakes. Because fp-go is thinly represented in training data, the agent should look up unfamiliar combinators through the fp-go MCP server, then run go build and go vet before presenting code.
5 steps, taken from the first numbered list in SKILL.md.
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.
Typed Dependencies with fp-go Effect loads about 4.3k tokens when it runs. Until then it costs about 250 tokens; SKILL.md has 1,510 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). 1,510 words, ~4,326 tokens.
.claude/skills/fp-go-effect/SKILL.md (or your agent's skills folder).C Is for Dependencies// Effect[C, A] = func(C) func(context.Context) func() Result[A]
type Effect[C, A any] = readerreaderioresult.ReaderReaderIOResult[C, A]An Effect takes three inputs, and each input has its own job:
| Input | Carries | Supplied |
|---|---|---|
C | dependencies: long-lived collaborators such as repositories, DB and HTTP clients, SDK clients, configuration, environment access, tool registries, clocks | once, at the composition root, with EF.Provide |
context.Context | request scope: cancellation, deadlines, request / trace IDs, authenticated principal, request logger | once per run, with EF.RunSync(...)(ctx) |
Kleisli argument (func(A) Effect[C, B]) | per-call input: IDs, payloads, the value flowing through the pipeline | as a function argument |
Rules that follow from this:
C. Never store it in context.Context (untyped, unchecked, panics on a missing key). Never pass it as a parameter through every layer, and never keep it in a package-level global.C is a type, so the compiler checks the wiring. A function's signature Effect[UserDeps, User] states exactly what it needs. Code that forgets to provide something does not compile.C per function. A function that only reads users asks for UserDeps, not for the whole application. Widen it with Local where it is composed.Provide it, and RunSync per request with that request's context.context.Context (see the fp-go-context skill). If a value differs per request, it is not a dependency.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.
| Situation | Use |
|---|---|
Needs only context.Context (no collaborators) | context/readerioresult (RIO) |
| Needs any collaborator: client, repository, config, env, registry | Effect[C, A] |
| Pure computation | a plain function or Flow, no monad |
Effect is the recommended top-level monad for service code. Every RIO operator still works inside it (see "Runtime Context Inside an Effect").
Each package that needs something from outside declares a small capability interface with getter methods, a private implementation, a constructor and a generic upcast helper:
package users
// UserRepo is the port; the adapter (Postgres, in-memory, fake) implements it.
type UserRepo interface {
FindUser(ctx context.Context, id int) (User, error)
}
// UserDeps is what this package needs from its environment.
type UserDeps interface {
GetUserRepo() UserRepo
}
type userDeps struct{ repo UserRepo }
func (d *userDeps) GetUserRepo() UserRepo { return d.repo }
// MakeUserDeps is the only way to build the dependency.
func MakeUserDeps(repo UserRepo) UserDeps { return &userDeps{repo} }
// AsUserDeps upcasts any wider dependency that embeds UserDeps.
// It is used with EF.Local to run a UserDeps effect inside a wider C.
func AsUserDeps[R UserDeps](r R) UserDeps { return r }GetLookupEnv() IOR.Kleisli[string, string] or GetRequestOptions() EF.Thunk[[]Option]. A capability that is a function is trivial to fake and is only evaluated when the effect runs.XxxDeps interface lists what this package uses, typically one to three getters.A plain struct of fields (type Deps struct{ DB DB; Config Config }) also works for a small program. Capability interfaces scale better, because every package keeps its own narrow view and the composite is assembled by embedding.
Higher layers combine the capabilities of the packages they use. The interface embeds interfaces, and the implementation embeds the implementations:
package app
type AppDeps interface {
users.UserDeps
mail.MailDeps
}
type appDeps struct {
users.UserDeps
mail.MailDeps
}
func MakeAppDeps(u users.UserDeps, m mail.MailDeps) AppDeps { return &appDeps{u, m} }Because Go generics are invariant, an Effect[UserDeps, A] is not an Effect[AppDeps, A], even though AppDeps embeds UserDeps. Local performs that conversion (next sections).
The leaves are where Go code meets the effect. Lift, never hand-write the nested closures:
| Go shape | Lift with | Result |
|---|---|---|
interface method func(Repo, ctx, A) (B, error) (method expression Repo.Find) | EF.Eitherize1(Repo.Find) | Kleisli[Repo, A, B] |
func(C, ctx) (B, error) | EF.Eitherize(f) | Effect[C, B] |
func(C, ctx, A) (B, error) | EF.Eitherize1(f) | Kleisli[C, A, B] |
service method func(A) func(ctx, C) (B, error) | EF.FromIdiomatic(f) | Kleisli[C, A, B] |
pure getter / projection func(C) A | EF.Asks(f), e.g. EF.Asks(MailDeps.GetSender) | Effect[C, A] |
| the whole dependency | EF.Ask[C]() | Effect[C, C] |
dependency-free ReaderIOResult[A] | EF.FromThunk[C](t) | Effect[C, A] |
Result[A], IO[A], value, error | EF.FromResult[C], EF.FromIO[C], EF.Of[C], EF.Fail[C, A] | Effect[C, A] |
Interface method expressions make the leaves point-free. The receiver becomes the dependency, and Local with the getter fetches it from the capability interface:
func FindUser() EF.Kleisli[UserDeps, int, User] {
return F.Flow2(
EF.Eitherize1(UserRepo.FindUser), // Kleisli[UserRepo, int, User]
EF.Local[User](UserDeps.GetUserRepo), // run it on UserDeps
)
}Asks is for pure projections only. Effect[C, A] is func(C) ReaderIOResult[A], so EF.Asks(func(c C) ReaderIOResult[A] {...}) silently yields the nested Effect[C, ReaderIOResult[A]]. For a getter that returns an effectful capability, use Asks followed by ChainThunkK:
func LookupEnv(key string) EF.Effect[EnvDeps, string] {
return F.Pipe1(
EF.Asks(EnvDeps.GetLookupEnv), // Effect[EnvDeps, IOR.Kleisli[string, string]]
EF.ChainThunkK[EnvDeps](F.Flow2(
RD.Read[IOR.IOResult[string]](key), // apply the capability to key
RIO.FromIOResult[string],
)),
)
}LocalEF.Local[A](f) takes f: C1 → C2 (from what you have to what the effect needs) and turns an Effect[C2, A] into an Effect[C1, A]. With the AsXxxDeps helpers this is how a narrow effect runs inside a wide dependency:
func NotifyUser() EF.Kleisli[AppDeps, int, MessageID] {
findUser := F.Flow2(users.FindUser(), EF.Local[User](users.AsUserDeps[AppDeps]))
sendMail := F.Flow2(mail.SendMail(), EF.Local[MessageID](mail.AsMailDeps[AppDeps]))
return F.Flow3(
findUser,
EF.Map[AppDeps](F.Flow2(getEmail, welcome)),
EF.Chain(sendMail),
)
}Local needs only the value type [A]. C1 and C2 are inferred from f, and AsXxxDeps[Wide] fixes the generic helper to the wide type.Asks + Map versus Local: build a new effect from a getter and a pure function with EF.Asks(getter) plus EF.Map[C](f). Use Local when you already have an Effect[C2, A] (a Kleisli defined elsewhere) and want to reuse it unchanged under another C.EF.ContraMap is an alias of Local.effect combinators (Asks, Map, Ap, Chain, ChainThunkK, FromThunk, Local). Do not rebuild Effect's nested reader shape by hand with reader / context/readerioresult. That also type-checks, but it depends on the internal representation and is hard to read.When deriving the inner dependency needs more than a pure function, use the Local*K variants (f goes from the outer to the inner dependency):
f | Operator |
|---|---|
C1 → C2, pure | Local / ContraMap |
C1 → Reader[context.Context, C2] | LocalReaderK |
C1 → IO[C2] | LocalIOK |
C1 → Result[C2] (validation) | LocalResultK |
C1 → IOResult[C2] | LocalIOResultK |
C1 → ReaderIOResult[C2] | LocalThunkK |
C1 → Effect[C1, C2] (most general) | LocalEffectK |
Effect has the full API of the other monads. Mind the leading type parameters, which C often cannot be inferred for:
| Operation | Form |
|---|---|
| transform the value | EF.Map[C](f) (Map[C, A, B]: annotate C) |
| sequence a Kleisli | EF.Chain(k) (inferred from k) |
| combine independent effects | EF.Ap[B](fa) on an Effect[C, func(A) B] |
| do-notation | EF.Do[C](S{}), EF.Bind(lens.Set, k), EF.ApS(lens.Set, eff), EF.ApSL(lens, eff), EF.Let |
| lift other monads mid-pipeline | EF.ChainResultK, EF.ChainIOK, EF.ChainThunkK[C], EF.ChainReaderK |
| side effects | EF.Tap(k), EF.TapIOK[C](f), EF.TapThunkK[C](f) |
| recover / alternative | EF.ChainLeft(k), EF.Alt(LZ.Of(other)), EF.TapLeft[A](k) |
| slices | EF.TraverseArray(k) |
| retries | EF.Retrying(policy, action, check) |
| run | EF.Provide[A](deps), then EF.RunSync(thunk)(ctx) |
Ap[B, C, A] and Provide[A, C] lead with the type that cannot be inferred. Write EF.Ap[ChatDeps](apiKey) and EF.Provide[User](deps).
Constructing a dependency is often effectful itself: reading an environment variable, loading a file, opening a connection. Model the constructor as an Effect over the bootstrap capabilities:
type BootDeps interface {
env.EnvDeps
GetMailer() Mailer
}
// The sender address is read lazily from the environment when the effect runs.
func MakeMailDepsFromEnv() EF.Effect[BootDeps, MailDeps] {
sender := F.Pipe1(env.LookupEnv("MAIL_SENDER"), EF.Local[string](env.AsEnvDeps[BootDeps]))
return F.Pipe1(
EF.Asks(F.Flow2(BootDeps.GetMailer, F.Curry2(MakeMailDeps))), // Effect[BootDeps, func(string) MailDeps]
EF.Ap[MailDeps](sender),
)
}Run it once at startup and provide the result. Alternatively, EF.LocalEffectK[A](F.Constant1[BootDeps](MakeMailDepsFromEnv())) runs a MailDeps effect directly on BootDeps, building the dependency on every run. A missing variable fails the effect with a normal error. Nothing panics.
The composition root (main, server setup, CLI command) is the only place that builds concrete dependencies and runs effects:
func main() {
deps := app.MakeAppDeps(
users.MakeUserDeps(postgres.NewUserRepo(db)),
mail.MakeMailDeps(smtp.NewMailer(cfg), cfg.Sender),
)
http.HandleFunc("/notify", func(w http.ResponseWriter, r *http.Request) {
id, err := EF.RunSync(EF.Provide[MessageID](deps)(app.NotifyUser()(userID(r))))(r.Context())
// write id or err
})
}Provide eliminates C and yields a ReaderIOResult[A]. RunSync runs it with a context.Context and returns an idiomatic (A, error). Alternatively, thunk(ctx)() yields a Result[A].context.Background().Effect or Kleisli values. Only the edge calls Provide and RunSync.EF.Local, EF.Ask and EF.Asks operate on C. To scope the runtime context.Context, lift any context/readerioresult operator over C with reader.Map:
F.Pipe1(
app.NotifyUser()(42),
RD.Map[AppDeps](RIO.WithTimeout[MessageID](2*time.Second)), // Effect[AppDeps, MessageID]
)
RD.Map[AppDeps](RIO.WithValue[MessageID](requestIDKey, id))
RD.Map[AppDeps](RIO.LogEntryExit[MessageID]("notifyUser"))Tests supply fakes through the same constructors production code uses. No mocking framework and no global state are needed:
type fakeRepo map[int]User
func (r fakeRepo) FindUser(_ context.Context, id int) (User, error) {
if u, ok := r[id]; ok {
return u, nil
}
return User{}, errNotFound
}
func TestFindUser(t *testing.T) {
deps := users.MakeUserDeps(fakeRepo{1: {ID: 1, Email: "a@x"}}) // only what FindUser declares
u, err := EF.RunSync(EF.Provide[User](deps)(users.FindUser()(1)))(t.Context())
assert.NoError(t, err)
assert.Equal(t, "a@x", u.Email)
_, err = EF.RunSync(EF.Provide[User](deps)(users.FindUser()(2)))(t.Context())
assert.ErrorIs(t, err, errNotFound)
}Cs.t.Context().MakeToolDeps(fakeCaller) where the getter returns a lookup function built from a map.| Mistake | Fix |
|---|---|
ctx.Value("db").(DB) or context.WithValue(ctx, dbKey, db) | The DB is a dependency: put it in C behind a getter |
Passing db, client, cfg as parameters through every function | Return Effect[XxxDeps, A] / Kleisli; the dependency travels in C |
Package-level var client = ... singletons | Build in MakeXxxDeps, provide at the edge |
Request IDs, principal or deadlines in C | They vary per request: context.Context (RIO.WithValue, RIO.WithTimeout via RD.Map[C]) |
One huge AppDeps as C of every function | Declare the narrowest XxxDeps; widen with EF.Local[A](AsXxxDeps[Wide]) |
Effect[AppDeps, A] expected, Effect[UserDeps, A] given, "fixed" with a type assertion | Generics are invariant: use EF.Local with the AsXxxDeps helper |
EF.Asks(func(c C) RIO.ReaderIOResult[A] {...}) | Yields Effect[C, ReaderIOResult[A]]. Use EF.Eitherize / Eitherize1 / FromIdiomatic, or Asks + ChainThunkK |
Hand-written func(c C) func(ctx) func() Result[A] around a Go method | EF.Eitherize1(Iface.Method) + EF.Local[B](Deps.GetIface) |
Rebuilding Effect with reader.Map / RIO internals | Compose with EF.Asks, Map, Ap, Chain, ChainThunkK, FromThunk, Local |
EF.Map(f), EF.Provide(deps) without annotation | EF.Map[C](f), EF.Provide[A](deps) |
| Building dependencies inside the request handler | Build once at startup; provide per run |
Provide / RunSync inside library code | Return the Effect; only the edge runs it |
C = context.Context | That is RIO; use context/readerioresult directly |
C, not from context.Context, globals or threaded parameters.XxxDeps interface with getters, a private implementation, MakeXxxDeps and AsXxxDeps.C and are widened with EF.Local[A](AsXxxDeps[Wide]).Eitherize / Eitherize1 / FromIdiomatic / Asks; no hand-written nested closures.Asks receives only pure projections.context.Context; runtime scoping uses RD.Map[C](RIO.…).Provide and RunSync appear only there and in tests.MakeXxxDeps and run with t.Context().import (
EF "github.com/IBM/fp-go/v2/effect"
RIO "github.com/IBM/fp-go/v2/context/readerioresult"
RD "github.com/IBM/fp-go/v2/reader"
IOR "github.com/IBM/fp-go/v2/ioresult"
F "github.com/IBM/fp-go/v2/function"
LZ "github.com/IBM/fp-go/v2/lazy"
R "github.com/IBM/fp-go/v2/result"
)See also the fp-go skill (core types, aliases), fp-go-context (request-scoped values, timeouts) and fp-go-logging.
© 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
Just SKILL.md in skills/fp-go-effect of IBM/fp-go.
Open the folder on GitHubat commit 1c4245d
Typed Dependencies with fp-go Effect 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 |
|---|---|---|---|---|---|---|
| Typed Dependencies with fp-go Effect this skillIBM/fp-go | 2k | — | ~4.3k | Automated safety check: Pass | Apache-2.0 | |
| RTK Rust Design Patternsrtk-ai/rtk | 83k | — | ~1.9k | Automated safety check: Pass | Apache-2.0 | |
| AST Visitor Pattern for Unionsprisma/orm | 48k | — | ~830 | Automated safety check: Pass | Apache-2.0 | |
| Valgocohesivestack/valgo | 508 | — | ~2.4k | Automated safety check: Pass | MIT | |
| Gograph Go Repository Intelligenceozgurcd/gograph | 227 | — | ~4.8k | Automated safety check: Notes | MIT | |
| Golang Dependency Injectionsamber/cc-skills-golang | 3.4k | — | ~3.2k | Automated safety check: Pass | MIT |
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.
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.
cohesivestack/valgo
Add, refactor, debug, review, explain, or migrate type-safe validation in consumer Go applications using github.com/cohesivestack/valgo.
ozgurcd/gograph
Gives an agent working in a Go codebase a structural view through a local MCP server: call graphs, blast-radius and impact analysis, and bounded first-call exploration.
samber/cc-skills-golang
Comprehensive guide for dependency injection (DI) in Golang.
context-labs/whip
Golang semantic code intelligence via gopls — go-to-definition, references, call hierarchy, symbols, diagnostics, rename, refactors.
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
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.
IBM/fp-go
Guides writing or reviewing point-free, first-match-wins case lists in fp-go v2 Go code instead of switch statements and if-else chains.
Works with
Categories
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. Context keeps request-scoped data such as cancellation and trace IDs. Rules follow from that split: declare the narrowest C per function, never store dependencies in the context or a global, and Provide once at startup and RunSync per request so the compiler checks the wiring.
Typed Dependencies with fp-go Effect fits situations like: writing or reviewing fp-go v2 service code built on the effect package; adding database, HTTP client or config dependencies to an Effect-based service; replacing clients stored in context.Context with typed dependencies; testing Effect code with fake dependencies.
Run `npx skills add IBM/fp-go --skill fp-go-effect -a claude-code`. Or copy the skill folder (skills/fp-go-effect in IBM/fp-go) into .claude/skills/fp-go-effect in your project. Claude Code loads it when a task matches its description.
Run `npx skills add IBM/fp-go --skill fp-go-effect -a codex`. Or copy the skill folder (skills/fp-go-effect in IBM/fp-go) into .agents/skills/fp-go-effect 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-effect -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-effect, .gemini/skills/fp-go-effect, .github/skills/fp-go-effect and .opencode/skills/fp-go-effect in your project.
Going by SKILL.md and its folder, Typed Dependencies with fp-go Effect needs the command-line tools its instructions call (go). Our summary lists: Go with the fp-go v2 library; The fp-go MCP server for looking up combinators.
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.
Typed Dependencies with fp-go Effect 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 4.3k tokens (SKILL.md is roughly 17k 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 Typed Dependencies with fp-go Effect: RTK Rust Design Patterns (rtk-ai/rtk, 83k stars), AST Visitor Pattern for Unions (prisma/orm, 48k stars), Valgo (cohesivestack/valgo, 508 stars) and Gograph Go Repository Intelligence (ozgurcd/gograph, 227 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.