effect-http-server

Build HTTP servers with Effect v4 HttpRouter routes, middleware, and platform layers.

1|Updated Aug 24, 2026
One-click install
npx skills add https://github.com/lambdasolver2/opencode-effect-harness --skill effect-http-server-lambdasolver2
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: effect-http-server
Source: https://github.com/lambdasolver2/opencode-effect-harness/tree/main/packages/module-typescript/assets/skills/effect-http-server
Command: npx skills add https://github.com/lambdasolver2/opencode-effect-harness --skill effect-http-server-lambdasolver2

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill requires effect, @effect/platform-node, @effect/platform-bun.

What problem does it solve? Building HTTP servers with Effect v4's unstable effect/unstable/http modules requires navigating a service-based router model, schema decoding, multipart handling, and platform adapters that differ significantly from v3 — this Skill provides the exact patterns and API references to do it correctly. ## Core Features & Use Cases - Routing & Middleware: Register routes with HttpRouter.add/addAll/use, decode path/search params with schemas, and compose route-scoped or global middleware with typed error handling. - Request & Response Handling: Schema-validate JSON/form/multipart bodies, build responses with HttpServerResponse constructors, stream bodies, manage cookies, and map domain errors to status codes via HttpServerRespondable. - Platform Serving & Testing: Serve on Node or Bun with graceful shutdown, handle WebSocket upgrades, serve static files, and test handlers in-memory without binding a real port. - Use Case: You need a typed REST endpoint that accepts a multipart file upload with size limits, validates fields against a Schema, and returns a 413 on oversized files — this Skill gives the exact Multipart limit references and error mapping code. ## Quick Start Ask the AI to create an Effect v4 HTTP server with a GET route, schema-decoded path params, and a NodeHttpServer layer on port 3000.

Frequently Asked Questions about effect-http-server

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I create an HTTP server with Effect v4 HttpRouter?

Register routes as Layers with HttpRouter.add(method, path, handler), then pass them to HttpRouter.serve and provide a platform layer like NodeHttpServer.layer(createServer, { port: 3000 }). Launch with Layer.launch and NodeRuntime.runMain.

How do I validate request bodies with Schema in Effect HTTP?

Use HttpServerRequest.schemaBodyJson for JSON bodies, schemaBodyUrlParams for form posts, or schemaBodyMultipart for file uploads. These return Effects failing with SchemaError, which the server boundary converts to an empty 400 response automatically.

Does Effect v4 HttpRouter support middleware like Express?

Yes, via HttpRouter.middleware, which wraps route handlers and can provide services, modify responses, or catch typed route errors declared in its handles config. Pass { global: true } to apply middleware to all routes, or provide its .layer to specific route layers.

How do I handle multipart file uploads in Effect HTTP server?

Access request.multipart to persist file parts to temp files, or use schemaBodyMultipart with Multipart.FilesSchema for validated uploads. Control limits with the Multipart.MaxFileSize, MaxFieldSize, and MaxParts context references, and catch MultipartError to return 413.

What is the difference between HttpRouter and HttpApi in Effect?

HttpRouter is the imperative, low-level routing primitive covered here, where handlers are plain Effects returning HttpServerResponse. HttpApi is the declarative, schema-first layer with OpenAPI generation, covered by the separate effect-http-api skill.

Why does my Effect HTTP route return 500 instead of my custom error?

Unhandled failures are converted at the server boundary: SchemaError becomes 400, NoSuchElementError becomes 404, and everything else becomes 500. Implement HttpServerRespondable on your error class or catch it with Effect.catchTag to control the response.