← All provider guides

Shopify GraphQL API migration: four deprecation waves, four codemods

shopify graphql migration 49 tracked change records

Shopify does not break its APIs in big SDK majors. It retires surface on a dated-version schedule — 2026-07, 2026-10 — and the changes land inside GraphQL documents rather than SDK method names: a field renamed on the Customer Account API, an entire query subtree removed, a deprecated mutation argument, a new enum value that existing exhaustive switches do not handle, and a POS UI extensions print call replaced by a namespaced successor. Each of these breaks consuming code in a way a lockfile bump never mentions, and each is mechanical enough to carry as a codemod. mendapi ships four deterministic packs for these waves, all applied locally as reviewable diffs.

The four packs, exactly as the registry ships them

This list is read directly from the mendapi migration pack registry at page build time, so it matches what the codemods actually do:

Shopify Customer Account API: discountedUnitPrice -> approximateDiscountedUnitPrice

Pack shopify-customer-account-draftorder-price:

  • Rename discountedUnitPrice field to approximateDiscountedUnitPrice in Customer Account API GraphQL usage

Upstream changelog: https://shopify.dev/changelog/discountedunitprice-on-draftorderlineitem-customer-account-api-deprecation

Shopify Customer Account API: remove Customer.lastIncompleteCheckout selections (Checkout subtree removed in 2026-10)

Pack shopify-customer-last-incomplete-checkout:

  • Delete lastIncompleteCheckout selections (including the nested Checkout selection block) from Customer Account API GraphQL queries

Upstream changelog: https://shopify.dev/changelog/customer-account-api-customer-lastincompletecheckout-and-checkout-types-removed

Shopify Admin API: drop deprecated isCumulative argument on marketingEngagementCreate

Pack shopify-marketing-engagement-cumulative:

  • Remove the deprecated cumulative flag from marketingEngagementCreate calls (GraphQL field, variable declaration, and JS variables object)

Upstream changelog: https://shopify.dev/changelog/deprecation-of-cumulative-marketing-engagements

Shopify Admin API: handle new OrderDisplayFulfillmentStatus value FULFILLMENT_NOT_REQUIRED (2026-10)

Pack shopify-order-fulfillment-not-required:

  • Insert case 'FULFILLMENT_NOT_REQUIRED' as a fall-through before case 'UNFULFILLED' in switches over displayFulfillmentStatus
  • Insert a FULFILLMENT_NOT_REQUIRED entry mirroring the UNFULFILLED entry in status-to-value object maps

Upstream changelog: https://shopify.dev/changelog/orderdisplayfulfillmentstatus-now-returns-fulfillment_not_required

Preview each migration as one diff

Every pack runs locally as a dry run by default. On the bundled fixture repos each pack rewrites the affected GraphQL documents and call sites, writing a unified patch you can read before anything is applied:

npx mendapi scan
# -> which files touch the affected Shopify API surfaces, with line numbers
mendapi fix --migration shopify-customer-account-draftorder-price
# -> dry run: changes.patch + fix-report.json, nothing applied
mendapi fix --migration shopify-customer-account-draftorder-price --apply
# -> applies the reviewed diff

Nothing leaves your machine at any step; zero network calls is the default and only mode. The report records which rule fired where, and every rewritten file carries a syntax-check verdict, so review is a read of the patch, not an audit of the tool.

What the codemods refuse to touch

A migration tool earns trust by what it leaves alone. GraphQL rewrites here anchor on the affected API's document shape, not on bare identifiers: a discountedUnitPrice field on an unrelated object is never renamed, and the fulfillment-status pack only inserts the new FULFILLMENT_NOT_REQUIRED case where an exhaustive switch or status map over displayFulfillmentStatus already exists — it does not invent handling logic. Every rule is locked by golden-fixture regression tests with negative controls (fixture lines that must survive byte-for-byte), so a rule that starts over-firing fails our build before it reaches your repo.

The part no codemod fixes

Honest scope: the packs handle the mechanical rewrites. They do not decide what your checkout flow should do now that the Checkout subtree is gone, whether your analytics should recompute historical marketing engagements as non-cumulative, or how mTLS certificates get provisioned for the card deposit endpoint. The tracked Shopify history counts 18 breaking or deprecation entries, and the platform-behavior ones stay not code-fixable by verdict — the Shopify tracker lists every verdict with its reason — because pretending a codemod covers them is how migrations go wrong.

Related

Every entry on this page is generated from the mendapi change database at build time and links its upstream source.