The Medusa architecture is a commerce engine, not a store builder. You get products, carts, orders, payments, inventory, promotions and an admin as composable modules over your own Postgres, MIT-licensed, with no cut of your sales. What you do not get is a storefront, a support desk, or anyone else's opinion about how your checkout should work. That last part is the entire point — and the entire cost.
Short answer
Medusa gives you the commerce primitives as TypeScript modules you run yourself: product, pricing, inventory, cart, order, payment, fulfilment, promotion, customer and an admin dashboard. Your code extends it in four places — workflow hooks, event subscribers, custom modules and API routes — without forking core. You build the storefront, and you own hosting, PCI scope, fraud tooling, tax logic and uptime. It replaces the platform, not the operations team the platform stood in for.
I am Manoj, an open-source implementation consultant at Mith Tech in Bengaluru. I build Medusa storefronts for brands moving off hosted platforms, and the code patterns below are verified against a production Medusa 2.14.2 backend we run — not read off the documentation alone. Honest take: Medusa is the best answer to a specific question, and the wrong answer to a common one. This post is mostly about telling those two apart.
What does Medusa actually ship with?
The commerce domain, modelled as separate modules that talk over a shared container rather than one monolithic application. That modularity is the defining trait of the Medusa architecture and the reason it extends cleanly where a monolith would need forking. In practice you get product and variant modelling, a pricing module that handles price lists and currency, multi-location inventory with reservations, cart and order lifecycles, payment and fulfilment provider abstractions, promotions, customer accounts and groups, regions and tax rates, and a React admin dashboard that ships with the backend.
That is genuinely most of a commerce platform. What is conspicuously absent is anything above the API line: there is no theme, no page builder, no storefront. Medusa exposes a Store API and an Admin API, and your frontend — Next.js, Remix, Astro, a native app, whatever — consumes them.
For a Shopify merchant this is the first real conceptual shift. On Shopify, "the store" is a theme you edit. On Medusa, "the store" is an application your team deploys, and the commerce backend is a service it talks to.
| Storefront | Liquid theme, editable in-browser | Your application, in your framework |
| Commerce logic | Closed, extended via apps | Open modules over your Postgres |
| Admin | Shopify admin | Ships with Medusa, extensible in React |
| Database | Not accessible | Yours — SQL, joins, exports |
| Hosting | Shopify's | Yours |
| Cost per sale | Plan fee + platform cut | Gateway MDR only |
Skimmable summary: Medusa ships the commerce domain as modules plus an extensible admin, over a Postgres you own. It ships no storefront — your frontend consumes its Store API.
Who owns what once you switch?
This is the question worth spending real time on, because the honest answer is not "everything gets better". Some concerns become possible for the first time. Others were being handled invisibly and now land on your team. The full medusa architecture workflow is part of the standard production setup.
Sixteen commerce and operational concerns, each marked as handled, yours to own, or impossible on Shopify and Medusa respectively — filtered by commerce, control, data and operations.
Read the two counters at the bottom together, because they are the whole decision. Medusa unlocks a set of things Shopify will not do at any tier — custom checkout steps, conditional rules, B2B approval flows, your own URL structure, your own invoice document. It simultaneously hands you a set of operational concerns Shopify was absorbing: hosting, PCI scope, fraud scoring, tax calculation and the support desk you no longer have.
The trade is only rational if the unlocked list contains something your business genuinely needs. If it does not — and for most stores under a few crore a year it does not — you are taking on work in exchange for capability you will never use. That is the argument I make in why businesses are leaving Shopify, and it applies with equal force here.
Skimmable summary: Medusa unlocks capability Shopify blocks at any tier, and hands back operational concerns Shopify absorbed. The trade only pays if you need something on the unlocked list.
Where does your code actually go?
In four places. Knowing them is most of what separates a Medusa build that stays maintainable from one that quietly becomes a fork, and it is the part of the Medusa architecture that repays study before you write a line.
Copyable skeletons for the four Medusa v2 extension points — workflow hooks, event subscribers, custom modules and API routes — with guidance on which to reach for.
Workflow hooks gate the core flows
Medusa's core flows — completing a cart, creating an order, capturing a payment — expose workflow hooks you attach to instead of forking. A validate hook that throws aborts the flow, which makes it the correct home for any rule that must prevent something from happening.
There is one property here that catches every team once, and it is worth stating plainly: a workflow hook accepts exactly one handler. You cannot register three independent validators on completeCartWorkflow.hooks.validate from three different files and expect all three to run. On the production backend I verified this against, every cart-completion gate is composed in a single file, called in a deliberate order:
// One file owns the hook; every gate is called from it, in priority order.
completeCartWorkflow.hooks.validate(async (data, { container }) => {
await assertNoSecurityTripwire(data, container) // fails closed
await assertQuotedPriceIntact(data, container) // fails closed
await assertEligibleForCheckout(data, container) // fails open
})
Ordering is a design decision, not an accident. The money-critical check runs before the softer one, and the gates deliberately fail in opposite directions: the price check fails closed, because letting a tampered price through on a transient error would charge the customer the wrong amount, while the eligibility check fails open rather than blocking a legitimate sale on a downstream hiccup.
That is a decision Shopify makes for you, invisibly and reasonably. On Medusa it is yours, and you have to actually make it.
That is a level of control Shopify does not offer at any tier, and it is also a level of responsibility Shopify never asked you to carry. Both halves of that sentence are true.
Subscribers react after the fact
Anything that must not block or fail a checkout belongs in a subscriber: ERP sync, notification sends, ledger writes, analytics. A subscriber declares the event it listens for and runs outside the request path.
The trap is assuming a throwing subscriber rolls something back. It does not — the order is already placed. Retries, idempotency and dead-lettering are yours to design. This is exactly the kind of work Shopify's app ecosystem was quietly doing for you.
Custom modules are how capability gets added
When Medusa genuinely does not have something, you add a module: its own data models, its own service, its own migrations, registered by name and resolved from the container. MedusaService generates the CRUD surface for each model, so a module is mostly the logic you actually care about.
This is the extension point that makes Medusa open-ended rather than merely configurable, and it is what people mean when they say they moved for control. A dealer credit line, a quote-approval state machine, a custom commission model — none of these are apps you install. They are modules you own.
API routes expose it to the world
File-based routing under src/api/ publishes store and admin endpoints. This is how a custom module reaches your storefront, and how your admin extensions read and write.
The discipline that keeps a Medusa build maintainable
Resist putting back-office logic into Medusa. It is very good at storefront, cart, checkout, orders, payments and inventory. It is not an accounting system, a warehouse management system or a manufacturing planner, and every hour spent making it pretend to be one is an hour not spent on the thing you migrated for. Point it at whatever finance and inventory systems you already run.
Skimmable summary: Extend via workflow hooks (gate core flows, one handler each), subscribers (react after the fact, own your retries), custom modules (add real capability) and API routes (expose it). Forking core is almost never right.
Is Medusa production-ready?
Yes, with caveats worth stating precisely rather than waving away.
The core is mature. It is MIT-licensed, actively developed, and running real commerce for real money — the backend I verified these patterns against is a production system on Medusa 2.14.2 with dozens of custom modules, hundreds of API routes and a heavily extended admin.
Nothing in the Medusa architecture creaks under that load. The caveats are ecosystem and staffing, not stability:
- The plugin ecosystem is thin. Shopify's app store has an answer for everything. Medusa's does not. Capability you would have installed you will now build, which is slower up front and cheaper forever — but only if you actually have someone to build it.
- You need a developer permanently. Not for the migration — for the lifetime of the store. Every merchant who regretted moving named maintenance, not the build, as the real cost.
- The operational surround is yours. Fraud tooling, transactional email deliverability, monitoring, backups with a tested restore, load testing before every sale event. None of it is exotic; all of it is real.
- It is not a compliance product. Medusa does not ship Indian GST invoicing or e-invoicing, any more than Shopify does. What changes is permission: you own the order and document layer, so a Rule 46 invoice and an IRN call are things you can build. On Shopify they are things you cannot build at any price.
I talked to a few big shop owners who moved to the platform and they're loving the control they get.
That quote is worth its context. It came from a Shopify Expert, in a thread where most commenters were arguing against leaving Shopify — which is roughly the correct distribution of opinion, and why the recommendation carries weight.
Skimmable summary: The core is mature and runs real commerce at scale. The genuine caveats are a thin plugin ecosystem, a permanent developer requirement, the operational surround, and no built-in compliance tooling.
Who should actually run Medusa? The full medusa architecture workflow is part of the standard production setup.
A short list, and it is short on purpose.
Good fit
You have a named capability Shopify blocks — B2B approvals, credit lines, custom pricing logic, a compliant invoice. You have or will hire a developer permanently. Your fees are large enough that owning is cheaper. You want the database.
Bad fit
Your complaint is cost, support, or app fatigue. You have no engineering capacity. You are under a few crore a year. You need to ship this quarter. You want someone to call at 2am on Black Friday.
If you land in the second box, that is not a failure — it is the correct answer for most stores, and Shopify is genuinely good at what it does. The fee stack breakdown will tell you when that stops being true for you, and the migration guide covers what moving actually involves once it does.
Skimmable summary: Run Medusa when a named capability is blocked, you have permanent engineering, and the fee arithmetic is decisive. Otherwise stay on hosted SaaS.
Frequently asked questions The full medusa architecture workflow is part of the standard production setup.
What is Medusa.js in simple terms?
Medusa is an open-source commerce backend written in TypeScript. It gives you the building blocks of an online store — products, carts, checkout, orders, payments, inventory, promotions — as modules you run on your own server and database, plus an admin dashboard. It is MIT-licensed and takes no percentage of your sales. You build the customer-facing storefront yourself against its APIs.
Does Medusa come with a storefront?
No. Medusa ships a backend and an admin dashboard, not a themed storefront. You build the frontend in whatever framework you prefer and it consumes Medusa's Store API. Starter templates exist to speed this up, but there is no in-browser theme editor and no equivalent of installing a Shopify theme — the storefront is an application your team owns and deploys.
How do you customise Medusa without forking it?
Through four extension points: workflow hooks that gate core flows such as cart completion, event subscribers that react after something happens, custom modules that add entirely new capability with their own models and services, and file-based API routes that expose it. Between them these cover almost every requirement, so forking core is rarely necessary and generally a mistake.
Can multiple parts of my code hook the same Medusa workflow?
No — a workflow hook accepts exactly one handler. If you need several checks on cart completion, compose them inside a single handler and call them in a deliberate order. This surprises most teams once. Decide explicitly which checks fail closed (abort on any error) and which fail open, because that ordering is a genuine design decision with money attached.
Is Medusa cheaper than Shopify?
Only above a threshold. Medusa has no licence fee and takes no cut of your sales, but you still pay your payment gateway's MDR, plus hosting and at least one developer permanently. Total your annual Shopify plan, platform transaction and app fees and compare them against a developer plus infrastructure. Below roughly a few crore in revenue, hosted SaaS usually wins on pure economics.
Does Medusa handle GST and e-invoicing for Indian stores?
Not out of the box — and neither does Shopify. The meaningful difference is permission rather than features: on Medusa you own the order and document layer, so a Rule 46 compliant invoice and IRN generation are things you can implement, or hand to a finance system behind the storefront. On Shopify the invoice is a rented document you cannot change, which is why Indian merchants there need a third-party app.
Is Medusa production-ready for a serious store?
Yes. The core is mature, MIT-licensed and actively developed, and runs real commerce at scale — including production systems with dozens of custom modules and hundreds of API routes. The honest caveats are that its plugin ecosystem is much thinner than Shopify's app store, so you build more than you install, and that you need a developer on it permanently rather than only during the build.
Closing The full medusa architecture workflow is part of the standard production setup.
The best description of Medusa I can give a Shopify merchant is this: it removes every constraint you have been working around, and hands you every problem you did not know you were being protected from. Both of those are real, and neither is a marketing line.
So do not evaluate Medusa on whether it is good — it is. Evaluate it on whether the constraint you want removed is worth the problems you would inherit. If you cannot name the constraint, the answer is no. If you can, Medusa is very probably the platform you should be looking at, and the honest next step is the fee arithmetic rather than a demo.
About the author
I am Manoj, an open-source implementation consultant at Mith Tech, an independent Medusa.js, Frappe and n8n studio in Bengaluru. I build and run production Medusa backends for brands in India and abroad, and the patterns in this post are taken from systems we operate — not from documentation alone.
Wondering whether Medusa is the right platform for what you are trying to build?
Tell us the capability you cannot get today and roughly what you turn over. We will tell you whether Medusa solves it, what owning it would involve, and when the honest answer is to stay where you are.