Architecture
Medusa is built on a modular, composable architecture that separates concerns into distinct layers: modules, workflows, API routes, and the framework runtime.Architecture Overview
Core Concepts
Modules
Modules are self-contained packages that handle specific business domains. Each module:- Manages its own data models and database schema
- Exposes a service interface for business logic
- Can be used independently or composed together
- Is versioned and published to npm
Product
Cart
Order
Payment
Customer
Inventory
Fulfillment
Promotion
Notification
Workflows
Workflows orchestrate complex business processes by composing steps. They provide:- Compensation logic: Automatic rollback on failures
- Type safety: Full TypeScript support
- Composability: Reuse steps across workflows
- Observability: Built-in hooks and events
API Routes
API routes define HTTP endpoints with full framework integration:Framework Runtime
The@medusajs/framework package provides the core runtime that powers Medusa:
Key components:
1
Dependency Injection Container
2
Database Layer
PostgreSQL integration via MikroORM:
- Automatic migrations
- Entity relationships
- Query builder
- Transaction management
@medusajs/framework/src/database/3
HTTP Server
Express-based server with middleware:
- CORS configuration
- Authentication
- Request validation
- Response serialization
@medusajs/framework/src/http/4
Event Bus
Pub/sub system for async communication:
5
Workflow Engine
Orchestration runtime from
@medusajs/orchestration:- Step execution
- Compensation handling
- State management
- Retry logic
Module Architecture
Each module follows a consistent internal structure:Service Layer
Services contain business logic and use decorators for cross-cutting concerns:@InjectManager()- Inject entity manager (public methods)@InjectTransactionManager()- Inject transaction manager (protected methods)@MedusaContext()- Inject shared context parameter@EmitEvents()- Emit domain events after operation
Model Layer
Data models use MikroORM entities:Repository Layer
Repositories handle data access:Configuration
Medusa’s configuration is defined inmedusa-config.ts:
medusa-config.ts
packages/core/framework/src/config/config.ts
Monorepo Structure
Medusa’s source code is organized as a Yarn 3 monorepo:~/workspace/source/README.md and package.json
Request Lifecycle
Understanding how a request flows through Medusa:1
HTTP Request
Client sends request to
/admin/products2
Routing
Express routes to
src/api/admin/products/route.ts3
Middleware
- Authentication (JWT verification)
- CORS headers
- Request validation
- Query parsing
4
Handler Execution
Route handler executes:
5
Workflow Invocation
Handler invokes workflow:
6
Step Execution
Workflow executes steps sequentially:
- Validates input
- Calls module services
- Handles errors with compensation
7
Module Service
Module service performs business logic:
- Data validation
- Database operations
- Event emission
8
Response
Handler returns JSON response:
Error Handling
Medusa usesMedusaError for consistent error handling:
NOT_FOUND- Resource doesn’t existINVALID_DATA- Invalid input or stateNOT_ALLOWED- Operation not permittedDUPLICATE_ERROR- Unique constraint violationUNAUTHORIZED- Authentication requiredPAYMENT_AUTHORIZATION_ERROR- Payment processing failed
Event System
Modules emit events for async operations:product.created,product.updated,product.deletedorder.placed,order.fulfilled,order.canceledcart.created,cart.updatedcustomer.created,customer.updated
Development Workflow
Local Development
Testing Strategy
- Unit tests:
packages/*/__tests__/*.spec.ts - Integration tests:
packages/*/integration-tests/__tests__/*.spec.ts - API tests:
integration-tests/http/__tests__/*.spec.ts - Framework: Jest 29 (backend), Vitest 3 (frontend)