AI

OSS Eコマース比較:Medusa.js vs WooCommerce vs Saleor でShopifyを脱却する

オープンソースラボ編集部2026年6月14日

OSSEコマース比較:Medusa.js vs WooCommerce vs Saleor でShopifyを脱却する

Shopify(月$79〜)・BigCommerce(月$29〜)・Salesforce Commerce Cloud(年間数百万円〜)に対して、Medusa.js(Next.js時代のOSSコマースエンジン)・WooCommerce(WordPress統合・最大シェア)・Saleor(GraphQL APIファーストOSS)はECをセルフホストできます。

OSS Eコマースを選ぶ理由

  • コスト: Shopify Plus(月$2,300〜)→ Medusa.jsセルフホストで0円
  • 手数料なし: Shopifyは売上の0.2〜2%の取引手数料。OSS版はなし
  • カスタマイズ: 独自決済フロー・会員機能・B2Bワークフローをコードで実装
  • データ主権: 顧客の購買履歴・個人情報を自社DBで管理

主要ツールの概要

Medusa.js

2021年公開、TypeScript/Node.js製のOSSです。GitHubスター27k+。Next.js App RouterとAPIファーストで設計されたモダンなHeadless Commerceです。商品管理・注文管理・在庫・支払い・配送・割引・顧客管理をモジュールとして提供し、フロントエンドは自由に選択できます。

# Medusa.js プロジェクトを作成
npx create-medusa-app@latest

# または手動セットアップ
mkdir my-store && cd my-store
npx @medusajs/medusa-cli new . --skip-db

# 環境変数を設定(.env)
cat > .env << 'EOF'
DATABASE_URL=postgresql://postgres:password@localhost:5432/medusa-db
REDIS_URL=redis://localhost:6379
JWT_SECRET=your-super-secret-jwt-key
COOKIE_SECRET=your-cookie-secret

# Stripe決済
STRIPE_API_KEY=sk_live_xxxx
STRIPE_WEBHOOK_SECRET=whsec_xxxx

# メール(SendGrid)
SENDGRID_API_KEY=SG.xxxx
SENDGRID_FROM=orders@yourstore.com
EOF

# DB マイグレーション
npx medusa db:migrate

# 開発サーバー起動
npx medusa develop
// Medusa.js カスタムAPI Route
// src/api/store/custom/route.ts
import { MedusaRequest, MedusaResponse } from '@medusajs/medusa'
import { ProductService } from '@medusajs/medusa'

// B2B向けのバルク価格取得エンドポイント
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
  const productService: ProductService = req.scope.resolve('productService')

  const { customer_group_id } = req.query

  const products = await productService.list(
    { is_giftcard: false },
    {
      relations: ['variants', 'variants.prices'],
    }
  )

  // 顧客グループに応じた価格を返す
  const productsWithPrice = products.map(product => ({
    id: product.id,
    title: product.title,
    variants: product.variants.map(variant => ({
      id: variant.id,
      sku: variant.sku,
      price: variant.prices?.find(
        p => p.price_list?.customer_groups?.some(cg => cg.id === customer_group_id)
      )?.amount ?? variant.prices?.[0]?.amount,
    })),
  }))

  return res.json({ products: productsWithPrice })
}
// Next.js App Router で Medusa ストアフロントを構築
// app/products/[handle]/page.tsx

import Medusa from '@medusajs/medusa-js'

const medusa = new Medusa({
  baseUrl: process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL!,
  maxRetries: 3,
})

interface ProductPageProps {
  params: { handle: string }
}

export default async function ProductPage({ params }: ProductPageProps) {
  // サーバーサイドで商品データを取得(ISR対応)
  const { products } = await medusa.products.list({
    handle: params.handle,
    expand: 'variants,variants.prices,images,collection,tags',
  })
  const product = products[0]

  if (!product) return <div>商品が見つかりません</div>

  return (
    <div className="max-w-4xl mx-auto p-8">
      <h1 className="text-3xl font-bold">{product.title}</h1>
      <p className="text-gray-600 mt-2">{product.description}</p>
      <div className="mt-6 grid grid-cols-2 gap-4">
        {product.images?.map(img => (
          <img key={img.id} src={img.url} alt={product.title} className="rounded-lg" />
        ))}
      </div>
      <div className="mt-8">
        {product.variants.map(variant => (
          <div key={variant.id} className="flex justify-between items-center py-2 border-b">
            <span>{variant.title}</span>
            <span className="font-bold">
              ¥{((variant.prices?.[0]?.amount ?? 0) / 100).toLocaleString()}
            </span>
          </div>
        ))}
      </div>
    </div>
  )
}

export async function generateStaticParams() {
  const { products } = await medusa.products.list({ limit: 100 })
  return products.map(p => ({ handle: p.handle }))
}

export const revalidate = 60  // 60秒ごとに再生成
# Medusa Admin API でバックオフィス処理を自動化(Python)
import requests
import os

MEDUSA_URL = 'https://admin.yourstore.com'

def get_admin_token() -> str:
    resp = requests.post(f'{MEDUSA_URL}/admin/auth/token', json={
        'email': os.environ['MEDUSA_ADMIN_EMAIL'],
        'password': os.environ['MEDUSA_ADMIN_PASSWORD'],
    })
    resp.raise_for_status()
    return resp.json()['access_token']

token = get_admin_token()
headers = {'Authorization': f'Bearer {token}'}

# 注文一覧を取得(未処理の注文のみ)
def get_pending_orders():
    resp = requests.get(
        f'{MEDUSA_URL}/admin/orders',
        headers=headers,
        params={'fulfillment_status': 'not_fulfilled', 'limit': 50},
    )
    return resp.json()['orders']

# 在庫を一括更新(CSVからインポート)
def update_inventory(variant_id: str, quantity: int, location_id: str):
    resp = requests.post(
        f'{MEDUSA_URL}/admin/inventory-items/{variant_id}/location-levels',
        headers=headers,
        json={'location_id': location_id, 'stocked_quantity': quantity},
    )
    resp.raise_for_status()
    return resp.json()

# 使用例: 倉庫システムから在庫データを同期
import csv
with open('inventory.csv') as f:
    for row in csv.DictReader(f):
        update_inventory(row['variant_id'], int(row['quantity']), 'loc_main')
print('在庫同期完了')

Saleor

2012年公開、Python/Django製のOSSです。GitHubスター21k+。GraphQL APIのみで設計されたHeadless Commerceで、PWA・React Native・Next.jsなど任意のフロントエンドと組み合わせられます。多通貨・多言語・複数チャンネル(実店舗/ECサイト/モバイルアプリ)を単一バックエンドで管理できます。

# docker-compose.yml - Saleor Commerce
version: '3.8'
services:
  api:
    image: ghcr.io/saleor/saleor:3.20.0
    restart: unless-stopped
    ports:
      - "8000:8000"
    environment:
      DATABASE_URL: postgres://saleor:saleor@db/saleor
      DEFAULT_FROM_EMAIL: noreply@yourstore.com
      SECRET_KEY: ${DJANGO_SECRET_KEY}
      ALLOWED_HOSTS: "api.yourstore.com,localhost"
      ENABLE_DEBUG_TOOLBAR: "false"
      DEFAULT_CHANNEL_SLUG: "jp"
    depends_on:
      - db
      - redis

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: saleor
      POSTGRES_USER: saleor
      POSTGRES_PASSWORD: saleor
    volumes:
      - db_data:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine

volumes:
  db_data:

機能比較表

比較項目Medusa.jsWooCommerceSaleor
技術スタックTypeScript/Node.jsPHP/WordPressPython/Django
GraphQL API❌(REST)✅(フルGraphQL)
Headless
B2B機能
日本語対応
GitHub Stars27k+N/A(WP)21k+

ECサイトはLow-Codeカテゴリ/categories/low-codeのN8N・Zapierと連携して注文→在庫更新→配送指示→メール通知の自動化ワークフローを構築します。マーケティングカテゴリ/categories/marketingのListmonk・PostHogと組み合わせてカート離脱メール・購買分析ダッシュボードを構築する構成も一般的です。

FAQ

Q. ShopifyからMedusa.jsへの移行ステップは?

A. ①データエクスポート: Shopify管理→Settings→Data Export→商品・注文・顧客をCSVで出力②Medusa環境構築: create-medusa-appでバックエンド+Next.jsストアフロントを作成③データインポート: medusa seedコマンドまたはAdmin APIのPOST /admin/products/admin/customersでCSVデータを移行④決済・配送設定: Stripeプラグイン(@medusajs/payment-stripe)・配送プロバイダー設定⑤ドメイン切り替え: DNSをMedusaサーバーに向けてShopifyのDNSを解除。注意: ShopifyのURLリダイレクト(/products/xxx→Medusaの/products/[handle])を適切に設定してSEOを維持することが重要です。

Q. WooCommerceとMedusa.jsのどちらが日本の中小ECに向いていますか?

A. 既存WordPressサイトがある・非エンジニアが管理するならWooCommerceNext.js・TypeScriptでカスタマイズしたいエンジニアチームにはMedusa.jsが向いています。WooCommerce: ①WordPress管理画面で商品・注文管理(ノーコード)②日本決済(PAY.JP・KOMOJU・SBペイメント)の公式プラグインが充実③送料計算・消費税計算が日本向けに整備されたプラグインあり。Medusa.js: ①TypeScript型安全・Next.js App RouterでSEO最適化が容易②Stripeが主要決済(PAY.JP統合は自作が必要)③消費税(10%・軽減税率8%)の処理は自前実装が必要。2024〜2026年のトレンドはMedusa.jsが急速に日本コミュニティを獲得しています。

Q. Medusa.jsでサブスクリプション機能を実装するには?

A. ①Medusa.js + Stripe Subscriptionsの組み合わせが標準的なアプローチです。実装手順: ①Stripe Dashboardでサブスクリプション商品(Product)とPrice(月額・年額)を作成②Medusa.jsのカスタムAPIエンドポイント(src/api/store/subscribe)でStripe Subscription作成③Stripe WebhookでMedusaに支払い状況を通知(customer.subscription.updatedイベント)④Medusaのカスタマーテーブルにsubscription_statusフィールドを追加してアクセス制御。またはmedusa-plugin-subscription(コミュニティプラグイン)を使えばベース実装が30分で完了します。

Q. SaleorのGraphQL APIはどう使うのですか?

A. SaleorはすべてのEC操作をGraphQL(Strawberry Python)で提供します。エンドポイント: https://api.yourstore.com/graphql/。基本クエリ例: 商品一覧はquery { products(channel: "jp") { edges { node { id name slug pricing { priceRange { start { gross { amount currency } } } } } } } }。ミューテーション例: カートに商品を追加はmutation { checkoutLinesAdd(checkoutId: "...", lines: [{variantId: "...", quantity: 1}]) { checkout { id totalPrice { gross { amount } } } } }。TypeScript/React向けのSDK(@saleor/sdk)を使うとGraphQLクエリのtype-safeな実装が容易になります。

まとめ

ユースケース推奨ツール
モダンHeadless・TypeScript・B2BMedusa.js
WordPress統合・非エンジニア管理WooCommerce
GraphQLファースト・多言語多通貨Saleor

関連外部リソース

他の記事も読む

Let's Build Together

OSS導入、自社だけで悩まない。

ツール選定から構築・運用・AI活用まで、オープンソースラボ運営元のClasslessが伴走します。初回のご相談は無料です。