Skip to content
Medusa Ecommerce logo

Medusa Ecommerce

Build ecommerce applications with Medusa v2 - commerce modules, customization, workflows, and deployment

SKILL.md

Full skill instructions

Medusa Ecommerce Skill

Build modern ecommerce applications with Medusa v2's modular architecture.

Context7 Integration

Always use context7 MCP for up-to-date API documentation:

# Primary sources (use in order of preference)
mcp-cli call context7/​resolve-library-id '{"libraryName": "medusajs"}'

# Recommended library IDs:
# - /​websites/​medusajs_learn      - Tutorials, getting started
# - /​websites/​medusajs_resources  - API reference, detailed docs
# - /​llmstxt/​medusajs_llms-full_txt - Comprehensive reference

Query pattern:

mcp-cli call context7/​query-docs '{"libraryId": "/​websites/​medusajs_learn", "topic": "your topic"}'

Architecture Overview

┌─────────────────────────────────────────────────────────────────┐
│                         Medusa Application                       │
├─────────────────────────────────────────────────────────────────┤
│  API Layer        │  Admin Routes (/​admin)                       │
│                   │  Store Routes (/​store)                       │
│                   │  Custom Routes (/​custom)                     │
├─────────────────────────────────────────────────────────────────┤
│  Workflows        │  Multi-step operations with compensation     │
├─────────────────────────────────────────────────────────────────┤
│  Commerce Modules │  Product │ Cart │ Order │ Payment │ etc.    │
├─────────────────────────────────────────────────────────────────┤
│  Infrastructure   │  Cache │ Events │ File │ Notification       │
├─────────────────────────────────────────────────────────────────┤
│  Database         │  PostgreSQL with MikroORM                    │
└─────────────────────────────────────────────────────────────────┘

Project Structure

my-medusa-store/
├── src/
│   ├── modules/           # Custom modules
│   │   └── my-module/
│   │       ├── index.ts
│   │       ├── service.ts
│   │       └── models/
│   ├── workflows/         # Custom workflows
│   ├── subscribers/       # Event subscribers
│   ├── api/              # API routes
│   │   ├── admin/
│   │   ├── store/
│   │   └── middlewares.ts
│   ├── admin/            # Admin UI extensions
│   │   ├── routes/
│   │   └── widgets/
│   └── links/            # Module links
├── medusa-config.ts
└── package.json

Quick Reference

Container Resolution

// In API routes, subscribers, workflows
const productService = container.resolve("product")
const query = container.resolve("query")

// Common services
// "product", "cart", "order", "customer", "pricing"
// "payment", "fulfillment", "inventory", "region"
// "query" - for Query/​Graph operations
// "logger" - for logging

Query (Graph) Operations

import { Query } from "@medusajs/​framework"

// Retrieve with relations
const { data: products } = await query.graph({
  entity: "product",
  fields: ["id", "title", "variants.*", "variants.prices.*"],
  filters: { id: productId }
})

// Pagination
const { data, metadata } = await query.graph({
  entity: "order",
  fields: ["*", "items.*"],
  pagination: { skip: 0, take: 20 }
})

Remote Query (Cross-Module)

import { useQueryGraphStep } from "@medusajs/​medusa/​core-flows"

// In workflows - query across linked modules
const { data } = await useQueryGraphStep({
  entity: "product",
  fields: ["*", "inventory_items.*"] // Linked data
})

Creating API Routes

// src/​api/​store/​custom/​route.ts
import { MedusaRequest, MedusaResponse } from "@medusajs/​framework"

export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
  const query = req.scope.resolve("query")
  // ... handle request
  res.json({ data })
}

export const POST = async (req: MedusaRequest, res: MedusaResponse) => {
  const body = req.body
  // ... handle request
  res.json({ success: true })
}

Protected Admin Routes

// src/​api/​admin/​custom/​route.ts
import { MedusaRequest, MedusaResponse } from "@medusajs/​framework"
import { authenticate } from "@medusajs/​medusa"

export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
  // req.auth_context.actor_id contains admin user ID
  res.json({ data })
}

// Middleware applies authentication automatically for /​admin routes

Creating Workflows

import { createWorkflow, createStep, StepResponse } from "@medusajs/​framework/​workflows-sdk"

const myStep = createStep(
  "my-step",
  async (input: { data: string }, { container }) => {
    const service = container.resolve("myService")
    const result = await service.doSomething(input.data)
    return new StepResponse(result, result.id) // data, compensateInput
  },
  async (id, { container }) => {
    // Compensation (rollback) logic
    const service = container.resolve("myService")
    await service.undoSomething(id)
  }
)

export const myWorkflow = createWorkflow("my-workflow", (input) => {
  const result = myStep(input)
  return result
})

Event Subscribers

// src/​subscribers/​order-placed.ts
import { SubscriberArgs, SubscriberConfig } from "@medusajs/​framework"

export default async function orderPlacedHandler({
  event,
  container
}: SubscriberArgs<{ id: string }>) {
  const orderId = event.data.id
  const logger = container.resolve("logger")
  logger.info(`Order placed: ${orderId}`)
}

export const config: SubscriberConfig = {
  event: "order.placed"
}

Data Models

import { model } from "@medusajs/​framework/​utils"

const MyModel = model.define("my_model", {
  id: model.id().primaryKey(),
  name: model.text(),
  description: model.text().nullable(),
  metadata: model.json().nullable(),
  is_active: model.boolean().default(true),
  created_at: model.dateTime(),
})

export default MyModel

Module Links

// src/​links/​product-custom.ts
import { defineLink } from "@medusajs/​framework/​utils"
import ProductModule from "@medusajs/​medusa/​product"
import MyModule from "../​modules/​my-module"

export default defineLink(
  ProductModule.linkable.product,
  MyModule.linkable.myModel
)

Common Operations

Create Product with Variants

const product = await productService.createProducts({
  title: "T-Shirt",
  options: [{ title: "Size", values: ["S", "M", "L"] }],
  variants: [
    { title: "Small", options: { Size: "S" }, prices: [{ amount: 1000, currency_code: "usd" }] },
    { title: "Medium", options: { Size: "M" }, prices: [{ amount: 1000, currency_code: "usd" }] },
  ]
})

Cart to Order Flow

// 1. Create cart
const cart = await cartService.createCarts({ region_id, currency_code: "usd" })

// 2. Add items
await cartService.addLineItems(cart.id, [{ variant_id, quantity: 1 }])

// 3. Add shipping/​payment
await cartService.addShippingMethods(cart.id, [{ shipping_option_id }])
await paymentService.createPaymentCollections({ cart_id: cart.id })

// 4. Complete checkout (via workflow)
import { completeCartWorkflow } from "@medusajs/​medusa/​core-flows"
await completeCartWorkflow(container).run({ input: { id: cart.id } })

Payment Integration

// Initialize payment session
const paymentCollection = await paymentService.createPaymentCollections({
  cart_id: cartId,
  amount: cart.total,
  currency_code: cart.currency_code,
})

await paymentService.createPaymentSession(paymentCollection.id, {
  provider_id: "stripe", // or your provider
  data: { /​* provider-specific */ }
})

CLI Commands

# Development
npx medusa develop          # Start dev server with admin

# Database
npx medusa db:migrate       # Run migrations
npx medusa db:generate      # Generate migration from models
npx medusa db:sync-links    # Sync module links

# Build
npx medusa build            # Production build
npx medusa start            # Start production server

Reference Files

Detailed documentation organized by topic:

FileTopics
commerce-modules.mdProduct, Cart, Order, Pricing, Inventory, Customer
checkout-payments.mdPayment, Fulfillment, Tax, Region, Sales Channel
customization.mdCustom modules, services, data models, links, API routes
workflows-events.mdWorkflows, steps, compensation, subscribers, events
admin-storefront.mdAdmin UI extensions, JS SDK, storefront integration
infrastructure-production.mdRedis, S3, SendGrid, deployment, medusa-config.ts

Best Practices

  1. Use workflows for multi-step operations - Built-in compensation handles failures
  2. Query with query.graph() - Efficient data fetching with relations
  3. Extend, don't modify - Create custom modules instead of modifying core
  4. Use module links - Connect custom data to core entities
  5. Validate at API layer - Use Zod schemas for request validation
  6. Subscribe to events - React to changes asynchronously

Troubleshooting

Module not found: Ensure module is registered in medusa-config.ts

Link not working: Run npx medusa db:sync-links after adding links

Migration issues: Check model definitions match database schema

Type errors: Regenerate types with npx medusa generate:types

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View