A modern, high-performance API starter template using Bun, Hono, MongoDB, and TypeScript.
- β‘οΈ Ultra-fast performance with Bun runtime
- π Hot reloading for fast development cycles
- π§© Modular architecture for scalability
- π Built-in authentication middleware and JWT support with expiration
- π‘οΈ Security-first design with rate limiting, secure headers, and CSRF protection
- π¦ Request validation for robust API design
- ποΈ MongoDB integration with Mongoose
- π¦ Compression support for optimized responses
- β TypeScript for type safety
- π Error handling middleware with proper stack trace management
- π¨ Rate limiting to prevent brute force attacks
- π Secure headers (XSS, clickjacking, MIME sniffing protection)
- π¨ Prettier code formatting with automated enforcement
- πͺ Husky git hooks for pre-commit and pre-push quality checks
- π Winston logger with daily rotation, structured logging, and multiple log levels
- Getting Started
- Usage
- Logging
- Security
- API Routes
- User Model
- Project Structure
- Changelog
- Contributing
- License
- Contact
Before you begin, make sure you have the following installed:
- Bun (v1.0.0 or newer)
- MongoDB or MongoDB Atlas
- Clone this repository:
git clone https://github.com/ProMehedi/bun-hono-api-starter.git
cd bun-hono-api-starter- Install dependencies:
bun installCreate a .env file in the root directory with the following variables:
# Required
JWT_SECRET=your-super-secret-key-minimum-32-characters-long
MONGO_URI=mongodb://localhost:27017/bun-hono-api
# Optional
PORT=8000
NODE_ENV=development
# Logging (Optional)
LOG_LEVEL=info # Log level: debug, info, warn, error (default: debug in dev, info in production)
LOG_TO_FILE=both # Log destination: console, file, both, auto (default: both)
# - console: console only
# - file: file only
# - both: console + file
# - auto: console in dev, file in production
# Production only (comma-separated list)
ALLOWED_ORIGINS=https://yourdomain.com,https://app.yourdomain.comSecurity Note:
JWT_SECRETmust be at least 32 characters long and kept secure- Never commit
.envfile to version control - In production, set
NODE_ENV=productionand configureALLOWED_ORIGINSfor CORS
Run the development server with hot reloading:
bun devStart the production server:
bun startThis project uses Prettier for code formatting with automatic enforcement via Husky git hooks.
Format all files (auto-fix):
bun run formatCheck formatting (verify only):
bun run format:checkGit Hooks:
- Pre-commit: Automatically checks code formatting and TypeScript types before allowing commits
- Pre-push: Ensures all formatting and type checks pass before pushing to remote
If formatting fails, run bun run format to auto-fix issues.
This starter template includes comprehensive logging capabilities using Winston with daily log rotation.
- Structured JSON logging for production environments
- Human-readable console output for development
- Daily log rotation with automatic compression
- Multiple log levels:
debug,info,warn,error - Separate log files for different log types:
app-YYYY-MM-DD.log- General application logs (info, warn, error)error-YYYY-MM-DD.log- Error logs onlydebug-YYYY-MM-DD.log- Debug logs (whenLOG_LEVEL=debug)exceptions-YYYY-MM-DD.log- Uncaught exceptionsrejections-YYYY-MM-DD.log- Unhandled promise rejections
- HTTP request logging with method, path, status, duration, IP, and user agent
- Configurable log destinations (console, file, or both)
- Automatic log retention and cleanup
Configure logging behavior using environment variables:
LOG_LEVEL (Optional):
debug- Most verbose, includes debug logsinfo- Standard logging (default in production)warn- Warnings and errors onlyerror- Errors only- Default:
debugin development,infoin production
LOG_TO_FILE (Optional):
console- Log to console onlyfile- Log to files onlyboth- Log to both console and files (default)auto- Console in development, files in production- Default:
both
App Logs (app-YYYY-MM-DD.log):
- Contains: info, warn, error level logs
- Max size: 50MB per file
- Retention: 14 days
- Compressed: Yes (after rotation)
Error Logs (error-YYYY-MM-DD.log):
- Contains: error level logs only
- Max size: 20MB per file
- Retention: 30 days
- Compressed: Yes (after rotation)
Debug Logs (debug-YYYY-MM-DD.log):
- Contains: debug level logs (only when
LOG_LEVEL=debug) - Max size: 100MB per file
- Retention: 3 days (short retention due to verbosity)
- Compressed: Yes (after rotation)
Exception/Rejection Logs:
- Contains: Uncaught exceptions and unhandled promise rejections
- Max size: 20MB per file
- Retention: 30 days
- Compressed: Yes (after rotation)
All log files are stored in the logs/ directory at the project root:
logs/
βββ app-2026-01-06.log
βββ error-2026-01-06.log
βββ debug-2026-01-06.log (if LOG_LEVEL=debug)
βββ exceptions-2026-01-06.log
βββ rejections-2026-01-06.log
βββ .audit/ # Audit files for log rotation
Every HTTP request is automatically logged with the following information:
- HTTP method (GET, POST, PUT, etc.)
- Request path
- Full URL
- Response status code
- Request duration (in milliseconds)
- User agent
- Client IP address
Example log entry:
{
"timestamp": "2026-01-06T10:30:45.123Z",
"level": "info",
"message": "HTTP Request",
"method": "POST",
"path": "/api/v1/users/login",
"url": "http://localhost:8000/api/v1/users/login",
"status": 200,
"duration": "45ms",
"userAgent": "Mozilla/5.0...",
"ip": "127.0.0.1"
}Development (console + file logging):
LOG_LEVEL=debug
LOG_TO_FILE=bothProduction (file logging only):
LOG_LEVEL=info
LOG_TO_FILE=fileDebugging (verbose console output):
LOG_LEVEL=debug
LOG_TO_FILE=consoleThis starter template includes comprehensive security features:
- JWT-based authentication with 7-day token expiration
- Protected routes requiring valid JWT tokens
- Admin-only routes with role-based access control
- Password hashing using Bun's built-in bcrypt implementation
- Mass assignment protection - prevents privilege escalation
-
Rate Limiting:
- Strict rate limiting (5 requests per 15 minutes) on sensitive endpoints (login, register)
- Standard rate limiting (60 requests per minute) on general endpoints
- Prevents brute force attacks and API abuse
-
Secure Headers:
- X-Frame-Options: DENY (prevents clickjacking)
- X-XSS-Protection: 1; mode=block (XSS protection)
- X-Content-Type-Options: nosniff (prevents MIME sniffing)
- Referrer-Policy: strict-origin-when-cross-origin
- Content-Security-Policy (in production)
-
CSRF Protection: Enabled in production mode
-
CORS Configuration: Configurable allowed origins for production
- β Input validation on all user inputs
- β Email format validation
- β Password length requirements (minimum 6 characters)
- β Error messages don't leak sensitive information
- β Stack traces only shown in development
- β Environment variable validation (throws error if missing)
- β Password hashes never returned in API responses
- β Admin role cannot be set during user registration
The API implements two levels of rate limiting:
-
Strict Rate Limit (Login/Register endpoints):
- 5 requests per 15 minutes per IP
- Prevents brute force attacks
-
Standard Rate Limit (All other endpoints):
- 60 requests per minute per IP
- Prevents API abuse
Rate limit headers are included in responses:
X-RateLimit-Limit: Maximum requests allowedX-RateLimit-Remaining: Remaining requests in current windowX-RateLimit-Reset: Unix timestamp when limit resetsRetry-After: Seconds to wait when limit exceeded (429 status)
| Method | Route | Description | Auth Required | Admin Only |
|---|---|---|---|---|
| GET | /api/v1 |
API welcome message | No | No |
| POST | /api/v1/users |
Create a new user | No | No |
| POST | /api/v1/users/login |
User login | No | No |
| GET | /api/v1/users/profile |
Get user profile | Yes | No |
| PUT | /api/v1/users/profile |
Update user profile | Yes | No |
| GET | /api/v1/users |
Get all users | Yes | Yes |
| GET | /api/v1/users/:id |
Get user by ID | Yes | Yes |
Create User:
POST /api/v1/users
Note: This endpoint has strict rate limiting (5 requests per 15 minutes)
{
"name": "Mehedi Hasan",
"email": "mehedi@example.com",
"password": "123456"
}Response:
{
"success": true,
"data": {
"_id": "...",
"name": "Mehedi Hasan",
"email": "mehedi@example.com",
"isAdmin": false,
"token": "jwt_token_here"
},
"message": "User created successfully"
}Note: The isAdmin field cannot be set via API - it's always false for security.
User Login:
POST /api/v1/users/login
Note: This endpoint has strict rate limiting (5 requests per 15 minutes) to prevent brute force attacks
{
"email": "mehedi@example.com",
"password": "123456"
}Response:
{
"success": true,
"data": {
"_id": "...",
"name": "Mehedi Hasan",
"email": "mehedi@example.com",
"isAdmin": false,
"token": "jwt_token_here"
},
"message": "User logged in successfully"
}Note: JWT tokens expire after 7 days. Include the token in the Authorization header for protected routes.
Update Profile:
PUT /api/v1/users/profile
Authorization: Bearer your_jwt_token
{
"name": "Updated Name",
"email": "updated@example.com",
"password": "newpassword"
}All fields are optional. The response will not include the password hash:
Response:
{
"user": {
"_id": "...",
"name": "Updated Name",
"email": "updated@example.com",
"isAdmin": false
}
}Protected Routes: Include the JWT token in the Authorization header:
Authorization: Bearer your_jwt_token
The user model includes the following properties:
interface IUser extends Document {
_id: Types.ObjectId
name: string
email: string
password: string
isAdmin: boolean
matchPassword: (pass: string) => Promise<boolean>
createdAt: Date
updatedAt: Date
}Key features:
- Password hashing with Bun's built-in bcrypt implementation (cost: 10)
- Automatic email validation (must match email pattern)
- Admin role support with the
isAdminproperty - Password matching method for secure authentication
- Timestamps automatically managed by Mongoose
- Security: The
isAdminfield cannot be set via API endpoints - it must be set directly in the database for security reasons
βββ config/ # Configuration files
β βββ compress.config.ts # Compression configuration
β βββ db.config.ts # Database configuration
β βββ index.ts # Config exports
βββ controllers/ # Route controllers
β βββ user.controllers.ts # User-related controllers
β βββ index.ts # Controller exports
βββ middlewares/ # Hono middlewares
β βββ auth.middlewares.ts # Authentication middleware
β βββ error.middlewares.ts # Error handling middleware
β βββ logger.middlewares.ts # HTTP request logging middleware
β βββ rateLimit.middlewares.ts # Rate limiting middleware
β βββ index.ts # Middleware exports
βββ models/ # Database models
β βββ user.model.ts # User model schema
β βββ index.ts # Model exports
βββ routes/ # API routes
β βββ user.routes.ts # User routes
β βββ index.ts # Route exports
βββ utils/ # Utility functions
β βββ genToken.ts # JWT token generator
β βββ logger.ts # Winston logger configuration
β βββ index.ts # Utils exports
βββ server.ts # Main application entry
βββ .env # Environment variables (create this)
βββ .gitignore # Git ignore file
βββ bun.lock # Bun lock file
βββ package.json # Package configuration
βββ README.md # This file
βββ tsconfig.json # TypeScript configuration
βββ wrangler.toml # Cloudflare Workers configuration
Logging Feature:
- π Added comprehensive Winston logger with daily log rotation
- π Implemented HTTP request logging middleware with method, path, status, duration, IP, and user agent
- π Added structured JSON logging for production and human-readable console output for development
- ποΈ Created separate log files for app logs, errors, debug logs, exceptions, and rejections
- βοΈ Added configurable log destinations (
LOG_TO_FILE: console, file, both, auto) - π Added configurable log levels (
LOG_LEVEL: debug, info, warn, error) - ποΈ Implemented automatic log compression and retention policies
- π Log files stored in
logs/directory with daily rotation - π Added context logger helper for structured logging with custom context
Dependencies:
- Added
winstonv3.19.0 for logging - Added
winston-daily-rotate-filev5.0.0 for log rotation
TypeScript Fixes:
- β
Fixed
IUserinterface type incompatibility - changedSchema.Types.ObjectIdtoTypes.ObjectIdfor proper TypeScript type checking - β
Fixed Mongoose pre-save hook - removed deprecated
next()callback in favor of modern async/await pattern - β Improved type safety with correct Mongoose TypeScript types
- β All TypeScript compilation errors resolved
Code Quality & Developer Experience:
- π§ Updated user model to use modern Mongoose async hook pattern
- π Fixed typo in comment ("Heiger" β "Higher")
- π¨ Added Prettier code formatting with comprehensive configuration
- πͺ Integrated Husky git hooks for automated code quality checks
- pre-commit hook: Automatically runs
format:checkandtypecheckbefore commits - pre-push hook: Ensures code formatting and type checking pass before pushing
- pre-commit hook: Automatically runs
- π¦ Added format scripts:
format(auto-fix) andformat:check(verify only) - β Automatic code quality enforcement prevents committing unformatted or type-unsafe code
Security Improvements:
- π Fixed critical mass assignment vulnerability -
isAdmincan no longer be set during registration - π Added JWT token expiration (7 days) with proper validation
- π‘οΈ Implemented rate limiting middleware to prevent brute force attacks
- π Added secure headers middleware (XSS, clickjacking, MIME sniffing protection)
- π‘οΈ Added CSRF protection for production environments
- π Fixed JWT secret validation - now throws error if missing
- π Fixed password hash leak in profile update response
- π‘οΈ Improved CORS configuration with environment-based origin restrictions
- π Fixed error handler stack trace exposure logic
- β Added comprehensive input validation (email format, password length)
Code Quality:
- π¦ Removed deprecated
@types/mongoosedependency - π Standardized environment variable access to
process.env - β Improved TypeScript types and error handling
- π Updated to modern Hono JWT API (
sign/verifyinstead of deprecatedJwt) - π Enhanced error messages and validation feedback
Dependencies:
- Updated to Hono v4.11.3
- Mongoose v9.1.1 (includes built-in TypeScript types)
- Complete project restructuring with improved modularity
- Added compression support with polyfill for
CompressionStream - Enhanced error handling middleware
- Updated MongoDB connection with better error feedback
- Improved CORS configuration for better security
- Updated to latest Hono v4.7.4 and Mongoose v8.12.1
- Enhanced TypeScript support and typings
- Standardized export patterns across modules
- Added admin role functionality with middleware protection
- Added profile editing functionality
- Initial release with basic CRUD functionality
- MongoDB integration
- JWT-based authentication
- Basic error handling
Contributions are welcome! Please feel free to submit a Pull Request.
- 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
This project is licensed under the MIT License - see the LICENSE file for details.
Mehedi Hasan - admin@promehedi.com
Project Link: https://github.com/ProMehedi/bun-hono-api-starter