ERP · DATA · INTEGRATIONS · 12 MAY 2026 · 8 MIN READ
ERP-first or Shopify-first: where the catalogue lives
Which system a product is born in decides more about your integration than which connector you buy. Most stores with a real ERP should be ERP-first, and a good number of them should not.
The ERP should be the master of product identity — the SKU, the cost, the pack size, the supplier reference, the fact that the item exists at all — and Shopify should be the master of how that item is sold. So for most merchants running a real ERP, the catalogue is ERP-first: the item is born in the ERP and arrives in Shopify as a record the ERP keeps alive. Shopify-first is the honest answer only where the ERP is a finance system that has never held an item master, or where the range changes faster than the ERP can be made to describe it. What you cannot do is leave it undecided, because undecided means both systems create products and you spend the next two years deduplicating.
IN SHORT
- ERP-first means a product cannot exist in Shopify until it exists in the ERP, which is the rule that keeps SKUs unique and finance able to reconcile.
- Shopify-first is legitimate where the ERP is really an accounting ledger with no item master, or where new lines appear faster than ERP master data can be maintained.
- Mastering identity in the ERP and merchandising in Shopify is not a compromise — it is the split that actually works, and it is a field-level decision, not a system-level one.
- Shopify’s `productSet` mutation synchronises list fields, so variants, metafields and collections missing from an ERP payload are deleted rather than left alone.
- Store the ERP’s internal id on the Shopify record in a metafield at creation. SKU is a label people rename, not an identifier.
- Whichever direction you choose, one system creates products and the other never does — a store where both create is a store with duplicates it will never fully clear.
The question is where a product is born, not where it is edited
Most discussions of product master data get stuck because they conflate two different questions. One is which system owns each field — price, description, cost, stock — and that is a field-by-field question with a different answer per field. The other is which system a product record is *created* in, and which one is allowed to say that it has stopped existing. That second question has exactly one answer per business, and it is the one that shapes the integration.
Call the two answers ERP-first and Shopify-first. ERP-first means the item master is in the ERP: somebody sets up the item there, with its code, its cost, its supplier and its units, and a feed creates the matching product in Shopify. Nobody creates products in the Shopify admin, and the ERP decides when a line is discontinued. Shopify-first means the reverse: a merchandiser creates the product in Shopify, and the ERP learns about it — often only when an order for it arrives.
Almost every hybrid you have seen in the wild is one of those two with an exception bolted on, and the exceptions are where the mess accumulates.
When ERP-first is right, which is most of the time
If your ERP holds a genuine item master — items with costs, units of measure, supplier links, bills of materials, stock by location — then ERP-first is not really a choice. It is a description of what is already true, and fighting it means maintaining two item masters and reconciling them by hand.
The tells are straightforward. You buy or manufacture goods before you list them. Purchase orders, goods receipts and stock movements happen in the ERP. Finance closes the month from ERP data and needs cost of goods against every line sold. You sell the same items through more than one route — wholesale, a marketplace, a trade counter — so Shopify is one channel rather than the business. Any two of those and the item master belongs upstream.
The benefit is not tidiness. It is that a SKU means one thing everywhere, so stock, cost and margin reconcile without a mapping spreadsheet, and a new line cannot reach the storefront without having been costed. That last one sounds like bureaucracy until the first time someone sells an uncosted product at a loss for three weeks.
When Shopify-first is the honest answer
We will argue for Shopify-first more often than the reflex suggests, because a surprising number of the systems called an ERP in a discovery call are not holding an item master at all.
- The ERP is a finance system. A ledger with a chart of accounts and an invoice run is not an item master. If products exist there only as revenue lines, forcing item creation into it means building an item master inside an accounting package and training merchandisers to use it. The cheaper answer is Shopify-first with SKUs pushed to finance for reporting.
- The range moves faster than ERP master data can. Fashion drops, made-to-order, personalised goods, second-hand and one-off stock all create products at a rate that item master maintenance will not match. Where the catalogue turns over quickly and nobody buys inventory against it, the ERP is describing history rather than governing it.
- Digital, service or bundle lines that are not stocked items. Gift cards, warranties, delivery upgrades and virtual bundles have no natural item in an ERP, and inventing one usually creates a stock record that then needs suppressing everywhere.
- The ERP is on its way out. If a replacement is being selected, do not spend a year building item master discipline into a system you intend to switch off. Master in Shopify, keep the feed to finance thin, and revisit when the new system lands.
The split that actually works: identity upstream, merchandising in Shopify
Neither answer means one system owns everything. The direction decides creation and identity; merchandising almost always belongs in Shopify regardless, because that is where the people who do it work and where the cost of a slow change is highest.
A workable ERP-first split looks like this. The ERP owns existence, SKU, barcode, cost, weight, dimensions, supplier reference, pack size and whether an item is discontinued. Shopify owns title as it appears to a shopper, description, images, collection membership, tags, SEO fields, and the decision to publish. Price needs deciding explicitly and both answers are defensible — the point is that it gets an answer rather than a default.
The reason to write this down is specific: a feed configured to sync "the product" will overwrite a title someone spent an afternoon on with a line from the item master that reads BLK WIDGET 12PK CASE. The ERP name is a warehouse label. It is not a product title, and the integration should never treat it as one after the first import.
Shopify-first inverts the identity half and keeps the rest. Shopify creates the product and assigns the SKU — with a format finance has agreed to, because the ERP will have to live with it — and pushes the new item downstream so purchasing and reconciliation have something to hang off.
Three mechanics that decide whether an ERP-first feed behaves
The direction is a business decision. These three are not, and each of them causes a failure that looks like the connector misbehaving.
`productSet` deletes what you leave out. Shopify documents productSet as the mutation for syncing a product from an external source, and its handling of list fields is true synchronisation: for fields such as variants, metafields and collections it creates what is new, updates what matches, and *deletes entries not included in the input*. Non-list fields are left alone when omitted. So an ERP payload that names three of a product’s four variants removes the fourth, and a payload with no metafields removes the metafields — including the merchandising ones Shopify was supposed to own. Either send the complete intended state, or use the narrower mutations for the fields you actually govern. This is the single most common way an ERP-first feed eats content nobody meant it to touch.
Match on the ERP’s internal id, stored in a metafield. Write it onto the Shopify product when the record is created and match on it forever after. SKU matching needs no setup and works right up until someone renames a code or a second subsidiary issues the same one. productSet will happily look a product up by its handle, which is fine for a first load and a poor identifier afterwards, because handles change when titles do.
Load the initial catalogue in bulk, then feed deltas. Shopify’s bulk import path stages a JSONL file and runs the mutation asynchronously, and the documentation notes the bulkOperationRunMutation request itself is not subject to the standard rate limits — you consume quota creating and polling the operation rather than per record. JSONL files are capped at 100MB and an operation must finish within 24 hours. From API version 2026-01 a shop can run up to five concurrent bulk mutations; before that it is one per type at a time. Use that path for the first load and for the occasional mass re-price, and keep the day-to-day feed to changed records only.
Lifecycle is the half everybody forgets
Creation gets designed. What happens to a product afterwards usually does not, and it is where the ERP-first model either holds or quietly stops being true.
Decide, before the first sync, what the ERP saying "discontinued" should do in Shopify. Archiving removes the product from the storefront and from search results, which is right for a line that will never return and wrong for a seasonal item coming back in September — and it takes the URL with it, so anything holding rankings or inbound links deserves a decision rather than a default. Unpublishing from the online store keeps the record and the history. Setting stock to zero keeps the page up entirely, which is sometimes what you want for SEO and always what you want if the item is on back order. One rule, encoded in the feed, agreed with whoever answers for organic traffic.
Decide, too, what happens when a product is created in the wrong place. Somebody will build one in the Shopify admin on an ERP-first store, because they were in a hurry and the button is there. The feed should notice a product with no ERP id and report it, daily, to a person. Not delete it — deleting somebody’s work teaches them to work around the system. A short list headed "products Shopify has that the ERP does not" is the whole control, and it is an afternoon of work.
And decide who may create a product at all. Shopify’s staff permissions separate creating and editing products from editing price and cost, so on an ERP-first store you can leave merchandisers full control of content while product creation sits with a small number of people. Most of governance is choosing a default that makes the wrong path slightly harder than the right one.
How to decide, in one meeting
Four questions, answered honestly in front of the people who will live with the result. If the first two both point upstream, you are ERP-first and the rest is implementation.
- Where is a new item costed, and could it reach the storefront without being costed? If the answer is the ERP and no, that is ERP-first already.
- Does anything other than Shopify sell these items? A second channel makes a shared item master worth its overhead; a single storefront often does not.
- How many new products appear in a typical month, and who creates them today? If the answer is dozens a week created by merchandisers, ERP-first will be routed around within a quarter.
- When a line is discontinued, who says so, and what should the storefront do about it? An unanswered question here is a feed that archives pages nobody intended to lose.
The position we take
If you run a real ERP, go ERP-first for identity, keep merchandising in Shopify, and spend the effort on lifecycle rather than on the initial load. The load is a week. The lifecycle rules are what you live with.
If the thing you are calling an ERP is a finance package, do not build an item master inside it to satisfy a diagram. Master in Shopify, push what finance needs, and be clear that you have chosen it rather than drifted into it. A deliberate Shopify-first store is a much better place to work than an ERP-first store everyone has learned to bypass.
Questions this raises
Should the ERP or Shopify be the source of truth for products?
The ERP should master product identity — existence, SKU, cost, supplier, pack size — and Shopify should master how the product is sold, meaning title, description, images, collections and publication. If your ERP holds a genuine item master with purchasing and stock behind it, the catalogue is ERP-first. If it is really a finance ledger with no item master, Shopify-first is the honest answer.
Can both systems create products?
They can, and the result is duplicates you will never fully clear. Pick one creator. On an ERP-first store, have the feed report any Shopify product without an ERP id so the exceptions surface daily instead of accumulating silently — reporting them is better than deleting them, because deleting somebody’s work only teaches them to work around the system.
What is the safest way to sync a product from an ERP into Shopify?
Shopify documents `productSet` for exactly this. Be aware that it synchronises list fields: variants, metafields and collections that are absent from your payload are deleted, not left alone. Send the full intended state or use narrower mutations for the specific fields the ERP governs, otherwise the feed will remove merchandising data Shopify was supposed to own.
Should we match products on SKU?
No. Store the ERP’s internal id on the Shopify product in a metafield when the record is created, and match on that. SKU matching needs no setup and breaks the first time somebody renames a code or a second subsidiary issues the same one. Handles are worse again, because they change when titles do.
How do we load a large catalogue for the first time?
Use Shopify’s bulk import path: stage a JSONL file and run the mutation asynchronously. The documentation notes that the `bulkOperationRunMutation` request itself is not subject to the standard rate limits, so you spend quota creating and polling the operation rather than per record. Files are capped at 100MB and an operation must complete within 24 hours.
What should happen in Shopify when the ERP discontinues a product?
Decide it before the first sync, because the three options behave very differently. Archiving removes the product from the storefront and from search results and takes the URL with it. Unpublishing keeps the record and the history. Setting stock to zero keeps the page live, which is what you want for a seasonal line or a back order. Encode one rule and agree it with whoever answers for organic traffic.
NEXT STEP
Free store audit
A senior Shopify engineer reviews your storefront, theme performance and checkout, then sends a prioritised list of fixes.
