From effect-ts
This skill should be used when the user asks about "@effect/platform", "Effect HTTP client", "Effect HTTP server", "FileSystem", "KeyValueStore", "Terminal", "platform services", "HttpClient", "HttpServer", "Effect file operations", "Effect networking", or needs to understand Effect's platform-agnostic I/O capabilities.
npx claudepluginhub andrueandersoncs/claude-skill-effect-ts --plugin effect-tsThis skill uses the workspace's default tool permissions.
`@effect/platform` provides cross-platform abstractions for:
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
@effect/platform provides cross-platform abstractions for:
npm install @effect/platform
# For Node.js:
npm install @effect/platform-node
# For Bun:
npm install @effect/platform-bun
import { HttpClient } from "@effect/platform";
import { NodeHttpClient } from "@effect/platform-node";
import { Effect } from "effect";
const program = Effect.gen(function* () {
const client = yield* HttpClient.HttpClient;
// GET request
const response = yield* client.get("https://api.example.com/users");
const data = yield* response.json;
return data;
}).pipe(Effect.provide(NodeHttpClient.layer));
const program = Effect.gen(function* () {
const client = yield* HttpClient.HttpClient;
// POST with body
const response = yield* client.post("https://api.example.com/users", {
body: HttpClientRequest.jsonBody({ name: "Alice", email: "alice@example.com" }),
});
// With headers
const response = yield* client.get("https://api.example.com/protected", {
headers: { Authorization: "Bearer token123" },
});
// With timeout
const response = yield* client.get("https://api.example.com/slow").pipe(Effect.timeout("5 seconds"));
});
const program = Effect.gen(function* () {
const client = yield* HttpClient.HttpClient;
const response = yield* client.get("https://api.example.com/data");
// Parse as JSON
const json = yield* response.json;
// Parse as text
const text = yield* response.text;
// Get status
const status = response.status;
// Get headers
const contentType = response.headers["content-type"];
});
import { HttpClient, HttpClientResponse } from "@effect/platform";
import { Schema } from "effect";
const User = Schema.Struct({
id: Schema.Number,
name: Schema.String,
email: Schema.String,
});
const program = Effect.gen(function* () {
const client = yield* HttpClient.HttpClient;
const response = yield* client.get("https://api.example.com/users/1");
// Validate response with schema
const user = yield* HttpClientResponse.schemaBodyJson(User)(response);
return user;
});
import { HttpServer, HttpServerResponse } from "@effect/platform";
import { NodeHttpServer } from "@effect/platform-node";
import { Effect, Layer } from "effect";
import { createServer } from "node:http";
const app = HttpServer.router.empty.pipe(
HttpServer.router.get("/", HttpServerResponse.text("Hello, World!")),
HttpServer.router.get(
"/users",
HttpServerResponse.json([
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
]),
),
);
const ServerLive = NodeHttpServer.layer(createServer, { port: 3000 });
const program = Effect.gen(function* () {
yield* Effect.log("Server starting on port 3000");
yield* Effect.never; // Keep running
}).pipe(Effect.provide(HttpServer.router.Live(app)), Effect.provide(ServerLive));
const app = HttpServer.router.empty.pipe(
HttpServer.router.get(
"/users/:id",
Effect.gen(function* () {
const params = yield* HttpServer.router.params;
const id = params.id;
return HttpServerResponse.json({ id, name: "User " + id });
}),
),
);
import { HttpServerRequest } from "@effect/platform";
const app = HttpServer.router.empty.pipe(
HttpServer.router.post(
"/users",
Effect.gen(function* () {
const request = yield* HttpServerRequest.HttpServerRequest;
const body = yield* request.json;
// Or with schema validation
const validated = yield* HttpServerRequest.schemaBodyJson(CreateUser)(request);
return HttpServerResponse.json({ created: true, user: validated });
}),
),
);
import { FileSystem } from "@effect/platform";
import { NodeFileSystem } from "@effect/platform-node";
const program = Effect.gen(function* () {
const fs = yield* FileSystem.FileSystem;
const content = yield* fs.readFileString("./config.json");
const bytes = yield* fs.readFile("./image.png");
const exists = yield* fs.exists("./file.txt");
}).pipe(Effect.provide(NodeFileSystem.layer));
const program = Effect.gen(function* () {
const fs = yield* FileSystem.FileSystem;
yield* fs.writeFileString("./output.txt", "Hello, World!");
yield* fs.writeFile("./data.bin", new Uint8Array([1, 2, 3]));
yield* fs.appendFileString("./log.txt", "New log entry\n");
});
const program = Effect.gen(function* () {
const fs = yield* FileSystem.FileSystem;
yield* fs.makeDirectory("./new-dir", { recursive: true });
const files = yield* fs.readDirectory("./src");
yield* fs.remove("./temp", { recursive: true });
yield* fs.copy("./source.txt", "./dest.txt");
yield* fs.rename("./old.txt", "./new.txt");
});
const program = Effect.gen(function* () {
const fs = yield* FileSystem.FileSystem;
const stat = yield* fs.stat("./file.txt");
console.log({
size: stat.size,
isFile: stat.type === "File",
isDirectory: stat.type === "Directory",
modified: stat.mtime,
});
});
Persistent key-value storage:
import { KeyValueStore } from "@effect/platform";
import { NodeKeyValueStore } from "@effect/platform-node";
const program = Effect.gen(function* () {
const store = yield* KeyValueStore.KeyValueStore;
yield* store.set("user:1", JSON.stringify({ name: "Alice" }));
const value = yield* store.get("user:1");
yield* store.remove("user:1");
const exists = yield* store.has("user:1");
}).pipe(Effect.provide(NodeKeyValueStore.layerFileSystem("./data")));
CLI interactions:
import { Terminal } from "@effect/platform";
import { NodeTerminal } from "@effect/platform-node";
const program = Effect.gen(function* () {
const terminal = yield* Terminal.Terminal;
const name = yield* terminal.readLine;
yield* terminal.display(`Hello, ${name}!`);
}).pipe(Effect.provide(NodeTerminal.layer));
import { HttpServer, HttpServerResponse, HttpServerRequest } from "@effect/platform";
import { NodeHttpServer } from "@effect/platform-node";
import { Effect, Layer, Schema } from "effect";
import { createServer } from "node:http";
// Schemas
const CreateUser = Schema.Struct({
name: Schema.String,
email: Schema.String,
});
const User = Schema.Struct({
id: Schema.Number,
name: Schema.String,
email: Schema.String,
});
// In-memory store
let users: Schema.Schema.Type<typeof User>[] = [];
let nextId = 1;
// Routes
const app = HttpServer.router.empty.pipe(
HttpServer.router.get("/users", HttpServerResponse.json(users)),
HttpServer.router.post(
"/users",
Effect.gen(function* () {
const body = yield* HttpServerRequest.schemaBodyJson(CreateUser);
const user = { id: nextId++, ...body };
users.push(user);
return HttpServerResponse.json(user, { status: 201 });
}),
),
HttpServer.router.get(
"/users/:id",
Effect.gen(function* () {
const { id } = yield* HttpServer.router.params;
const user = users.find((u) => u.id === parseInt(id));
return user ? HttpServerResponse.json(user) : HttpServerResponse.json({ error: "Not found" }, { status: 404 });
}),
),
);
// Server
const ServerLive = NodeHttpServer.layer(createServer, { port: 3000 });
const main = HttpServer.serve(app).pipe(Effect.provide(ServerLive), Effect.catchAllCause(Effect.logError));
Effect.runPromise(main);
For comprehensive platform documentation, consult ${CLAUDE_PLUGIN_ROOT}/references/llms-full.txt.
Search for these sections: