This starter kit provides a robust foundation for building scalable and feature-rich REST APIs using ExpressJS and TypeScript.
- Logging: Advanced logging with
Pino
and log rotation usingfile-stream-rotator
- Database: Efficient data management with
Prisma ORM
- Events: Powerful event handling with
EventEmitter2
- Authentication: Secure bearer sessions and OAuth support (Google, Facebook, Twitter, GitHub) via
passportjs
- Authorization: Fine-grained access control with
Casl
- Validation: Request validation (Body, Parameters, Query) using
Zod
- Error Handling: Comprehensive error management system
- Dependency Injection: Service container with type-safe dependency management
- File Upload: S3 integration with
multer
- Video Upload: S3 integration with
multer
- Video Processing: Conversion to browser-compatible formats with
ffmpeg
- Redis: In-memory data structure store with
ioredis
- Caching: Improved performance through strategic caching
- Rate Limiting: Protect your API from abuse with
express-rate-limit
- Queues & Workers: Efficient task processing with
BullMQ
- Cron Jobs: Scheduled tasks using
cron
- i18n: Multi-language support
- Swagger: API documentation made easy
- PDF Generation: Create PDFs with
playwright
- Command-line Interface: Easy-to-use CLI commands with
commander
- Docker Support: Containerization for easy deployment
- CORS protection
- Rate limiting
- Request validation (Query, Parameters, Body)
- Secure authentication (Bearer sessions, OAuth)
- Hot-reload
- Performance-optimized architecture
- Code formatting with
Prettier
- Linting with
ESLint
- Path aliases for clean imports (e.g.,
#/common
,#/modules
)
- Clone the repository
- Install dependencies:
npm install
- Set up your environment variables
π You can use the .env.template
file to create your own .env
file
π Importantly, you need to have a running instance of redis
and mysql
on your machine to run this project.
If you need a more complete solution with docker-compose to setup everything, please check this repository: https://github.com/ghostlexly/ultimate-typescript-starter-kit
- Run the development server:
npm run start:dev
This starter kit includes a set of CLI commands to help you manage your application. Here are some examples:
npm run cli test:split-text this-is-a-test -s -
: Split a text into an arraynpm run cli seed:countries
: Seed the database with countries datanpm run cli create:admin-account [email protected] password
: Create an admin account
For a full list of available commands, run:
npm run cli
Project Root
βββ core/ # Core application logic and shared use cases
β βββ use-cases/ # Contains pure business logic implementations
| βββ event-handlers/ # Events that can be called
β # Independent of external frameworks/libraries
β
βββ modules/ # Modular feature-specific implementations
β βββ cart/ # Complete cart feature module
β βββ controllers/ # HTTP request handlers
β β βββ cart.admin.controller.ts # Admin-specific operations
β β βββ cart.controller.ts # Public cart operations
β βββ routes/ # Route definitions with type-safe parameters
β β βββ cart.admin.routes.ts # Protected admin routes
β β βββ cart.routes.ts # Public cart endpoints
β βββ validators/ # Input validation schemas
β β βββ cart.admin.validators.ts # Admin input validation
β β βββ cart.validators.ts # Public cart validation
β βββ cart.listener.ts # Event subscribers
β βββ test.config.ts # Test configuration
β βββ cart.service.ts # Cart-specific business logic
β
βββ cli/ # Command-line tools and utilities
β βββ cli.ts # CLI entry point with command registration
β βββ commands/ # Individual CLI command implementations
β βββ create-admin-account.cli.ts
β
βββ common/ # Reusable utilities and common functionality
βββ constants/ # Constants
βββ cron/ # Cron jobs
βββ database/ # Database utilities
βββ events/ # Event handlers
βββ exceptions/ # Custom error handling
βββ guards/ # Guards
βββ locales/ # Internationalization resources
βββ middlewares/ # Middlewares
βββ queue/ # Queue utilities
βββ services/ # Common business services
βββ storage/ # Storage utilities (S3, local, etc..)
βββ test/ # Test utilities
βββ throttlers/ # Throttlers
βββ transformers/ # Data transformation utilities
βββ types/ # TypeScript type definitions
βββ utils/ # Helper functions
βββ validators/ # Common validation rules
βββ views/ # Template files (EJS)
The Clean Architecture with modules by Tolga MALKOC
The heart of the application containing essential business logic.
core/
βββ use-cases/ # Contains pure business logic implementations
# Independent of external frameworks/libraries
Modular feature-specific implementations following vertical slice architecture.
modules/
βββ cart/ # Complete cart feature module
βββ controllers/ # HTTP request handlers
β βββ cart.admin.controller.ts # Admin-specific operations (CRUD for products, pricing)
β βββ cart.controller.ts # Public cart operations (add/remove items, checkout)
β
βββ routes/ # Route definitions with type-safe parameters
β βββ cart.admin.routes.ts # Protected admin routes (/admin/cart/)
β βββ cart.routes.ts # Public cart endpoints (/cart/)
β
βββ validators/ # Input validation schemas
β βββ cart.admin.validators.ts # Admin input validation (product management)
β βββ cart.validators.ts # Public cart validation (item quantities, user data)
β
βββ cart.listener.ts # Event subscribers (order completed, stock updates)
βββ test.config.ts # Test configuration
βββ cart.service.ts # Cart-specific business logic implementation
Command-line tools and utilities.
cli/
βββ cli.ts # CLI entry point with command registration
βββ commands/ # Individual CLI command implementations
βββ create-admin-account.cli.ts # CLI command for creating admin accounts
Reusable utilities and common functionality.
common/
βββ constants/ # Constants
|ββ cron/ # Cron jobs
|ββ database/ # Database utilities
|ββ events/ # Event handlers
βββ exceptions/ # Custom error handling
βββ guards/ # Guards
βββ locales/ # Internationalization resources
|ββ middlewares/ # Middlewares
|ββ queue/ # Queue utilities
βββ services/ # Common business services
|ββ storage/ # Storage utilities (S3, local, etc..)
|ββ test/ # Test utilities
|ββ throttlers/ # Throttlers
βββ transformers/ # Data transformation utilities
βββ types/ # TypeScript type definitions
βββ utils/ # Helper functions
βββ validators/ # Common validation rules
βββ views/ # Template files (EJS)
- Modularity: Each module is self-contained with its own MVC components
- Scalability: Easy to add new modules without affecting existing ones
- Maintainability: Clear separation of concerns and predictable file locations
- Testability: Isolated components are easier to unit test
- Developer Experience: Intuitive navigation and reduced cognitive load
- Keep feature modules independent of each other
- Implement consistent error handling across modules
- Follow the Single Responsibility Principle
This structure follows clean architecture principles while remaining practical for modern TypeScript applications.
Controller -> Use-Cases -> Services -> Repositories
- Controller : Receives requests and delegates to use-cases.
- Use-Case : Executes a complete business scenario by orchestrating multiple services from different modules.
- Event-Handlers : Handles events you can call from the services. The event-handlers can call use-cases. They are in core/event-handlers folder.
- Service : Provides specialized features (reusable).
- Repository : Interacts directly with the database.
Layer | Allowed to Import |
---|---|
Controller | Use-Case, Service |
Use-Case | Service, Repository, (and sometimes, other use-case) |
Event-Handler | Use-Case |
Service | Repository, Event-Handler |
Repository | Models, Database Utilities (e.g., Prisma) |
-
Controllers
- Can only interact with use-cases and Services.
- Why? They handle HTTP requests and delegate business logic to the Use-Cases.
Flow:
- Validates input
- Calls appropriate use-cases
- Returns responses
- Handles errors from the use-cases
-
Use-Cases
- Can interact with Services and Repositories.
- Why? They orchestrate business rules but don't deal with HTTP directly or low-level database logic.
Flow:
- Call any services from any modules
- Access database
- Throw errors
- Services
- Can interact with Repositories.
- Why? They encapsulate reusable logic and may coordinate multiple repositories.
- Repositories
- Can only interact with Models or database tools.
- Why? They directly access the data layer and shouldn't handle business logic.
It's a good thing that the files grows in numbers, it's keep all concerns separated.
Good naming conventions help you quickly identify use-cases:
- Use verbs like
Create
,Update
,Delete
,List
, orGet
. - Add the feature name for clarity, e.g.,
booking-create.usecase.ts
orcart-update.usecase.ts
Operations that are good candidates for use-cases:
- Complex business logic involving multiple steps
- Operations requiring transaction management
- Operations that coordinate multiple services
- Operations with complex validation rules
- Operations that emit multiple events
Operations that should stay in the service:
- Will be called in two or more use-cases
- Operations that don't require coordination or other services
- Simple CRUD operations (create, update, delete...)
- Single-step operations
- Internal utility methods
Use-Cases can't call other Use-Cases. If you want to call a function after your update or create crud operation, it's better to add them into a service and call this service in your use-cases. If use-cases need to share functionality and you need to import one use-case into another, you may reference one from another. However, if this creates a circular dependency, extract the common logic into a third independent use-case that both can utilize.
We welcome contributions!
This project is licensed under the MIT License.