3.4. Modules and Services

In this chapter, you’ll learn about modules, their main service, and how to create them.

What is a Module?#

A module is a package of reusable functionalities. It can be integrated into your Medusa application without affecting the overall system.

Use modules to customize or develop commerce and architectural features in your Medusa application.


How to Create a Module?#

Steps Summary
  1. Create module's main service.
  2. Create module definition.
  3. Add module to Medusa's configurations.

Modules are created in a sub-directory of src/modules.

For example, create the directory src/modules/hello.

1. Create Main Service#

A module must define a service. A service is a TypeScript or JavaScript class holding methods related to a business logic or commerce functionality.

For example, create the file src/modules/hello/service.ts with the following content:

src/modules/hello/service.ts
1export default class HelloModuleService {2  getMessage() {3    return "Hello, world!"4  }5}

2. Export Module Definition#

A module must have an index.ts file in its root directory that exports its definition. The definition specifies the main service of the module.

For example, create the file src/modules/hello/index.ts with the following content:

src/modules/hello/index.ts
1import HelloModuleService from "./service"2import { Module } from "@medusajs/utils"3
4export const HELLO_MODULE = "helloModuleService"5
6export default Module(HELLO_MODULE, {7  service: HelloModuleService,8})

You use the Module function imported from @medusajs/utils to create the module definition. It requires two parameters:

  1. The module's name.
  2. An object with a required property service indicating the module's main service.

3. Add Module to Configurations#

The last step is to add the module in Medusa’s configurations.

In medusa-config.js, add a modules property and pass to it your custom module:

medusa-config.js
1import { HELLO_MODULE } from "./src/modules/hello"2// ...3
4module.exports = defineConfig({5  // ...6  modules: {7    [HELLO_MODULE]: {8      resolve: "./modules/hello",9    },10  },11})

Its key (helloModuleService or HELLO_MODULE) is the name of the module’s main service. It will be registered in the Medusa container with that name. It should also be the same name passed as the first parameter to the Module function in the module's definition.

Its value is an object having the resolve property, whose value is either a path to module's directory relative to src(it shouldn't include src in the path), or an npm package’s name.


Test the Module#

Since the module's main service is registered in the Medusa container, you can resolve it in other resources to use its functionalities.

For example, create the API route src/api/store/custom/route.ts with the following content:

src/api/store/custom/route.ts
1import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"2import HelloModuleService from "../../../modules/hello/service"3import { HELLO_MODULE } from "../../../modules/hello"4
5export async function GET(6  req: MedusaRequest,7  res: MedusaResponse8): Promise<void> {9  const helloModuleService: HelloModuleService = req.scope.resolve(10    HELLO_MODULE11  )12
13  res.json({14    message: helloModuleService.getMessage(),15  })16}

Then, start the Medusa application:

Finally, send a GET request to /store/custom:

curl http://localhost:9000/store/custom

You’ll receive the following response:

1{2  "message": "Hello, world!"3}

When to Use Modules#

Use modules when
  • You're implementing a custom commerce feature. For example, you're implementing digital products.
  • You want to re-use your custom commerce functionalities across Medusa applications or use them in other environments, such as Edge functions and Next.js apps.
Was this chapter helpful?