A monorepo example demonstrating how to build a type-safe API using Effect, @effect/platform, and Drizzle ORM.
effect-api-example/
├── apps/
│ └── server/ # Bun HTTP server
│ ├── src/
│ │ ├── api/
│ │ │ ├── groups/ # API endpoint handlers
│ │ │ └── middleware/ # Auth middleware implementations
│ │ ├── db/
│ │ │ ├── schema/ # Drizzle table schemas
│ │ │ ├── migrations/ # Database migrations
│ │ │ └── SqlLive.ts # Database layer
│ │ └── main.ts # Server entrypoint
│ ├── scripts/
│ │ ├── seed.ts # Database seeding script
│ │ └── client-example.ts # Example API client
│ ├── docker-compose.yml # PostgreSQL container
│ └── drizzle.config.ts # Drizzle Kit configuration
├── packages/
│ ├── api/ # API definition (schemas, endpoints, middleware)
│ │ └── src/definition/
│ │ ├── groups/ # Endpoint group definitions
│ │ ├── middleware/ # Middleware definitions
│ │ └── WarpApi.ts # Main API definition
│ ├── shared/ # Shared types and utilities
│ │ └── src/index.ts # Branded types, schemas, helpers
│ ├── eslint-config/ # Shared ESLint configuration
│ └── typescript-config/ # Shared TypeScript configuration
# Clone the repository
git clone <repo-url>
cd effect-api-example
# Install dependencies
pnpm installcd apps/server
docker compose up -dThis starts a PostgreSQL container with:
- Host:
localhost - Port:
5432 - Database:
postgres - User:
postgres - Password:
postgres_password
Copy the example environment file:
cd apps/server
cp .env.example .envThe .env file should contain:
DB_HOST=localhost
DB_PORT=5432
DB_NAME=postgres
DB_USERNAME=postgres
DB_PASSWORD=postgres_passwordpnpm --filter @effect-api-example/server db:migratePopulate the database with 1000 sample employees:
pnpm --filter @effect-api-example/server db:seedpnpm --filter @effect-api-example/server devThe server runs on http://localhost:9277 by default.
Run the example client to test the API:
pnpm --filter @effect-api-example/server client:example| Script | Description |
|---|---|
pnpm build |
Build all packages |
pnpm dev |
Start development mode for all packages |
pnpm lint |
Lint all packages |
pnpm format |
Format code with Prettier |
| Script | Description |
|---|---|
pnpm dev |
Start server in hot-reload mode |
pnpm build |
Build server for production |
pnpm start |
Run production build |
pnpm db:generate |
Generate new migrations |
pnpm db:migrate |
Apply migrations |
pnpm db:seed |
Seed database with sample data |
pnpm client:example |
Run example API client |
GET /health- Health check endpoint
All employee endpoints require an x-api-key header.
GET /employees- List employees with pagination- Query params:
limit,afterId,beforeId,types[]
- Query params:
GET /employees/:id- Get employee by tag
- Runtime: Bun
- Framework: @effect/platform HTTP API
- Database: PostgreSQL with Drizzle ORM
- Type Safety: Effect Schema
- Monorepo: Turborepo with pnpm workspaces