Magento migrations are the hardest of the common ones, for a structural reason: Magento is more configurable than Medusa in exactly the places nobody uses, and its data model spreads a single product across a dozen tables.
The projects that go well start by deciding which Magento capabilities the business actually uses. Usually it is a fraction of what is configured.
Extraction
Do not hand-join EAV. Use the REST API, which assembles attributes for you:
TOKEN=$(curl -sS -X POST "https://store.example.com/rest/V1/integration/admin/token" \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"…"}' | tr -d '"')
curl -sS "https://store.example.com/rest/V1/products?searchCriteria[pageSize]=100&searchCriteria[currentPage]=1" \
-H "Authorization: Bearer $TOKEN" -o products-1.jsonMagento's REST API is slow — expect hours for a large catalog — so paginate, checkpoint, and be able to resume. Run it once into files, then iterate against the files.
Where the API genuinely omits something, targeted SQL against catalog_product_entity joined to the relevant catalog_product_entity_<type> value table is the fallback. Reach for it rarely.
Mapping
| Magento | Medusa | Notes |
|---|---|---|
| Simple product | Product with one variant | |
| Configurable product | Product with variants | Simple children become variants |
| Grouped product | Product relations or a bundle module | No direct equivalent |
| Bundle product | Custom module | Needs modelling |
| Attribute set | Product type plus options | Loosely equivalent |
| Attribute | Product option or module field | Decide per attribute |
| Category | Product category | Hierarchy preserved |
| Website / store / store view | Region + sales channel + locale | Three concepts from one |
| Customer group | Customer group | Direct |
| Catalog price rule | Price list or promotion | Rules differ |
| Cart price rule | Promotion | Rules differ |
Configurable products are the main translation. In Magento a configurable is a shell linked to simple products, each a separate entity with its own SKU, price and stock. In Medusa the variants belong to the product. The simple children stop existing independently — which is usually a relief, and does mean any URL pointing at a simple child needs redirecting to the parent.
Store views are the conceptual trap. A Magento store view mixes language, currency and catalog scope. In Medusa those are three things: region for currency and tax, locale for language, sales channel for catalog scope. Map deliberately rather than assuming one store view equals one region.
Attributes: options or module fields?
Magento catalogs accumulate hundreds of attributes. Sort them:
- Drives variants (size, colour) → product option.
- Filtered or searched on (material, certification) → a module with a link, so it is queryable.
- Displayed only (care instructions) →
metadata. - Unused — and there will be many — → drop.
Do the audit before importing. Migrating three hundred attributes because they exist is how you rebuild EAV inside a system that deliberately does not have it.
B2B logic
Magento Commerce ships B2B features that Adobe charges for and that many merchants depend on: company accounts, shared catalogs, negotiable quotes, purchase orders and requisition lists.
None of these come with Medusa. All are buildable as modules and workflows, and that build is the bulk of a B2B Magento migration — plan four to eight weeks for it alone. B2B commerce in Medusa covers the shape.
The compensating benefit: you own the logic, and it costs nothing per year.
Orders and customers
Magento orders span sales_order, sales_order_item, sales_order_address and payment and shipping tables. Import as records, two years deep unless there is a reason for more, keeping the Magento increment id in metadata so support can search by the number on the customer's invoice.
Customers migrate with their groups intact — the group drives pricing, so getting it right matters more here than in a DTC migration. Passwords do not migrate.
Redirects
Magento URLs depend heavily on configuration:
| Magento | Medusa storefront |
|---|---|
| `/<url-key>.html` | `/products/<handle>` |
| `/<category>/<url-key>.html` | `/products/<handle>` |
| `/<category>.html` | `/collections/<handle>` |
| `/catalog/product/view/id/123` | 301 to the mapped product |
| Simple child URLs | 301 to the parent product |
The .html suffix is the one people forget. Export from url_rewrite, which is Magento's own record of every URL it has ever served — including historical ones from previous renames, which still carry links.
Realistic timeline
| Phase | Weeks |
|---|---|
| Discovery, attribute and extension audit | 2 |
| Domain modelling and custom modules | 3–4 |
| Storefront build | 4 |
| Data migration and validation | 2–3 |
| B2B features, if required | 4–8 |
| Integrations (ERP, tax, 3PL) | 2–4 |
| Testing and cutover | 2 |
Twelve to twenty weeks for a serious Magento migration. Anyone quoting six has not seen the extension list. General migration planning.
The extension audit
The single most important artefact in a Magento migration, and the thing that makes an estimate real rather than aspirational.
For every installed extension, record four things: what it does, whether the business actually uses it, whether Medusa covers it, and what replacing it costs.
| Extension type | Typical outcome |
|---|---|
| Performance and caching | Gone — architectural, not needed |
| SEO extensions | Gone — built into the storefront |
| Multi-currency, multi-store | Native regions and channels |
| Payment and shipping methods | Provider modules |
| B2B suite | Custom build, 4–8 weeks |
| ERP or PIM connector | Custom integration, 2–4 weeks |
| Industry-specific logic | Custom module, varies |
| Installed and unused | Delete, and say so out loud |
The last row is usually a third of the list. Being explicit about it is how a twenty-week estimate becomes a twelve-week one, and it is a conversation the merchant needs to have anyway.
Multi-store and multi-website
A Magento installation with several websites is not one migration. Decide the target shape before scoping:
One Medusa instance, multiple regions and sales channels. Right when the websites share a catalog and differ by market. Simplest to operate.
One instance, multiple storefronts. Different brands sharing inventory and operations, each with its own Next.js storefront against the same backend. Common and works well.
Separate instances. Genuinely separate businesses with separate catalogs, teams and P&Ls. Cleanest boundaries, highest operational cost.
Teams default to the third because it mirrors their Magento setup. That is usually mirroring an accident of Magento's architecture rather than a business requirement — check whether the websites really need separate everything before committing to running three deployments.
We scope Magento migrations with an audit first, because the quote depends entirely on what the extensions turn out to be doing. Ask.
Frequently asked questions
How do I export product data from Magento 2?
Use the REST API, which assembles EAV attributes into complete product objects, paginating and checkpointing since it is slow on large catalogs. Fall back to targeted SQL against `catalog_product_entity` and its value tables only for data the API omits.
How do Magento configurable products map to Medusa?
The configurable becomes a Medusa product and its linked simple products become variants. The simple products stop existing as separate entities, so any URLs pointing at them need redirecting to the parent product.
What happens to Magento store views in Medusa?
They decompose into three separate concepts: regions for currency and tax, locales for language, and sales channels for catalog scope. There is no one-to-one mapping, so map each store view deliberately.
Can I migrate Magento B2B features to Medusa?
Yes, but they are a build rather than a migration. Company accounts, shared catalogs, quotes and purchase orders are modules and workflows you write, typically four to eight weeks of work on top of the base migration.
How long does a Magento to Medusa migration take?
Twelve to twenty weeks for a serious store, driven mostly by custom extensions and B2B requirements rather than catalog size. The extension audit in the first two weeks is what makes the rest of the estimate meaningful.
How do I handle Magento URL redirects?
Export the `url_rewrite` table, which records every URL Magento has served including historical ones, and map each to its Medusa equivalent. Do not forget the `.html` suffix or the URLs of simple child products, which should redirect to the parent.
The US Vape Crackdown and Shopify: Why Brands Are Migrating to Medusa
Shopify Payments prohibits nicotine. The PACT Act killed your shipping options. Here is what actually happens when a vape brand gets deplatformed — and the migration path off Shopify onto self-hosted Medusa.
WooCommerce to Medusa Migration: Escaping post_meta
WooCommerce data lives in WordPress's generic post tables. Extracting it cleanly, mapping variable products, and deciding what to do with thirty plugins.
Shopify to Medusa Migration: The Complete Technical Guide
Catalog, customers, orders, subscriptions and the redirect map that decides whether you keep your rankings. A working plan for moving off Shopify, from people who have done it.



