Skip to content

aolus-software/clean-elysia-prisma

Repository files navigation

Clean Elysia

A clean architecture backend API built with Elysia.js, TypeScript, and Bun.

Features

  • Clean architecture pattern with separation of concerns
  • Elysia.js web framework with TypeBox validation
  • PostgreSQL with Drizzle ORM
  • Redis for caching and rate limiting
  • BullMQ for background job processing
  • ClickHouse for analytics (optional)
  • Comprehensive authentication and authorization (RBAC)
  • API documentation with OpenAPI and Scalar
  • Docker support

Tech Stack

  • Runtime: Bun
  • Framework: Elysia.js
  • Language: TypeScript
  • Databases: PostgreSQL, Redis, ClickHouse
  • ORM: Drizzle
  • Queue: BullMQ
  • Validation: TypeBox
  • API Docs: OpenAPI + Scalar

Prerequisites

  • Bun 1.x or higher
  • PostgreSQL
  • Redis
  • Docker (optional)

Installation

Install dependencies:

bun install

Configuration

Copy the example environment file and configure your environment variables:

cp .env.example .env

Configure the following environment variables:

  • Database connections (PostgreSQL, Redis, ClickHouse)
  • Mail settings
  • JWT secrets
  • Application settings

See Configuration Documentation for detailed reference.

Database Setup

Generate and run PostgreSQL migrations:

bun run db:generate
bun run db:migrate

Seed the database with initial data:

bun run db:seed

For development, you can also use:

bun run db:push  # Push schema directly without migrations

Open Drizzle Studio to view and edit data:

bun run db:studio

Run ClickHouse migrations:

bun run db:clickhouse:migrate

Check ClickHouse migration status:

bun run db:clickhouse:status

Development

Run the API server in development mode:

bun run dev

The API will be available at http://localhost:3000

Production

Build the application:

bun run build

Start the production server:

bun run start

Cluster Mode

The app can run in cluster mode to scale across CPU cores. This is controlled by two environment variables:

  • APP_CLUSTER_MODE (default false) — set to true to enable cluster mode.
  • APP_CLUSTER_WORKERS (default 0) — number of worker processes to fork. When 0, falls back to os.availableParallelism() (typically the number of available CPU cores).

When enabled, src/index.ts runs as the primary process: it forks workers, restarts any worker that exits, and forwards SIGINT/SIGTERM to all workers for graceful shutdown. Each worker loads src/server.ts, which is the actual Elysia app bootstrap.

Example:

APP_CLUSTER_MODE=true APP_CLUSTER_WORKERS=4 bun run start

Caveats

  • Every worker re-runs bootstrap() and instantiates its own Prisma, Redis, and BullMQ connections. Side-effectful imports (BullMQ workers, scheduled jobs) fire once per worker — if you need single-instance semantics, gate them on cluster.worker?.id === 1 or run queue workers as a separate process.
  • In-memory state (caches, rate-limit counters not backed by Redis) is not shared across workers — keep cross-worker state in Redis.
  • The primary process does not bind the HTTP port; only workers call .listen().

Docker

Build and run with Docker Compose:

docker-compose up -d

Project Structure

src/
├── base.ts                # Base Elysia app with core plugins
├── index.ts               # Cluster entrypoint (forks workers or imports server)
├── server.ts              # Elysia app bootstrap (runs per worker)
├── bull/                  # Background jobs
│   ├── queue/             # Job queues
│   └── worker/            # Job workers
├── libs/                  # Shared libraries
│   ├── cache/             # Cache utilities
│   ├── config/            # Configuration
│   ├── database/          # Database clients and repositories
│   ├── errors/            # Custom error classes
│   ├── guards/            # Authorization guards
│   ├── mailer/            # Email service
│   ├── plugins/           # Elysia plugins
│   ├── repositories/      # Data access layer
│   ├── types/             # TypeScript types
│   └── utils/             # Utility functions
└── modules/               # Feature modules
    ├── auth/              # Authentication
    ├── home/              # Root/health endpoints
    ├── profile/           # User profile
    └── settings/          # Application settings

Code Quality

Run linting:

bun run lint

Fix linting issues:

bun run lint:fix

Format code:

bun run format

Type checking:

bun run typecheck

API Documentation

Once the server is running, access the interactive API documentation at:

http://localhost:3000/docs

The API documentation is powered by OpenAPI with Scalar UI, providing:

  • Browse all endpoints with request/response schemas
  • Try endpoints directly from the browser
  • View validation rules and examples
  • Bearer token authentication support

Download the OpenAPI specification:

http://localhost:3000/docs/openapi.json

For more details, see the API Documentation Guide.

Scripts

Development

  • bun run dev - Run API server with hot reload
  • bun run build - Build the application
  • bun run start - Start the production server

Code Quality

  • bun run lint - Run ESLint
  • bun run lint:fix - Fix ESLint issues
  • bun run format - Format code with Prettier
  • bun run typecheck - Run TypeScript type checking

Database (PostgreSQL/Drizzle)

  • bun run db:generate - Generate migration files from schema
  • bun run db:migrate - Apply pending migrations
  • bun run db:push - Push schema to database (development only)
  • bun run db:pull - Pull schema from database
  • bun run db:studio - Open Drizzle Studio
  • bun run db:drop - Drop all tables (dangerous!)
  • bun run db:seed - Seed database with initial data

Database (ClickHouse)

  • bun run db:clickhouse:migrate - Run ClickHouse migrations
  • bun run db:clickhouse:status - Check migration status

Makefile Commands

You can also use make commands:

  • make help - Show all available commands
  • make dev - Start development server
  • make fresh - Drop, push schema, and seed (development)
  • make reset - Generate migrations, migrate, and seed

Documentation

Comprehensive documentation is available in the docs/ directory:

Architecture

This project follows Clean Architecture principles:

Layers

  1. Modules - Feature-based modules containing routes and business logic
  2. Repositories - Data access layer with database operations
  3. Services - Business logic and orchestration
  4. Plugins - Cross-cutting concerns (logging, error handling, security)
  5. Utils - Helper functions and utilities

Key Patterns

  • Repository Pattern - Factory functions returning database access methods
  • Service Pattern - Object exports with business logic methods
  • Plugin Pattern - Reusable Elysia plugins for middleware
  • Error Handling - Custom error classes with consistent API responses
  • Validation - TypeBox schemas for runtime validation

Roadmap & Improvements

See TODO.md for a comprehensive list of planned improvements and enhancements.

Compare with clean-hono implementation: COMPARISON.md

Contributing

  1. Fork the repository
  2. Create your feature branch
  3. Commit your changes
  4. Push to the branch
  5. Create a Pull Request

Please read our Contributing Guidelines and Code of Conduct.

License

This project is licensed under the MIT License.

About

Boilerplate For ElysiaJs with Prisma orm

Resources

License

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors