A production-ready starter template for building scalable web applications with Hono and Bun. Built with clean architecture principles, TypeScript, and modern development practices.
- Hono framework with Bun runtime
- TypeScript with strict type checking
- Modular monorepo structure
- Clean architecture with separation of concerns
- PostgreSQL with Drizzle ORM
- ClickHouse for analytics and time-series data
- Redis for caching and session management
- Type-safe database operations and migrations
- Database seeding support
- OpenAPI/Swagger documentation with Scalar UI
- Zod schema validation
- JWT authentication
- RBAC (Role-Based Access Control) with guards
- CORS configuration
- Rate limiting
- Request/response logging with Pino
- Performance monitoring middleware
- Request ID tracking
- Body size limits
- Secure headers
- BullMQ for job queues
- Worker processes for background tasks
- Email queue system
- Bcrypt password hashing
- Crypto-JS encryption/decryption
- Authentication middleware
- Permission and role guards
- Secure headers with Helmet
- Hot reload with Bun watch mode
- Docker and Docker Compose support
- ESLint and Prettier configuration
- Husky for Git hooks
- Makefile for common tasks
- Concurrent development workflows
- Bun (latest version)
- PostgreSQL (v14 or higher)
- ClickHouse
- Redis (v6 or higher)
- Docker (optional)
- Make (optional)
- Clone the repository
git clone https://github.com/aolus-software/clean-hono.git
cd clean-hono- Install dependencies
bun install- Configure environment variables
cp .env.example .env
# Edit .env with your configuration- Set up databases
make db-migrate # Run PostgreSQL migrations
make db-seed # Seed database
make migrate-clickhouse # Run ClickHouse migrations- Start development server
make dev-all # Start API and worker# API Server
bun run dev:api # Development
bun run build:api # Build
bun run start:api # Production
# Worker
bun run dev:worker # Development
bun run build:worker # Build
bun run start:worker # Production
# Run both
bun run dev:all # Development mode
bun run build:all # Build all
bun run start:all # Production mode# View all commands
make help
# Development
make dev-api # Start API with hot reload
make dev-worker # Start worker with hot reload
make dev-all # Run both concurrently
# Production
make start-api # Start API server
make start-worker # Start worker service
make start-all # Run both concurrently
# Database
make db-generate # Generate migration files
make db-migrate # Run pending migrations
make db-push # Push schema to database (dev)
make db-studio # Open Drizzle Studio
make db-seed # Seed database
# ClickHouse
make migrate-clickhouse # Run migrations
make migrate-clickhouse-status # Check migration status
# Code Quality
make lint # Run ESLint
make format # Format with Prettierdocker-compose up --build # Build and run
docker-compose up -d # Run in background
docker-compose down # Stop servicesclean-hono/
├── apps/ # Applications
│ ├── api/ # Main API application
│ │ ├── app.ts # Hono app configuration
│ │ ├── bootstrap.ts # Service initialization
│ │ ├── serve.ts # Server entry point
│ │ ├── modules/ # Feature modules
│ │ │ ├── auth/ # Authentication
│ │ │ ├── home/ # Home routes
│ │ │ ├── profile/ # User profiles
│ │ │ └── settings/ # Settings
│ │ └── types/ # Type definitions
│ └── worker/ # Background workers
│ ├── queue/ # Queue handlers
│ └── worker/ # Worker implementations
├── config/ # Application configuration
│ ├── app.config.ts # App settings
│ ├── cors.config.ts # CORS settings
│ ├── database.config.ts # Database config
│ ├── mail.config.ts # Email config
│ ├── redis.config.ts # Redis config
│ └── env.ts # Environment validation
├── infra/ # Infrastructure
│ ├── clickhouse/ # ClickHouse setup
│ │ ├── client/ # Client configuration
│ │ ├── migrations/ # Migrations
│ │ ├── repositories/ # Data access
│ │ └── services/ # Business logic
│ ├── postgres/ # PostgreSQL setup
│ │ ├── migrations/ # Migrations
│ │ ├── repositories/ # Data access
│ │ └── schema/ # Drizzle schemas
│ ├── redis/ # Redis client
│ └── seed/ # Database seeding
├── packages/ # Shared packages
│ ├── cache/ # Caching utilities
│ ├── core/ # Core functionality
│ ├── default/ # Default values
│ ├── errors/ # Error handling
│ ├── guards/ # Auth guards
│ ├── logger/ # Logging
│ ├── mail/ # Email service
│ ├── middlewares/ # Middleware functions
│ ├── schemas/ # Validation schemas
│ ├── security/ # Security utilities
│ ├── toolkit/ # Helper functions
│ └── types/ # Shared types
├── storage/ # Storage directory
│ └── logs/ # Application logs
├── docs/ # Documentation
│ ├── guards/ # Guard documentation
│ └── validation/ # Validation docs
└── todos/ # Project todos
Required environment variables (see .env.example):
APP_NAME=Hono App
APP_PORT=3000
APP_URL=http://localhost:3000
APP_ENV=development
APP_TIMEZONE=UTC
APP_SECRET=your-app-secret
APP_JWT_SECRET=your-jwt-secret
APP_JWT_EXPIRES_IN=3600DATABASE_URL=postgresql://user:password@localhost:5432/databaseCLICKHOUSE_HOST=http://localhost:8123
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=
CLICKHOUSE_DATABASE=analyticsREDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USER=your-user
MAIL_PASSWORD=your-password
MAIL_FROM=noreply@example.comOnce the server is running, access the interactive API documentation:
- Swagger UI:
http://localhost:3000/docs - OpenAPI JSON:
http://localhost:3000/openapi.json
Each module in apps/api/modules/ follows a consistent pattern:
- Routes definition and registration
- Request/response schemas with Zod
- OpenAPI documentation
- Middleware and guards integration
Example modules:
auth/- Authentication endpoints (login, register, logout)home/- Public endpointsprofile/- User profile managementsettings/- Application settings
The template includes a robust guard system:
import { roleGuard } from "@packages/guards";
// Require admin role
app.get("/admin", roleGuard("admin"), (c) => {
// Handler
});import { permissionGuard } from "@packages/guards";
// Require specific permission
app.post("/posts", permissionGuard("posts.create"), (c) => {
// Handler
});Centralized error handling with custom error classes:
ForbiddenError- 403 ForbiddenNotFoundError- 404 Not FoundUnauthorizedError- 401 UnauthorizedUnprocessableEntityError- 422 Validation Error
Example:
import { NotFoundError } from "@packages/errors";
throw new NotFoundError("User not found");Create workers in apps/worker/queue/:
export const sendEmailQueue = async (job: Job) => {
const { to, subject, html } = job.data;
// Send email logic
};- Fork the repository
- Create a feature branch (
git checkout -b feature/name) - Commit your changes (
git commit -m 'Add feature') - Push to the branch (
git push origin feature/name) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
For issues and questions:
- Open an issue on GitHub
- Check the documentation in the
docs/directory
- Hono - The web framework
- Bun - JavaScript runtime and package manager
- Drizzle ORM - Type-safe database toolkit
If you have any questions or issues, please:
- Open an issue
- Start a discussion
Made by Aolus Software