Provides access to Effect's platform-agnostic I/O services including HTTP clients and file systems.

Install

mkdir -p .claude/skills/platform && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/14403" && unzip -o skill.zip -d .claude/skills/platform && rm skill.zip

Installs to .claude/skills/platform

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

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.
321 chars✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
Intermediate

Key capabilities

  • Make HTTP GET, POST, and other requests
  • Configure HTTP requests with headers, body, and timeouts
  • Handle HTTP responses by parsing JSON or text
  • Build HTTP servers with routing and request body handling
  • Perform file system operations like reading, writing, and directory management
  • Interact with the terminal for input and output

How it works

The `@effect/platform` provides cross-platform abstractions for HTTP clients, HTTP servers, file system operations, and terminal interactions, allowing for consistent I/O across different runtime environments.

Inputs & outputs

You give it
HTTP requests, file paths, terminal commands
You get back
HTTP responses, file content, terminal output

When to use Platform

  • Build cross-platform HTTP clients
  • Implement persistent storage
  • Handle file operations in Effect

About this skill

Effect Platform

Overview

@effect/platform provides cross-platform abstractions for:

  • HTTP Client - Make HTTP requests
  • HTTP Server - Build HTTP servers
  • FileSystem - File operations
  • KeyValueStore - Persistent storage
  • Terminal - CLI interactions
  • Worker - Background workers

HTTP Client

Installation

npm install @effect/platform
# For Node.js:
npm install @effect/platform-node
# For Bun:
npm install @effect/platform-bun

Basic Requests

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)
)

Request Configuration

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: "[email protected]" })
  })

  // 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")
  )
})

Response Handling

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"]
})

Schema Validation

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
})

HTTP Server

Basic Server

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)
)

Route Parameters

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 })
    })
  )
)

Request Body

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 })
    })
  )
)

FileSystem

Reading Files

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)
)

Writing Files

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")
})

Directory Operations

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")
})

File Info

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
  })
})

KeyValueStore

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"))
)

Terminal

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)
)

Complete Example: REST API

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)

Best Practices

  1. Use Schema validation - Validate all external data
  2. Provide platform layers - NodeHttpClient.layer, etc.
  3. Handle errors - Network failures, file not found, etc.
  4. Use Effect.scoped for resources - Files, connections
  5. Configure timeouts - Prevent hanging requests

Additional Resources

For comprehensive platform documentation, consult ${CLAUDE_PLUGIN_ROOT}/references/llms-full.txt.

Search for these sections:

  • "HTTP Client" for making requests
  • "HTTP Server" for building servers
  • "FileSystem" for file operations
  • "KeyValueStore" for persistent storage
  • "Terminal" for CLI interactions

When not to use it

  • When the project does not use Effect for application development
  • When platform-agnostic I/O capabilities are not required
  • When a different framework or library is preferred for HTTP, file system, or terminal interactions

Limitations

  • Requires providing specific platform layers (e.g., `NodeHttpClient.layer`)
  • Schema validation must be explicitly applied for external data
  • Error handling and resource management (e.g., `Effect.scoped`) are best practices to implement

How it compares

This skill offers a unified, platform-agnostic API for common I/O operations within the Effect ecosystem, providing a consistent programming model across various runtimes unlike using separate, platform-specific libraries.

Compared to similar skills

Platform side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
Platform (this skill)02moReviewIntermediate
telegram-mini-app626moReviewAdvanced
stripe-integration482moNo flagsAdvanced
nodejs-backend-patterns122moNo flagsIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

You might also like

telegram-mini-app

davila7

Expert in building Telegram Mini Apps (TWA) - web apps that run inside Telegram with native-like experience. Covers the TON ecosystem, Telegram Web App API, payments, user authentication, and building viral mini apps that monetize. Use when: telegram mini app, TWA, telegram web app, TON app, mini app.

62163

stripe-integration

wshobson

Implement Stripe payment processing for robust, PCI-compliant payment flows including checkout, subscriptions, and webhooks. Use when integrating Stripe payments, building subscription systems, or implementing secure checkout flows.

48165

nodejs-backend-patterns

wshobson

Build production-ready Node.js backend services with Express/Fastify, implementing middleware patterns, error handling, authentication, database integration, and API design best practices. Use when creating Node.js servers, REST APIs, GraphQL backends, or microservices architectures.

1246

agent-dev-backend-api

ruvnet

Agent skill for dev-backend-api - invoke with $agent-dev-backend-api

318

shopify-apps

alinaqi

Shopify app development - Remix, Admin API, checkout extensions

19

ccxt-typescript

ccxt

CCXT cryptocurrency exchange library for TypeScript and JavaScript developers (Node.js and browser). Covers both REST API (standard) and WebSocket API (real-time). Helps install CCXT, connect to exchanges, fetch market data, place orders, stream live tickers/orderbooks, handle authentication, and manage errors. Use when working with crypto exchanges in TypeScript/JavaScript projects, trading bots, arbitrage systems, or portfolio management tools. Includes both REST and WebSocket examples.

15

Search skills

Search the agent skills registry