From Magento concepts to Sylius variants and channels
The official Sylius documentation on product variants, channels and promotions explains the destination, but offers no Magento to Sylius import path that I could find. Configurable products map well to Sylius variants, store views need sorting into channels or locales, and discount rules are best rebuilt by hand. For import data, expect a custom script reading the Magento database, since the concepts look alike without being the same.
I work on Sylius, so I have an interest in the subject, and I have not presented a Magento migration of my own as a reference. Treat this as a reading of the two models, with links so you can verify it. On the Magento side I have read the database schema files in its public code repository.
Product variants: the closest match
Magento stores a configurable product as a parent with simple child products, linked through catalog_product_super_link, with the choosing attributes in catalog_product_super_attribute. Sylius instead has one product with options and variants: ProductOption holds ProductOptionValue entries, and a variant generator can create the combinations.
The shift is mostly conceptual. A Magento simple product has its own URL, name, price and possibly its own visibility. A Sylius variant is subordinate to its product. So decide what to do with child products that were sold or indexed on their own, because they will not become pages by default. Then there are Magento's other product types, such as bundles and downloadables, for which the 1.14 docs only give part of an answer: a variant can have shippingRequired set to false, for instance. Anything further should be scoped as a requirement.
The First Product guide adds a constraint that affects an import: you choose simple or configurable at creation and cannot change it afterwards. Your script therefore has to decide correctly the first time.
Channels: where Magento's hierarchy gets flattened
Magento has three levels, store_website, store_group and store. Sylius has the channel, one sales channel that can differ in products, currencies, locales, countries, themes, hostnames, taxes, payment and shipping methods, and that holds its own billing data. Channels share one admin panel and one set of users. Prices are also set per channel, and a product not assigned to one stays hidden on it.
| In Magento | In Sylius | Decision to make |
|---|---|---|
| Website with its own domain | Channel | Hostname, currency, billing data |
| Store view for a language | Locale on a channel | Translated slugs and redirects |
| Store view with its own catalog | Possibly a channel | Assign products per channel |
| Configurable with simple children | Product with variants | What happens to child URLs |
| Category tree | Taxon tree | Main taxon for breadcrumbs |
| Catalog price rule | Catalog promotion | Recreate by scope |
| Cart price rule | Cart promotion | Recreate rules and actions |
One caution: "one set of users" means customer accounts behave differently from a Magento setup that keeps accounts separate per website. If two of your websites have the same email with different histories, plan for it.
Promotions: rebuild, do not import
Sylius splits discounts in two, as Magento does with catalogrule and salesrule. Catalog promotions target products, taxons or variants, per channel, with percentage or fixed actions. They run in the background through Symfony Messenger, and the 1.14 docs suggest allowing roughly 2 to 10 minutes after the start date, so a flash sale should be scheduled ahead and a worker must be running. Cart promotions combine rules with actions, with priority and exclusivity.
In my view, rebuilding is healthier than converting. Rules accumulate over the years, and their conditions tend to rely on Magento attributes that will have changed. Export the list, ask marketing which ones are still in use, and recreate only those. Coupon codes still in customers' hands are the exception: list them explicitly with remaining uses.
Import data: the realistic path
The documented tools are fixtures, described as mainly for testing, the API built on API Platform, and programmatic creation through factories and repositories. For a Magento catalog, the last one usually wins, since the reading side is the hard part. Attribute values are spread across catalog_product_entity_varchar, _int, _decimal, _text and _datetime, each per store_id, with definitions in eav_attribute. A store-level value overrides the default. Write that fallback logic once and test it, because it is where wrong prices and descriptions come from.
For the overall project, with timing, order history and redirects, see the companion Magento to Sylius migration guide.
When the mapping shows you should stay
If most of your value lies in Magento modules you bought off the shelf, list each one and find its Sylius equivalent before going further. If several have none and you have no budget to build them, you have your answer, and a Magento specialist or a simpler hosted platform may suit you better. Sylius is a framework you shape with developers, without a licence fee but with a real need for development.
Before committing, ask a provider to walk you through this table using your own data, and to say which rows they would not migrate. You can send me your store structure through my Sylius developer page. I reply within 24 working hours and you will speak directly with the person who writes the code.
