effect-ts-idioms
Write idiomatic modern Effect TypeScript using Effect.gen or clear pipelines, typed error channels, Context and Layer services, and resource-safe runtime boundaries. Use when building or reviewing code with Effect, @effect/platform, Schema, Layers, or Effect-based applications.
- License 许可
- MIT
- 最近更新
- 2026-11-11
- Stars
- ★ 0
- Forks
- 0
01 前言 Front Matter
- name
- effect-ts-idioms
- description
- Write idiomatic modern Effect TypeScript using Effect.gen or clear pipelines, typed error channels, Context and Layer services, and resource-safe runtime boundaries. Use when building or reviewing code with Effect, @effect/platform, Schema, Layers, or Effect-based applications.
- compatibility
- opencode
03 SKILL.md 正文
Use this skill to keep Effect code modern, explicit, and faithful to the library's model instead of falling back to Promise-first habits.
Mindset
Effect code should make three things obvious from the type and structure:
- success value
- expected failure mode
- required services/environment
Prefer Effect-native modeling over wrapping Promise code and keeping the old design.
Default style
- Use
Effect.genfor multi-step workflows, branching, and orchestration. - Use
pipe(...)plus combinators for short local transformations. - Keep effects lazy; describe work first, run it only at the program edge.
- Write explicit lambdas instead of point-free or tacit style.
Prefer:
Effect.map((user) => formatUser(user))
Over:
Effect.map(formatUser)
This follows the official guidance to avoid tacit usage because it can hurt inference, overload resolution, and stack traces.
Error modeling
- Put expected domain and operational failures in the error channel.
- Reserve defects for truly unexpected bugs or violated invariants.
- Prefer tagged, structured errors over raw strings.
- Recover close to the boundary where a fallback is meaningful.
Good defaults:
Effect.fail(...)for expected failuresEffect.try(...)/Effect.tryPromise(...)when wrapping throwing or rejecting APIscatchTag,catchAll, andmapErrorfor recovery and translation
Avoid:
- throwing inside
Effect.sync - burying business failures in
Option.none()when the caller needs an explanation - converting everything to
unknownorErrortoo early
Services, Context, and Layers
- Model shared capabilities as services with
Context.Tag. - Provide implementations with
Layerfor reusable dependency graphs. - Keep service interfaces small and capability-oriented.
- Inject services through requirements, not global singletons.
Prefer:
- pure domain functions for pure logic
- service tags for effectful capabilities
- layers at app assembly boundaries
Do not manually thread giant dependency objects through business logic if Effect requirements can model them cleanly.
Resource safety
- Use scoped resource management for files, sockets, clients, subscriptions, locks, and anything requiring cleanup.
- Prefer
Effect.acquireRelease,Effect.addFinalizer, and scoped layers over manual cleanup bookkeeping. - Treat interruption as a normal part of execution, not an edge case.
If something must always be cleaned up, model it in the effect structure rather than relying on convention.
Runtime boundaries
- Run effects at the outermost program boundary.
- In Node apps, prefer
NodeRuntime.runMain(...)for the main program so shutdown is graceful. - Avoid
Effect.runPromiseorEffect.runSyncinside library code, helpers, or domain modules. - Convert external APIs at the edge, then stay inside Effect.
Concurrency and composition
- Use fibers and combinators deliberately; choose sequential vs concurrent behavior explicitly.
- Prefer
Effect.all(...)and concurrency options for independent work. - Use retries, schedules, timeouts, and supervision as first-class tools instead of ad hoc loops.
- Keep concurrent workflows readable; name intermediate effects when needed.
Data modeling
- Prefer
Schemaat boundaries for parsing, validation, and encoding. - Prefer
Option,Either,Data,Chunk,Duration, and other Effect data types when they make semantics clearer. - Avoid
nullandundefinedin domain modeling whenOptionor a tagged union is better.
Interop rules
- Wrap promise-returning APIs with
Effect.tryPromiseunless rejection is impossible. - Wrap callback or event APIs once, then expose an Effect-native interface.
- Keep framework glue thin.
Review checklist
When writing or reviewing Effect code, check:
- Is expected failure in the error channel?
- Are services expressed as requirements instead of hidden globals?
- Is resource cleanup guaranteed by structure?
- Is the runtime only used at the edge?
- Is the code using
Effect.genor pipelines in a way that is easy to follow? - Is this still really Effect code, or just Promise code wrapped at the last second?
04 同仓库更多 Skills
skill-creator
Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, edit, or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy.
modern-astro-v6
Build idiomatic Astro v6 applications with server-first rendering, islands, content collections, actions, and current v6-safe APIs. Use when creating, reviewing, or migrating Astro projects, pages, components, content layers, or integrations.
frontend-design
Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML/CSS layouts, or when styling/beautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics.
elixir-idioms
Write idiomatic Elixir and Phoenix code with pattern matching, small composable functions, OTP-friendly boundaries, and BEAM-aware error handling. Use when creating or reviewing Elixir code, APIs, GenServers, Phoenix apps, Ecto code, or tests.
ash-framework-idioms
Write idiomatic Ash framework code using intentful actions, code interfaces, relationship management, DSL-first modeling, and framework-native changes/preparations instead of ad hoc helper layers. Use when creating or reviewing Ash resources, domains, actions, queries, or Phoenix integrations.