agentsclimarketplace

Medusa

Skill ComeOnOliver/skillshub/skills/TerminalSkills/skills/medusa

🧠 The right skill, one API call. AI agent skills registry with token-efficient skill resolution. 5,000+ skills from 500+ top repos.From the repository description

Install
npx -y skills add ComeOnOliver/skillshub --skill medusa

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

SKILL.md

8.4 KB, ~2.1k tokens by cl100k_base, as published. Nobody here has run it

Medusa

Overview

Medusa is an open-source headless e-commerce engine (Node.js + PostgreSQL). It provides a complete backend for products, carts, orders, payments, shipping, and customers β€” exposed via REST and GraphQL APIs. Think of it as the open-source alternative to Shopify's backend, with full control over customization. This skill covers setup, product management, custom API routes, payment integration (Stripe), and connecting a Next.js storefront.

Instructions

Step 1: Project Setup

# Create new Medusa project
npx create-medusa-app@latest my-store
# This scaffolds: backend (Medusa server) + admin dashboard + storefront (Next.js)

# Or install backend only
npx create-medusa-app@latest my-store --skip-db --no-browser

cd my-store

# Configure database
# .env
DATABASE_URL=postgresql://user:pass@localhost:5432/medusa_store
REDIS_URL=redis://localhost:6379

# Run migrations and seed
npx medusa db:migrate
npx medusa seed --seed-file=data/seed.json

# Start development server
npx medusa develop
# API: http://localhost:9000
# Admin: http://localhost:7001

Step 2: Product Management

// src/api/routes/admin/custom-products.ts β€” Custom product creation endpoint
// Medusa's admin API handles CRUD, but custom routes extend it

import type { MedusaRequest, MedusaResponse } from "@medusajs/framework"
import { createProductsWorkflow } from "@medusajs/medusa/core-flows"

export async function POST(req: MedusaRequest, res: MedusaResponse) {
  const { result } = await createProductsWorkflow(req.scope).run({
    input: {
      products: [{
        title: req.body.title,
        description: req.body.description,
        status: "published",
        options: [
          { title: "Size", values: ["S", "M", "L", "XL"] },
          { title: "Color", values: ["Black", "White", "Navy"] },
        ],
        variants: [
          {
            title: "Small Black",
            sku: "TSHIRT-S-BLK",
            prices: [{ amount: 2999, currency_code: "usd" }],
            options: { Size: "S", Color: "Black" },
            manage_inventory: true,
            inventory_quantity: 100,
          },
        ],
        images: [{ url: "https://example.com/product.jpg" }],
        categories: [{ id: "cat_tshirts" }],
      }],
    },
  })

  res.json({ product: result })
}
# REST API examples β€” Product operations
# List products (public storefront API)
curl http://localhost:9000/store/products

# Get single product
curl http://localhost:9000/store/products/prod_01ABC

# Admin: create product
curl -X POST http://localhost:9000/admin/products \
  -H 'Authorization: Bearer admin_token' \
  -H 'Content-Type: application/json' \
  -d '{"title": "Classic T-Shirt", "status": "published"}'

Step 3: Cart and Checkout Flow

// lib/storefront-client.ts β€” Client-side cart operations for Next.js storefront
// This is the typical checkout flow: create cart β†’ add items β†’ add shipping β†’ complete

const API_URL = process.env.NEXT_PUBLIC_MEDUSA_URL || "http://localhost:9000"

export async function createCart() {
  const res = await fetch(`${API_URL}/store/carts`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ region_id: "reg_us" }),
  })
  return res.json()    // { cart: { id: "cart_01ABC", items: [], total: 0 } }
}

export async function addToCart(cartId: string, variantId: string, quantity: number) {
  const res = await fetch(`${API_URL}/store/carts/${cartId}/line-items`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ variant_id: variantId, quantity }),
  })
  return res.json()
}

export async function completeCheckout(cartId: string) {
  // Add customer email
  await fetch(`${API_URL}/store/carts/${cartId}`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ email: "[email protected]" }),
  })

  // Select shipping option
  await fetch(`${API_URL}/store/carts/${cartId}/shipping-methods`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ option_id: "so_standard" }),
  })

  // Initialize payment (Stripe)
  await fetch(`${API_URL}/store/carts/${cartId}/payment-sessions`, {
    method: "POST",
  })

  // Complete order
  const res = await fetch(`${API_URL}/store/carts/${cartId}/complete`, {
    method: "POST",
  })
  return res.json()    // { type: "order", data: { id: "order_01ABC", ... } }
}

Step 4: Payment Integration (Stripe)

# Install Stripe payment plugin
npm install @medusajs/payment-stripe
// medusa-config.ts β€” Configure Stripe payment provider
import { defineConfig } from "@medusajs/framework"

export default defineConfig({
  projectConfig: {
    databaseUrl: process.env.DATABASE_URL,
    redisUrl: process.env.REDIS_URL,
  },
  modules: [
    {
      resolve: "@medusajs/payment",
      options: {
        providers: [{
          resolve: "@medusajs/payment-stripe",
          options: {
            apiKey: process.env.STRIPE_SECRET_KEY,
            webhookSecret: process.env.STRIPE_WEBHOOK_SECRET,
          },
        }],
      },
    },
  ],
})

Step 5: Custom API Routes

// src/api/routes/store/custom-search.ts β€” Custom storefront endpoint
// Extend Medusa's API with business-specific logic

import type { MedusaRequest, MedusaResponse } from "@medusajs/framework"

export async function GET(req: MedusaRequest, res: MedusaResponse) {
  const query = req.query.q as string
  const productService = req.scope.resolve("product")

  const [products, count] = await productService.listAndCount(
    { q: query, status: "published" },
    { take: 20, relations: ["variants", "images"] }
  )

  res.json({ products, count })
}

Step 6: Subscribers and Events

// src/subscribers/order-placed.ts β€” React to events (send email, update inventory)
import type { SubscriberArgs, SubscriberConfig } from "@medusajs/framework"

export default async function orderPlacedHandler({ event, container }: SubscriberArgs) {
  /**
   * Triggered when an order is placed. Use for:
   * - Sending confirmation emails
   * - Notifying warehouse
   * - Updating external systems (ERP, CRM)
   */
  const order = event.data
  const notificationService = container.resolve("notification")

  await notificationService.send("order-confirmation", {
    to: order.email,
    data: {
      order_id: order.id,
      items: order.items,
      total: order.total,
    },
  })
}

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

Examples

Example 1: Launch a headless e-commerce store with Next.js frontend

User prompt: "I want to build an online clothing store. Open-source backend, custom Next.js frontend, Stripe payments. I need product variants (size, color), inventory tracking, and a proper checkout flow."

The agent will:

  1. Scaffold a Medusa project with create-medusa-app.
  2. Configure PostgreSQL, Redis, and Stripe payment plugin.
  3. Create product data model with size/color variants and inventory.
  4. Build Next.js storefront pages: product listing, product detail, cart, checkout.
  5. Set up order confirmation emails via subscribers.

Example 2: Migrate from Shopify to a self-hosted solution

User prompt: "We're paying $300/month for Shopify Plus. Migrate our 500 products and order history to a self-hosted Medusa backend."

The agent will:

  1. Export products and orders from Shopify via their Admin API.
  2. Transform the data to Medusa's format (handle variants, images, metadata).
  3. Write a migration script that imports products and historical orders.
  4. Set up equivalent payment and shipping configurations.

Guidelines

  • Medusa requires PostgreSQL and Redis β€” both must be running before starting the server. Use Docker Compose to manage all three services together.
  • The admin dashboard (port 7001) is separate from the storefront API (port 9000). Keep the admin behind authentication and network restrictions in production.
  • Use Medusa's workflow system for complex operations (multi-step processes like checkout) β€” it provides automatic rollback on failure.
  • For storefronts, use Medusa's official Next.js starter as a base rather than building from scratch β€” it handles cart state, checkout flow, and API integration.
  • Medusa's plugin ecosystem covers payments (Stripe, PayPal), shipping (FedEx, DHL), notifications (SendGrid, Twilio), and search (Meilisearch, Algolia). Check the plugin registry before building custom integrations.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.