Mercur is a marketplace platform built on Medusa. Every rule here is either a Medusa requirement or a Mercur convention that keeps the marketplace layer consistent. When Medusa’s docs and this guide agree, follow both; when in doubt, mirror an existing module, workflow, or route in
packages/core.The layered architecture
Every feature in Mercur flows through the same four layers, top to bottom. Data and requests move down; results move back up. A layer may only talk to the layer directly beneath it.Module
Owns one domain’s data. Thin CRUD only, with no orchestration and no cross-module calls.
Workflow
Orchestrates a business operation across modules, step by step, with automatic rollback (compensation) on failure.
API Route
A thin HTTP adapter: validate input, run a workflow (or query for reads), shape the response.
Frontend
Admin/Vendor panels and storefront. Talks to the API only through the typed SDK, never raw
fetch.- Testability: business logic lives in workflows, which can be run in isolation without an HTTP request.
- Reusability: a workflow can be called from a route, a subscriber, or a scheduled job.
- Upgrade safety: modules stay thin, so Medusa framework upgrades rarely touch your logic.
- Rollback: because mutations are workflow steps, a failure halfway through automatically undoes the earlier steps.
The non-negotiables
These are hard rules. Breaking one produces code that looks like it works but silently violates the architecture, with no rollback, broken upgrades, or data written outside a workflow. Two more that follow from the above:- Modules are thin. A module service is CRUD plus small, self-contained helpers. If a method touches more than one module’s data, it belongs in a workflow, not the service.
- One mutation per step. Each workflow step performs a single mutation and defines how to compensate it. This is what makes rollback reliable.
Logic-placement cheat sheet
When you’re about to write a piece of logic, find the concern in this table before you decide where the code goes. The “Never put it in” column is the part people get wrong.Guides
Follow these guides to build each layer the Mercur way.Server
Create a Module
Thin CRUD, naming, and what must never live in a service.
Link Modules
defineLink, link direction, and filtering by links.Create a Workflow
Composition constraints, steps, compensation, and the query engine.
Create an API Route
Thin adapters, Zod validation, middlewares as filters,
queryConfig.Subscribers & Jobs
Event-driven side effects and scheduled work done safely.
Add a Custom Field
Attach data to an entity end-to-end, from core to the panels.
Panels
Extend the Panels
The extension model shared by the Admin and Vendor panels.
Add a Widget
Inject a component into a built-in page zone.
Blocks
Add a Block
Install a feature block into your project.
Build a Block
Package your own feature as a distributable block.