Installation

Effect + @effect/platform — everything you need

Core Dependencies

pnpm add effect @effect/schema @effect/platform @effect/platform-node

Database (Drizzle + Postgres)

pnpm add drizzle-orm pg
pnpm add -D drizzle-kit @types/pg

Cache (Redis)

pnpm add ioredis
pnpm add -D @types/ioredis

Project Structure

src/
├── main.ts              # Entry point — Layer.launch(MainLayer)
├── layers/
│   ├── Config.ts        # Config Layer with Effect.Config
│   ├── Database.ts      # PgPool + Drizzle Layers
│   └── Redis.ts         # Redis Layer with acquireRelease
├── services/
│   └── UserRepo.ts      # Service Layers using Context.Tag
├── routes/
│   └── users.ts         # HttpRouter handlers
└── lib/
    └── schema.ts        # Drizzle schema definitions

TypeScript Config

{
  "compilerOptions": {
    "strict": true,
    "exactOptionalPropertyTypes": true,
    "moduleResolution": "bundler",
    "module": "ESNext",
    "target": "ES2022",
    "lib": ["ES2022"],
    "esModuleInterop": true,
    "skipLibCheck": true
  }
}

Entry Point

// src/main.ts
import { pipe } from "effect"
import * as Layer from "effect/Layer"
import * as HttpServer from "@effect/platform/HttpServer"
import * as NodeHttpServer from "@effect/platform-node/NodeHttpServer"
import * as NodeRuntime from "@effect/platform-node/NodeRuntime"
import { createServer } from "node:http"

import { AppRouter } from "./routes"
import { AppLayer } from "./layers"

const MainLayer = pipe(
  HttpServer.serve(AppRouter),
  HttpServer.withLogAddress,
  Layer.provide(AppLayer),
  Layer.provide(NodeHttpServer.layer(createServer, { port: 3000 }))
)

Layer.launch(MainLayer).pipe(NodeRuntime.runMain)

Run

npx tsx src/main.ts