A clean, production-ready starter template for building modern web applications with ElysiaJS. This template provides a well-structured monorepo setup with TypeScript, multi-database support, Docker integration, and development best practices.
- ElysiaJS Framework: Fast and modern web framework for Bun
- TypeScript: Full TypeScript support with strict configuration
- Bun Runtime: Lightning-fast JavaScript runtime and package manager
- Monorepo Structure: Organized with
apps,packages,config, andinfradirectories - Worker Support: Background job processing with BullMQ
- Clean Architecture: Separation of concerns with modular design
- Modular APIs: Feature-based module organization (auth, profile, settings)
- PostgreSQL: Production-ready relational database with Drizzle ORM
- ClickHouse: High-performance analytics database with custom migration system
- Drizzle ORM: Type-safe database operations and migrations
- Database Seeding: Pre-configured seeding with drizzle-seed
- Redis Integration: High-performance caching and session management (IORedis)
- BullMQ: Robust queue system for background jobs and task processing
- JWT Authentication: Secure token-based authentication with @elysiajs/jwt
- Password Hashing: Bcrypt integration for secure password storage
- Encryption: Crypto-JS for data encryption and decryption
- Rate Limiting: Protection against abuse with elysia-rate-limit
- Helmet: Security headers with elysia-helmet
- CORS Support: Configurable cross-origin resource sharing
- OpenAPI/Swagger: Auto-generated API documentation with @elysiajs/openapi
- Bearer Token: Built-in bearer token support with @elysiajs/bearer
- Structured Logging: Logging with Pino and pino-pretty
- Request ID: Request tracking and tracing
- Email Support: Nodemailer integration for sending emails
- Template Ready: Pre-configured email service layer with templates
- Docker Support: Complete containerization with Docker and Docker Compose
- Hot Reload: Fast development with Bun's watch mode
- Code Quality: ESLint, Prettier, and Husky for consistent code formatting
- Lint-Staged: Pre-commit hooks for code quality enforcement
- Date Handling: DayJS for modern date/time operations
- Concurrency: Run multiple services simultaneously with concurrently
- Environment Variables: Dotenv for configuration management
- Centralized Config: Organized configuration in
config/directory - Timezone Support: Configurable timezone settings
- Bun (latest version)
- PostgreSQL (v18 or higher)
- Redis (v7 or higher)
- ClickHouse (v23.12 or higher, optional)
- Docker (optional, for containerization)
- Make (optional, for using Makefile commands)
-
Clone the repository
git clone https://github.com/aolus-software/clean-elysia.git cd clean-elysia -
Install dependencies
bun install
-
Set up environment variables
cp .env.example .env # Edit .env with your configuration -
Start development server
bun run dev:server
Configure your environment by editing .env:
# Application
APP_NAME="Elysia APP"
APP_PORT=3000
APP_URL="http://localhost:3000"
APP_ENV="development"
APP_TIMEZONE="UTC"
APP_KEY="your-app-key"
APP_JWT_SECRET="your-jwt-secret"
# PostgreSQL Database
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/elysia_db"
# ClickHouse Database
CLICKHOUSE_HOST="http://localhost:8123"
CLICKHOUSE_USER="app"
CLICKHOUSE_PASSWORD="secret"
CLICKHOUSE_DATABASE="app"
# Redis
REDIS_HOST="localhost"
REDIS_PORT=6379
REDIS_PASSWORD=password123
REDIS_DB=0
# Mail (SMTP)
MAIL_HOST=
MAIL_PORT=
MAIL_SECURE=
MAIL_USER=
MAIL_PASS=
MAIL_FROM=
# Logging & Security
LOG_LEVEL="info"
ALLOWED_HOST="*"
CLIENT_URL="http://localhost:3000"# Install dependencies
bun install
# Start development server with hot reload
bun run dev:server
# Start development worker with hot reload
bun run dev:worker
# Start both server and worker
bun run dev:all
# Build for production
bun run build:all
# Start production server
bun run start:all# View all available commands
make help
# Development Commands
make dev-api # Start API development server with hot reload
make dev-server # Start SERVER development server with hot reload
make dev-worker # Start WORKER development with hot reload
make dev-all # Run server and worker in dev mode concurrently
# Build Commands
make build-api # Build the API application
make build-server # Build the SERVER application
make build-worker # Build the WORKER application
make build-all # Build server and worker concurrently
# Production Commands
make start-api # Start the API production server
make start-server # Start the SERVER production server
make start-worker # Start the WORKER production service
make start-all # Run server and worker in production concurrently
# Code Quality
make lint # Run ESLint
make format # Format code with Prettier
# Database Commands (PostgreSQL - Drizzle)
make db-generate # Generate migration files
make db-migrate # Run pending migrations
make db-push # Push schema to database (dev only)
make db-pull # Pull schema from database
make db-studio # Open Drizzle Studio
make db-drop # Drop all tables (dangerous!)
make db-seed # Run database seeder
# Database Commands (ClickHouse)
make migrate-clickhouse # Run ClickHouse migrations
make migrate-clickhouse-status # Check status of ClickHouse migrations
# Combined Workflows
make fresh # Drop database, push schema, and seed
make reset # Generate migrations, migrate, and seed# Build and run with Docker Compose (includes PostgreSQL, Redis, ClickHouse)
docker-compose up --build
# Run in detached mode
docker-compose up -d
# View logs
docker-compose logs -f app
# Stop all services
docker-compose downclean-elysia/
├── apps/ # Application modules
│ ├── apis/ # API application
│ │ ├── modules/ # Feature modules
│ │ │ ├── auth/ # Authentication module
│ │ │ ├── home/ # Home/dashboard module
│ │ │ ├── profile/ # User profile module
│ │ │ └── settings/ # Settings module
│ │ ├── types/ # API-specific type definitions
│ │ ├── base.ts # Base application setup
│ │ └── serve.ts # Server entry point
│ └── worker/ # Background job workers
│ ├── queue/ # Queue definitions
│ └── worker/ # Worker implementations
│
├── packages/ # Shared packages and utilities
│ ├── cache/ # Caching utilities
│ ├── default/ # Default configurations
│ ├── errors/ # Custom error classes
│ │ ├── bad-request-error.ts
│ │ ├── forbidden-error.ts
│ │ ├── not-found-error.ts
│ │ ├── unauthorized-error.ts
│ │ └── unprocessable-entity-error.ts
│ ├── guards/ # Authentication guards
│ ├── logger/ # Logging utilities
│ ├── mail/ # Email service
│ │ └── templates/ # Email templates
│ ├── plugins/ # Elysia plugins
│ │ ├── auth.plugin.ts # JWT authentication plugin
│ │ ├── docs.plugin.ts # OpenAPI documentation plugin
│ │ ├── error-handler.plugin.ts
│ │ ├── logger.plugin.ts
│ │ ├── request-id.plugin.ts
│ │ └── security.plugin.ts
│ ├── security/ # Security utilities
│ └── toolkit/ # Common tools and helpers
│ ├── datatable.ts # Datatable utilities
│ ├── date.ts # Date utilities (DayJS)
│ ├── number.ts # Number utilities
│ ├── response.ts # Response utilities
│ └── string.ts # String utilities
│
├── config/ # Centralized configuration
│ ├── app.config.ts # Application config
│ ├── clickhouse.config.ts # ClickHouse config
│ ├── cors.config.ts # CORS config
│ ├── database.config.ts # PostgreSQL config
│ ├── jwt.config.ts # JWT config
│ ├── mail.config.ts # Mail config
│ └── redis.config.ts # Redis config
│
├── infra/ # Infrastructure and database
│ ├── clickhouse/ # ClickHouse integration
│ │ ├── client/ # ClickHouse client
│ │ ├── migrations/ # ClickHouse migrations
│ │ ├── repositories/ # ClickHouse repositories
│ │ ├── scripts/ # Migration scripts
│ │ └── services/ # ClickHouse services
│ ├── postgres/ # PostgreSQL integration
│ │ ├── migrations/ # Drizzle migrations
│ │ ├── repositories/ # Data access layer
│ │ └── schema/ # Drizzle schema definitions
│ ├── redis/ # Redis integration
│ └── seed/ # Database seeding scripts
│
├── storage/ # File storage
│ └── logs/ # Application logs
│
├── docs/ # Documentation
│ └── images/ # Documentation images
│
├── .github/ # GitHub workflows and templates
│ ├── ISSUE_TEMPLATE/ # Issue templates
│ └── workflows/ # CI/CD workflows
│
├── .husky/ # Git hooks
├── Dockerfile # Container configuration
├── docker-compose.yml # Multi-service setup
├── drizzle.config.ts # Drizzle ORM configuration
├── eslint.config.mjs # ESLint configuration
├── Makefile # Build and deployment commands
├── tsconfig.json # TypeScript configuration
└── package.json # Project dependencies and scripts
-
Configure your database in
.env:DATABASE_URL="postgresql://postgres:postgres@localhost:5432/elysia_db"
-
Generate database migrations:
make db-generate # or bunx drizzle-kit generate -
Run migrations:
make db-migrate # or bunx drizzle-kit migrate -
Seed database:
make db-seed # or bun run db:postgres:seed -
Open Drizzle Studio (database GUI):
make db-studio # or bunx drizzle-kit studio
-
Configure ClickHouse in
.env:CLICKHOUSE_HOST="http://localhost:8123" CLICKHOUSE_USER="app" CLICKHOUSE_PASSWORD="secret" CLICKHOUSE_DATABASE="app"
-
Run ClickHouse migrations:
make migrate-clickhouse # or bun run migrate:clickhouse -
Check migration status:
make migrate-clickhouse-status # or bun run migrate:clickhouse:status
The docker-compose.yml includes the following services:
| Service | Image | Port(s) | Description |
|---|---|---|---|
postgres |
postgres:18.1 | 5432 | PostgreSQL database |
redis |
redis:7-alpine | 6379 | Redis cache/queue |
clickhouse |
clickhouse/clickhouse-server:23.12 | 8123, 9000 | ClickHouse analytics DB |
app |
Custom (Dockerfile) | 3000 | ElysiaJS application |
# Start all services
docker-compose up -d
# View logs
docker-compose logs -f
# Stop all services
docker-compose down
# Remove volumes (reset data)
docker-compose down -v
# Rebuild application
docker-compose up --build app- ESLint: Configured for TypeScript with strict rules
- Prettier: Automatic code formatting
- Husky: Pre-commit hooks for code quality
- Lint-Staged: Runs ESLint and Prettier on staged files
# Server Commands
bun run dev:server # Start development server with hot reload
bun run start:server # Start production server
bun run build:server # Build server for production
# Worker Commands
bun run dev:worker # Start development worker with hot reload
bun run start:worker # Start production worker
bun run build:worker # Build worker for production
# API Commands (alias for server)
bun run dev:api # Start development API with hot reload
bun run start:api # Start production API
bun run build:api # Build API for production
# Run All Services
bun run dev:all # Start both server and worker in development mode
bun run start:all # Start both server and worker in production mode
bun run build:all # Build both server and worker
# Code Quality
bun run lint # Run ESLint
bun run format # Format code with Prettier
# Database (PostgreSQL)
bun run db:postgres:seed # Seed PostgreSQL database
# Database (ClickHouse)
bun run migrate:clickhouse # Run ClickHouse migrations
bun run migrate:clickhouse:status # Check ClickHouse migration status# Build image
docker build -t clean-elysia .
# Run container
docker run -p 3000:3000 \
-e DATABASE_URL="postgres://user:pass@host:5432/db" \
-e REDIS_HOST="redis-host" \
clean-elysia# Start all services
docker-compose up -d
# Scale specific services
docker-compose up --scale app=3Clean Architecture: Separation between API layer, Application services, and Infrastructure components
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow the existing code style
- Run
bun run lintandbun run formatbefore committing - Write meaningful commit messages
- Use conventional commit format
- ElysiaJS - The web framework
- Bun - JavaScript runtime and package manager
- Drizzle ORM - Type-safe database toolkit
- ClickHouse - Analytics database
- BullMQ - Queue system
If you have any questions or issues, please:
- Open an issue
- Start a discussion
Made with love by Fexend
