Skip to main content

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
Module structure:
Available modules:

Product

Catalog, variants, options, collections

Cart

Shopping cart, line items, totals

Order

Order management, fulfillment, returns

Payment

Payment processing, refunds

Customer

Customer accounts, groups

Inventory

Stock levels, reservations

Fulfillment

Shipping, delivery providers

Promotion

Discounts, campaigns, rules

Notification

Multi-channel notifications

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
Workflow anatomy:
Workflow execution:

API Routes

API routes define HTTP endpoints with full framework integration:
Route file location determines URL:

Framework Runtime

The @medusajs/framework package provides the core runtime that powers Medusa: Key components:
1

Dependency Injection Container

Uses Awilix for dependency management:
From @medusajs/framework/src/container.ts
2

Database Layer

PostgreSQL integration via MikroORM:
  • Automatic migrations
  • Entity relationships
  • Query builder
  • Transaction management
From @medusajs/framework/src/database/
3

HTTP Server

Express-based server with middleware:
  • CORS configuration
  • Authentication
  • Request validation
  • Response serialization
From @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:
Decorator patterns from CLAUDE.md:
  • @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 in medusa-config.ts:
medusa-config.ts
Configuration handling from packages/core/framework/src/config/config.ts

Monorepo Structure

Medusa’s source code is organized as a Yarn 3 monorepo:
From ~/workspace/source/README.md and package.json

Request Lifecycle

Understanding how a request flows through Medusa:
1

HTTP Request

Client sends request to /admin/products
2

Routing

Express routes to src/api/admin/products/route.ts
3

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 uses MedusaError for consistent error handling:
Error types:
  • NOT_FOUND - Resource doesn’t exist
  • INVALID_DATA - Invalid input or state
  • NOT_ALLOWED - Operation not permitted
  • DUPLICATE_ERROR - Unique constraint violation
  • UNAUTHORIZED - Authentication required
  • PAYMENT_AUTHORIZATION_ERROR - Payment processing failed
From CLAUDE.md section 5.4

Event System

Modules emit events for async operations:
Common events:
  • product.created, product.updated, product.deleted
  • order.placed, order.fulfilled, order.canceled
  • cart.created, cart.updated
  • customer.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)
From CLAUDE.md section 3

Performance Considerations

Database Indexing: Modules automatically create indexes on foreign keys and frequently queried fields.
Query Optimization: Use the Query API for efficient data fetching with automatic join optimization.
Caching: Enable Redis for session storage and caching:
Worker Mode: Separate HTTP and background workers:

Next Steps

Create Your First Workflow

Learn to build custom workflows with compensation logic

Build Custom Modules

Extend Medusa with your own business domain modules

API Route Development

Create custom API endpoints with full type safety

Module Development

Deep dive into module architecture and patterns