Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/andabove-effect-services
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: frontend, backend
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/effect-services
What's inside
- Skill name
effect-services- Description
- Effect 4 services, layers and resources. Use when you define, compose or provide a dependency with Context.Service, Context.Reference or Layer, manage a resource lifetime with Scope or acquireRelease, read configuration with Config, run Effect code inside Hono, Express, Next.js, Nitro or another framework through ManagedRuntime, or use a platform service such as FileSystem or Path.
- License
- MIT
- Instructions
- 262 lines in SKILL.md · view on GitHub
Files (6)
- SKILL.md
- effect-services-config.md · references/
- effect-services-frameworks.md · references/
- effect-services-layers.md · references/
- effect-services-platform.md · references/
- effect-services-resources.md · references/
SKILL.md (first lines)
# Effect services, layers and resources
Checked against `effect 4.0.0` and `@effect/platform-node 4.0.0`. When the project has a newer version, read `node_modules/effect/src/Context.ts`, `Layer.ts`, `Scope.ts`, `Config.ts` and `ManagedRuntime.ts`, and `node_modules/effect/AGENTS.md`. The installed source wins over this skill.
## Decide: service or plain function
A service costs a requirement in every caller's type (`Effect<A, E, R>`), a layer, and a test double. Write a plain function, or an `Effect.fn` function, when the code has nothing to swap and nothing to close: pure logic, data shaping, a calculation, a helper with one caller.
Make a service when one of these is true:
- It reaches outside the process: a database, an HTTP API, a queue, mail, the file system.
- A test needs a fake for it.
- It owns a resource with a lifetime: a pool, a client, a socket, a background fiber.
- It needs configuration, or several modules must share one instance.
Cut services by capability, one per boundary (`UserRepo`, `Mailer`, `Payments`). A service whose methods only call pure functions is ceremony: write those as functions.
## Define a service
```ts
import * as Context from "effect/Context"
import * as Effect from "effect/Effect"
import * as Layer from "effect/Layer"
import * as Schema from "effect/Schema"
export class UserNotFound extends Schema.TaggedError<UserNotFound>()("UserNotFound", {
userId: Schema.String
}) {}
export interface User { readonly id: string; readonly email: string }
export class UserRepo extends Context.Service<UserRepo, {
findById(id: string): Effect.Effect<User, UserNotFound>
}>()("myapp/users/UserRepo") {
static readonly layer = Layer.effect(
UserRepo,
Effect.gen(function* () {
const rows = new Map<string, User>([["u1", { id: "u1", email: "ada@example.com" }]])
const findById = Effect.fn("UserRepo.findById")(function* (id: string) {
const user = rows.get(id)
if (user === undefined) return yield* new UserNotFound({ userId: id })
return user
})
return UserRepo.of({ findById })
})
)
}
```
- Write `Context.Service<Self, Shape>()("id")`: the class first, the shape second. The id string is the runtime identity. Two services with the same id share one slot, so one value answers for both. Prefix the id with the app or package name and the path: `"myapp/users/UserRepo"`.
- Keep `R = never` on every method of the shape. Read dependencies (`yield* Sql`, `yield* Config.String(...)`) in the layer's constructor, so callers and test doubles never see them. A method typed `Effect<A, E, Sql>` pushes `Sql` into every caller.
- Build the value with `UserRepo.of({ ... })` so TypeScript checks it against the shape. Write methods with `Effect.fn("UserRepo.findById")` to get a span per call.
- Attach layers as static fields: `layer` with its dependencies included, and `layerNoDeps` when tests swap a dependency.
- Read the service with `yield* UserRepo` in `Effect.gen`, or `UserRepo.use((repo) => repo.findById(id))` for one call. The shape type is `UserRepo["Service"]`.
- The second form, `Context.Service<Self>()("id", { make: effect })`, keeps the constructor on the class; its layer is `Layer.effect(this, this.make)`. Use it for a service with one implementation whose shape is whatever `make` returns. Use the interface form when the shape is a contract with a live and a test implementation.
## Context.Reference: a value with a default
Use `Context.Reference` for a setting, a feature flag or a per-request value with a sensible default. It adds nothing to `R`: code reads the default until something provides another value.
```ts
import * as Context from "effect/Context"
import * as Effect from "effect/Effect"
export const NewCheckout = Context.Reference<boolean>("myapp/flags/NewCheckout", {
defaultValue: () => false
})
const price = Effect.gen(function* () {
return (yield* NewCheckout) ? 90 : 100
})
export const discounted = price.pipe(Effect.provideService(NewCheckout, true))
```
The built-in services are references too: `Clock.Clock`, `Console.Console`, `Random.Random`, `ConfigProvider.ConfigProvider` and `Tracer.Tracer` need no layer. Override one for a region with `Effect.provideService` or a helper such as `Random.withSeed`. Read time through `Clock`, not `Date.now()`, so a test clock can control it. Details: [references/effect-services-layers.md](references/effect-services-layers.md).
## Compose layers
A `Layer<Out, E, In>` builds the services `Out`, can fail with `E`, and needs `In`.
| Constructor | Use it for |
| --- | --- |
| `Layer.succeed(S, value)` | a value with no construction work |
| `Layer.effect(S, effect)` | a constructor that reads services, config or resources. A resource acquired inside lives as long as the layer. Version 4 has no `Layer.scoped`. |
| `Layer.effectDiscard(effect)` | startup work or a background fiber that provides no service |
| `Layer.unwrap(effect)` | a layer chosen at build time, for example from config |
- `Layer.provide(self, deps)` feeds `deps` into `self` and hides them. `deps` can be one layer or an array.
- `Layer.provideMerge(self, deps)` feeds `deps` into `self` and outputs both.
- `Layer.mergeAll(a, b, c)` sets independent layers side by side. Their inputs add up.
```ts
import * as Config from "effect/Config"
import * as Context from "effect/Context"
import * as Effect from "effect/Effect"
import * as Layer from "effect/Layer"
import * as Redacted from "effect/Redacted"
import * as Schema from "effect/Schema"
export class SqlError extends Schema.TaggedError<SqlError>()("SqlError", { cause: Schema.Defect() }) {}
interface Pool {
query(text: string): Promise<ReadonlyArray<unknown>>
end(): Promise<void>
}
declare function openPool(url: string): Pool
export class Sql extends Context.Service<Sql, {
query(text: string): Effect.Effect<ReadonlyArray<unknown>, SqlError>
}>()("myapp/db/Sql") {
static readonly layer = Layer.effect(
Sql,
Effect.gen(function* () {
const url = yield* Config.Redacted("DATABASE_URL")
const pool = yield* Effect.acquireRelease(
Effect.sync(() => openPool(Redacted.value(url))),
(pool) => Effect.promise(() => pool.end())
)From andabove/skills, MIT.
More from andabove/skills
- 0.570score
effect-testing
andabove
Testing Effect code with @effect/vitest, TestClock and test layers.
SkillAFreshness: AClaude Code +9 - 0.570score
effect
andabove
Effect (the TypeScript library) core and router to the other Effect skills.
SkillAFreshness: AClaude Code +9 - 0.570score
effect-adoption
andabove
Adopting Effect in an existing Promise codebase one module at a time.
SkillAFreshness: AClaude Code +9 - 0.570score
effect-concurrency
andabove
Effect concurrency - fibers, interruption, coordination and Schedule.
SkillAFreshness: AClaude Code +9 - 0.570score
effect-data
andabove
Effect 4 data types, equality, caching and batching.
SkillAFreshness: AClaude Code +9 - 0.570score
effect-errors
andabove
Effect error handling, for expected errors, defects and interruptions.
SkillAFreshness: AClaude Code +9 - 0.570score
effect-observability
andabove
Effect 4 logging, tracing and metrics, and their export.
SkillAFreshness: AClaude Code +9 - 0.570score
effect-schema
andabove
Effect 4 Schema for parsing and modelling data.
SkillAFreshness: AClaude Code +9 - 0.570score
effect-streams
andabove
Effect Stream, Sink and Channel.
SkillAFreshness: AClaude Code +9 - 0.570score
effect-v3-to-v4
andabove
Effect v3 to v4 migration.
SkillAFreshness: AClaude Code +9 - 0.565score
linear-comment
andabove
Write a comment on a Linear issue as a status record against its acceptance criteria and QA notes.
SkillAFreshness: AClaude Code +9 - 0.565score
code-style
andabove
Fifteen TypeScript code rules for modules, names, doc comments, types, boundaries, errors and side effects.
SkillAFreshness: AClaude Code +9
Signals
- Stars
- 0
- Forks
- 0
- Open issues
- 0
- Last commit (this folder)
- Oct 3, 2026 (26 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/andabove/skills
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from andabove
- 0.570score
effect-data
andabove
Effect 4 data types, equality, caching and batching.
SkillAFreshness: AClaude Code +9 - 0.570score
effect-concurrency
andabove
Effect concurrency - fibers, interruption, coordination and Schedule.
SkillAFreshness: AClaude Code +9 - 0.570score
effect-testing
andabove
Testing Effect code with @effect/vitest, TestClock and test layers.
SkillAFreshness: AClaude Code +9 - 0.570score
effect
andabove
Effect (the TypeScript library) core and router to the other Effect skills.
SkillAFreshness: AClaude Code +9 - 0.570score
effect-adoption
andabove
Adopting Effect in an existing Promise codebase one module at a time.
SkillAFreshness: AClaude Code +9 - 0.570score
effect-errors
andabove
Effect error handling, for expected errors, defects and interruptions.
SkillAFreshness: AClaude Code +9
Cite this page
effect-services skill. Agent Mart. https://agentmart.dev/skills/andabove-effect-services (last updated 2026-10-24)