Skip to main content
Custom modules allow you to extend Medusa with domain-specific business logic while maintaining the framework’s architectural patterns. Modules are self-contained units that can manage their own data models, services, and business logic.

What is a Module?

A module in Medusa is a package that:
  • Encapsulates specific domain logic (e.g., product management, inventory)
  • Manages its own data models and database schema
  • Exposes a service interface for other parts of the application
  • Can be easily replaced or extended

Creating a Basic Module

1

Define the Module Entry Point

Create an index.ts file that exports your module using the Module utility:
src/modules/brand/index.ts
2

Create Data Models

Define your entities using MikroORM decorators:
src/modules/brand/models/brand.ts
Export your models:
src/modules/brand/models/index.ts
3

Create the Module Service

Extend MedusaService to create your module’s main service:
src/modules/brand/services/brand-module-service.ts
The MedusaService base class automatically provides:
  • createBrands() - Create one or more brands
  • updateBrands() - Update brands
  • listBrands() - List brands with filtering
  • listAndCountBrands() - List with pagination
  • retrieveBrand() - Get a single brand by ID
  • deleteBrands() - Delete brands
  • softDeleteBrands() - Soft delete brands
  • restoreBrands() - Restore soft-deleted brands
4

Define Type Definitions

Create TypeScript interfaces for your DTOs:
src/modules/brand/types/index.ts
5

Register the Module

Add your module to medusa-config.ts:
medusa-config.ts

Using Service Decorators

Medusa provides decorators for common service patterns:

@InjectManager

Injects the database entity manager into the method context. Use this for public methods:

@InjectTransactionManager

Injects a transactional entity manager. Use this for protected methods that modify data:

@MedusaContext

Marks a parameter as the shared context, which contains the transaction manager and metadata:

Module Configuration

You can define configuration options for your module:
src/modules/brand/types/index.ts
Access configuration in your service:

Best Practices

  • Keep modules focused on a single domain
  • Use the base MedusaService methods instead of reimplementing CRUD operations
  • Apply @InjectManager() to public methods and @InjectTransactionManager() to protected methods
  • Always include @MedusaContext() parameter for database operations
  • Define clear DTO interfaces for type safety
  • Use soft deletes for data that may need to be restored

Next Steps

Create Workflows

Compose multi-step business processes

Create Services

Build internal services for module logic