Configuration
Medusa applications are configured using a medusa-config.js or medusa-config.ts file in the root of your project.
Configuration File
The configuration file exports a configuration object using the defineConfig helper:
import { defineConfig } from "@medusajs/utils"
export default defineConfig({
projectConfig: {
databaseUrl: process.env.DATABASE_URL,
http: {
jwtSecret: process.env.JWT_SECRET,
cookieSecret: process.env.COOKIE_SECRET,
adminCors: process.env.ADMIN_CORS,
storeCors: process.env.STORE_CORS,
authCors: process.env.AUTH_CORS,
},
},
})
const { defineConfig } = require("@medusajs/utils")
module.exports = defineConfig({
projectConfig: {
databaseUrl: process.env.DATABASE_URL,
http: {
jwtSecret: process.env.JWT_SECRET,
cookieSecret: process.env.COOKIE_SECRET,
adminCors: process.env.ADMIN_CORS,
storeCors: process.env.STORE_CORS,
authCors: process.env.AUTH_CORS,
},
},
})
Configuration Structure
The configuration object has the following structure:
projectConfig: General configurations (database, HTTP, Redis)
admin: Admin dashboard configurations
modules: Module configurations and providers
plugins: Plugin configurations
featureFlags: Feature flag toggles
Project Configuration
Database Configuration
export default defineConfig({
projectConfig: {
// Database connection URL
databaseUrl: process.env.DATABASE_URL,
// Optional: Database schema (default: "public")
databaseSchema: "public",
// Optional: Database driver options
databaseDriverOptions: {
pool: {
min: 2,
max: 10,
idleTimeoutMillis: 30000,
},
},
},
})
The database URL format is: postgres://[user][:password]@[host][:port]/[dbname]
HTTP Configuration
export default defineConfig({
projectConfig: {
http: {
// JWT configuration
jwtSecret: process.env.JWT_SECRET,
jwtExpiresIn: "1d",
jwtPublicKey: process.env.JWT_PUBLIC_KEY, // For asymmetric JWT
jwtOptions: {
algorithm: "HS256", // or RS256 for asymmetric
},
jwtVerifyOptions: {
algorithms: ["HS256"],
},
// Cookie configuration
cookieSecret: process.env.COOKIE_SECRET,
// CORS configuration
adminCors: process.env.ADMIN_CORS || "http://localhost:7001",
storeCors: process.env.STORE_CORS || "http://localhost:8000",
authCors: process.env.AUTH_CORS || "http://localhost:7001",
// Authentication methods per actor type
authMethodsPerActor: {
user: ["emailpass"], // Admin users
customer: ["emailpass"], // Storefront customers
},
},
},
})
jwtSecret and cookieSecret are required for production. Use strong, random secrets.
Redis Configuration
For production, configure Redis for caching and event handling:
export default defineConfig({
projectConfig: {
redisUrl: process.env.REDIS_URL,
redisOptions: {
// Custom retry strategy
retryStrategy(retries) {
const delay = Math.min(Math.pow(2, retries) * 50, 4000)
const jitter = Math.floor(Math.random() * 200)
return delay + jitter
},
},
},
})
Worker Mode
Configure how your application handles HTTP requests and background jobs:
export default defineConfig({
projectConfig: {
workerMode: "shared", // "shared" | "server" | "worker"
},
})
You can also set this via environment variable:
MEDUSA_WORKER_MODE=server
Admin Configuration
export default defineConfig({
admin: {
// Disable admin dashboard
disable: process.env.DISABLE_ADMIN === "true",
// Admin path (default: "/app")
path: "/admin",
// Backend URL for admin
backendUrl: process.env.MEDUSA_BACKEND_URL || "http://localhost:9000",
// Storefront URL (for generating customer links)
storefrontUrl: process.env.STOREFRONT_URL || "http://localhost:8000",
// Output directory for admin build
outDir: "./build",
// Max file upload size (bytes)
maxUploadFileSize: 10 * 1024 * 1024, // 10MB
},
})
Module Configuration
Configure Medusa modules and providers:
import { Modules } from "@medusajs/utils"
export default defineConfig({
modules: [
{
key: Modules.FILE,
resolve: "@medusajs/file",
options: {
providers: [
{
resolve: "@medusajs/file-s3",
id: "s3",
options: {
bucket: process.env.S3_BUCKET,
region: process.env.S3_REGION,
access_key_id: process.env.S3_ACCESS_KEY_ID,
secret_access_key: process.env.S3_SECRET_ACCESS_KEY,
},
},
],
},
},
{
key: Modules.NOTIFICATION,
resolve: "@medusajs/notification",
options: {
providers: [
{
resolve: "@medusajs/notification-sendgrid",
id: "sendgrid",
options: {
api_key: process.env.SENDGRID_API_KEY,
from: process.env.SENDGRID_FROM,
},
},
],
},
},
{
key: Modules.PAYMENT,
resolve: "@medusajs/payment",
options: {
providers: [
{
resolve: "@medusajs/payment-stripe",
id: "stripe",
options: {
api_key: process.env.STRIPE_API_KEY,
webhook_secret: process.env.STRIPE_WEBHOOK_SECRET,
},
},
],
},
},
// Disable a module
{
key: Modules.INDEX,
disable: true,
},
],
})
Module Provider Configuration
Modules can have multiple providers configured. Each provider needs:
resolve: Package name or path to the provider
id: Unique identifier for the provider
options: Provider-specific configuration
is_default (optional): Set as the default provider
Plugin Configuration
export default defineConfig({
plugins: [
{
resolve: "medusa-payment-stripe",
options: {
api_key: process.env.STRIPE_API_KEY,
},
},
{
resolve: "medusa-fulfillment-shippo",
options: {
api_key: process.env.SHIPPO_API_KEY,
},
},
],
})
Feature Flags
Enable or disable experimental features:
export default defineConfig({
featureFlags: {
translation: process.env.MEDUSA_FF_TRANSLATION === "true",
rbac: process.env.MEDUSA_FF_RBAC === "true",
index_engine: process.env.ENABLE_INDEX_MODULE === "true",
},
})
Feature flags allow you to enable experimental features. Check the documentation for each feature flag before enabling.
Complete Production Example
import { defineConfig, Modules } from "@medusajs/utils"
export default defineConfig({
projectConfig: {
databaseUrl: process.env.DATABASE_URL,
redisUrl: process.env.REDIS_URL,
workerMode: process.env.MEDUSA_WORKER_MODE as any,
http: {
jwtSecret: process.env.JWT_SECRET,
cookieSecret: process.env.COOKIE_SECRET,
jwtExpiresIn: "7d",
adminCors: process.env.ADMIN_CORS,
storeCors: process.env.STORE_CORS,
authCors: process.env.AUTH_CORS,
},
databaseDriverOptions: {
pool: {
min: 2,
max: 10,
},
},
},
admin: {
backendUrl: process.env.MEDUSA_BACKEND_URL,
storefrontUrl: process.env.STOREFRONT_URL,
maxUploadFileSize: 10 * 1024 * 1024, // 10MB
},
modules: [
{
key: Modules.FILE,
resolve: "@medusajs/file",
options: {
providers: [
{
resolve: "@medusajs/file-s3",
id: "s3",
options: {
bucket: process.env.S3_BUCKET,
region: process.env.S3_REGION,
access_key_id: process.env.S3_ACCESS_KEY_ID,
secret_access_key: process.env.S3_SECRET_ACCESS_KEY,
},
},
],
},
},
{
key: Modules.CACHE,
resolve: "@medusajs/cache-redis",
options: {
redisUrl: process.env.REDIS_URL,
},
},
{
key: Modules.EVENT_BUS,
resolve: "@medusajs/event-bus-redis",
options: {
redisUrl: process.env.REDIS_URL,
},
},
],
featureFlags: {},
})
Configuration Validation
Medusa validates your configuration on startup. Common errors:
- Missing
jwtSecret: Required for JWT authentication
- Missing
cookieSecret: Required for session management
- Invalid database URL: Check connection string format
- Module configuration errors: Verify module options
In production mode (NODE_ENV=production), configuration errors will cause the application to fail to start. In development, warnings are logged instead.
Environment-Specific Configuration
You can create different configurations for different environments:
import { defineConfig } from "@medusajs/utils"
const isProduction = process.env.NODE_ENV === "production"
export default defineConfig({
projectConfig: {
databaseUrl: process.env.DATABASE_URL,
http: {
jwtSecret: process.env.JWT_SECRET || (isProduction ? undefined : "supersecret"),
cookieSecret: process.env.COOKIE_SECRET || (isProduction ? undefined : "supersecret"),
adminCors: isProduction
? process.env.ADMIN_CORS
: "http://localhost:7001",
storeCors: isProduction
? process.env.STORE_CORS
: "http://localhost:8000",
},
},
})