Platform Comparison

Unchained vs MedusaJS

A technical deep‑dive comparing two open‑source e‑commerce engines. GraphQL‑first vs REST‑first, MongoDB vs PostgreSQL, EUPL vs MIT — and the built‑in features that set them apart.

Unchained
GraphQL
Plugins
MongoDB
vs
MedusaJS
REST
Modules
PostgreSQL
Architecture

Architecture at a Glance

Two open‑source engines, two fundamentally different approaches to building e‑commerce backends.

Unchained
GraphQL API
Plugin System
PaymentsDeliveryMessagingWarehousing
MongoDB
+ PostgreSQL via FerretDB
28 independent NPM packages
MedusaJS
REST API
+ GraphQL via module
Module System
ServicesRepositoriesSubscribers
PostgreSQL
Monorepo module architecture
Comparison

Feature‑by‑Feature Comparison

Side‑by‑side breakdown of capabilities across core, built‑in features, enterprise, and infrastructure.

FeatureUnchainedMedusaJS
Core
LicenseEUPL (Copyleft)MIT
Primary APIGraphQL‑firstREST‑first
DatabaseMongoDBPostgreSQL
LanguageNode.js + TypeScriptNode.js + TypeScript
Built‑in Features
Subscriptions / EnrollmentsYesPlugin required
Quotations / RFQYesNo
Event TicketingYesNo
Product CatalogYesYes
Order ManagementYesYes
Payment IntegrationsYesYes
Enterprise
B2B FeaturesAdvancedBasic
MCP / AI IntegrationYesNo
OCSF Audit TrailYesNo
WebAuthn / PasskeysYesNo
Infrastructure
Docker‑nativeYesYes
Horizontal ScalingStatelessStateless
NPM Packages28 packagesMonorepo modules
API Design

GraphQL vs REST

Unchained exposes a GraphQL API by default, letting you fetch exactly the data you need in a single request. MedusaJS uses REST endpoints, often requiring multiple round‑trips for the same data.

Unchained — Single GraphQL Query
storefront.ts
// Single GraphQL query — products with variants, pricing & stock
const { data } = await client.query({
  query: gql`
    query Products($limit: Int) {
      products(limit: $limit) {
        _id
        texts { title description }
        simulatedPrice(currency: "CHF") {
          price { amount currency }
        }
        catalogChildren {
          _id
          texts { title }
          simulatedStocks { quantity }
        }
      }
    }
  `,
  variables: { limit: 10 }
});
MedusaJS — Multiple REST Calls
storefront.ts
// Multiple REST calls required for the same data
const products = await fetch('/store/products?limit=10')
  .then(r => r.json());

// For each product, fetch variants separately
const variants = await Promise.all(
  products.map(p =>
    fetch(`/store/products/${p.id}/variants`)
      .then(r => r.json())
  )
);

// Prices require another endpoint
const prices = await fetch('/store/pricing/calculate', {
  method: 'POST',
  body: JSON.stringify({
    product_ids: products.map(p => p.id),
    currency_code: 'chf'
  })
}).then(r => r.json());

// Stock levels from inventory module
const stock = await fetch('/admin/inventory-items')
  .then(r => r.json());

Type Safety

GraphQL schemas provide compile‑time type checking and auto‑generated TypeScript types for every query.

Fewer Round‑Trips

Fetch products, variants, prices, and stock in one request instead of chaining multiple REST calls.

Introspection

The schema is self‑documenting. Tools like GraphQL Playground let you explore the entire API interactively.

Database

Database Architecture

Different storage engines reflect different trade‑offs: schema flexibility vs relational integrity.

MongoDB (Unchained)

  • Flexible document schemas — embed variants, prices, and metadata directly inside product documents
  • Schema‑less evolution — add fields without migrations
  • Horizontal scaling with native sharding
  • PostgreSQL compatible via FerretDB when DB is not a choice

PostgreSQL (MedusaJS)

  • ACID transactions for every write
  • Normalized relational model with strong referential integrity
  • Mature ecosystem of extensions (PostGIS, pg_trgm, etc.)
  • JOIN‑based queries across orders, products, and customers
Extensibility

Plugin & Module System

Both platforms are extensible, but they take different architectural approaches to customization.

Both Follow DDD Principles

Both engines apply domain‑driven design with the Open/Closed Principle, layered architecture, adapters & factories, and dependency inversion. The core patterns are similar — the differences lie in naming and implementation details.

Unchained: Adapter‑Based Plugins

Each concern (payments, delivery, messaging, warehousing) has a clearly defined adapter interface. Swap providers by registering a different adapter — no core changes required.

MedusaJS: Service/Repository Pattern

Uses services, repositories, and subscribers. Modules are organized in a monorepo and extend the core through dependency injection and lifecycle hooks.

boot.ts
import { startPlatform } from '@unchainedshop/platform';
import { stripePayments } from '@unchainedshop/plugins';

await startPlatform({
  modules: {
    // Adapter-based plugin system
    payments: {
      adapters: [stripePayments],
    },
    delivery: {
      adapters: [postDelivery],
    },
    messaging: {
      adapters: [sendgridMessaging],
    },
    warehousing: {
      adapters: [customWarehouse],
    },
  },
});
Enterprise

Built‑in Enterprise Features

Features that Unchained ships natively — no plugins, no third‑party services, no extra cost.

Subscriptions & Enrollments

Recurring billing, membership management, and enrollment workflows built into the core engine.

Quotations & RFQ

B2B negotiation workflows with request‑for‑quote, approval chains, and custom pricing per customer.

Event Ticketing

Apple Wallet and Google Wallet passes, QR code generation, and check‑in management out of the box.

MCP Server

Native AI assistant integration via the Model Context Protocol. Let AI agents browse products, manage carts, and place orders.

OCSF Audit Trail

Compliance‑grade logging following the Open Cybersecurity Schema Framework for full operational transparency.

WebAuthn / Passkeys

Passwordless authentication with biometric and hardware key support. FIDO2‑compliant and phishing‑resistant.

Ready to Build with Unchained?

Start building your next e‑commerce project on a GraphQL‑first, enterprise‑ready platform licensed under the EUPL.

EUPL LicenseGraphQL APIMongoDBSwiss‑Made