Medusa.js E-Commerce Development
Medusa — Node.js open-source e-commerce framework, Shopify alternative for developers. Version 2.x (2024) completely rewritten: modular architecture via Medusa Modules, new IoC container, improved workflow-engine. Stack: TypeScript, Node.js 20+, PostgreSQL, Redis.
Medusa 2.x Architecture
Unlike monolithic v1, Medusa 2.x based on independent modules:
┌─────────────────────────────┐
│ Medusa Application │
├─────────────┬───────────────┤
│ HTTP Layer │ Workflows │ │
├─────────────┴───────────────┤
│ Module Container │
├──────┬───────┬────────┬─────┤
│ Product Module │ Order │ Cart│
├──────┴───────┴────────┴─────┤
│ Infrastructure Layer │
│ PostgreSQL + Redis + S3 │
└─────────────────────────────┘
Each module — independent package with own schema, services, events. Allows replacing parts.
Products and Variants
Product structure via hierarchy: Product → ProductVariant → Price:
const product = await productModuleService.createProducts({
title: 'Winter Jacket',
handle: 'jacket-winter',
status: ProductStatus.PUBLISHED,
options: [
{ title: 'Size', values: ['S', 'M', 'L', 'XL'] },
{ title: 'Color', values: ['Black', 'Blue'] },
],
variants: [
{
title: 'S / Black',
sku: 'JACKET-S-BLACK',
options: { Size: 'S', Color: 'Black' },
prices: [{ amount: 299900, currency_code: 'rub' }],
},
],
});
Workflows and Business Logic
Workflows — sagas with compensation and rollback:
const validateInventoryStep = createStep(
'validate-inventory',
async ({ variantId, quantity }, context) => {
const inventoryService = context.container.resolve('inventory');
const available = await inventoryService.retrieveAvailableQuantity(variantId);
if (available < quantity) throw new Error(`Insufficient: ${available} available`);
return new StepResponse({ available });
}
);
export const customOrderWorkflow = createWorkflow(
'custom-order-workflow',
function (input) {
const { available } = validateInventoryStep(input);
return new WorkflowResponse({ available });
}
);
Payment Gateways
Supports Stripe, PayPal, custom providers extending AbstractPaymentProvider.
Deployment
Docker compose with PostgreSQL, Redis, worker process:
services:
medusa:
build: .
environment:
NODE_ENV: production
DATABASE_URL: postgresql://user:pass@postgres:5432/medusa
command: npx medusa db:migrate && npx medusa start
medusa-worker:
build: .
environment:
MEDUSA_WORKER_MODE: worker
command: npx medusa start
Timeline
- Basic store: Medusa + Next.js starter: 3–4 weeks
- Custom modules, CRM/ERP integrations: 8–14 weeks
- Headless enterprise multi-region: 16–24 weeks







