Shopify’s Bundles API lets merchants group multiple products or variants into a single sellable unit. There are two bundle architectures — Fixed and Customized — each with different limits, mutations, and storefront behavior. For rendering bundles on a Hydrogen storefront, see hydrogen-bundles.

Fixed Bundles

Basic use cases including standard bundles and multi-packs, operating within Shopify’s variant limits.

  • Limits: 30 components max, 3 options max
  • Oversell protection: Shopify maintains parent variant inventory (minimum of component quantities) — always enforced
  • Pricing: derived from parent variant, allocated to components via weighted algorithm in checkout/cart/orders
  • Taxes: computed on components, not the parent
  • Storefront: works without Liquid changes; sellable qty available via Liquid

Product Fixed Bundles

Configured at the product level using products and option values. The API automatically maps all underlying variants of the bundle parent product to the component products. Structure: Product → Product component (quantity, parent product, component product, selected options).

  • Create: productBundleCreate mutation — input: title, components (array of quantity, productId, optionSelections). Returns a productBundleOperation ID for async polling.
  • Update: productBundleUpdate mutation — same structure for add/remove.
  • Poll: query productOperation(id) with ... on ProductBundleOperation; statuses: CREATEDCOMPLETE.
  • Access scope: write_products
  • Relationship model: bundleComponents field on bundle product; components connected via productId with optionSelections for variant mapping.
  • Combined options: when components share identical option names/values, they consolidate into a single storefront selector via consolidatedOptions mapping. Counts as one option toward the 3-option limit.
  • App-exclusive: once an app assigns components, only that app can manage them.
  • No nesting: a bundle can’t have components and be part of another bundle.
  • Supports bundle publishing
  • Docs: Add Product Fixed Bundle

Example — Hair and Skin Bundle:

OptionValues
ScentShampoo, Conditioner
Shampoo Size50ml, 100ml

Components: 1x Natural Shampoo (50ml or 100ml), 1x Coconut Conditioner.

Variant Fixed Bundles

Configured at the variant level, ideal for multi-packs. Structure: Product → Product variant → Product variant component (quantity, parent variant, child variant).

  • Two-step process: first productCreate, then productVariantRelationshipBulkUpdate to associate components.
  • Mutation input: parentProductVariantId (the bundle variant) + productVariantRelationshipsToCreate (array of component variant IDs and quantities). Supports productVariantRelationshipsToRemove for deletion.
  • Access scope: write_products
  • Relationship model: productVariantComponents field on the variant (vs bundleComponents for product fixed bundles). Components connected via variant IDs, not product IDs.
  • Detection: productVariant.requiresComponents returns true when components are associated — same field used in Storefront API for hydrogen-bundles rendering.
  • Docs: Add Variant Fixed Bundle

Example — Hair and Skin Bundle:

VariantComponents
Variant 12x Natural Shampoo 50ml, 1x Conditioner
Variant 21x Natural Shampoo 100ml, 1x Conditioner

Customized Bundles

Complex use cases like mix-and-match, where customers choose their own components.

  • Limits: 150 components max, 3 options max
  • Oversell protection: app-maintained on storefront; built-in post-add-to-cart component checking
  • Pricing: Expand mode: parent-derived; Merge mode: component-derived with price adjustment in function; weighted allocation
  • Taxes: computed on components
  • Storefront: multiple component variants; app-managed picker; sellable qty via Storefront API only
  • Cart Transform Function: cart_transform Shopify Function (API 2025-07+). Two operations: Expand (bundle line → component lines) and Merge (linesMerge — when all components are in cart, combine into parent variant).
  • Activation: cartTransformCreate mutation with the function handle.
  • Access scopes: write_cart_transforms + write_products
  • Implementation: Rust or JS/TS via Shopify CLI (shopify app generate extension --template cart_transform).
  • Docs: Add Customized Bundle Function
  • Tutorial: Create Bundle App

Data Sources

ApproachSecurityUse CaseNotes
MetafieldsSecure (server)Merchant-definedRecommended; requires metafield definitions
Line propertiesBrowser-editableMix-and-matchRequires validation in function

Metafields

Defined under Settings > Custom data > Variants. All variant references use GID format (gid://shopify/ProductVariant/<id>).

MetafieldTypePurpose
component_referenceProduct Variant — ListProduct variant IDs included in the bundle
component_quantitiesInteger — List (min 1)Quantity per component (order matches refs)
component_parentsJSONReverse-lookup: parent bundles a child belongs to

The component_parents JSON stores an array of parent definitions, each with id (parent variant GID), component_reference.value (array of child GIDs), and component_quantities.value (array of quantities). This enables the Merge operation to identify when all components of a bundle are present in the cart.

Shared Behavior (Both Types)

  • Discounts: calculated on the parent, allocated to components
  • Cart display: grouped in cart/checkout; queryable via cart.line.components
  • Bundle grouping: by parent variant ID
  • Order storage: components with parent reference via groupings
  • Fulfillment: no constraint — components can be fulfilled independently
  • Refunds/returns: component-level operations
  • Reporting: component-level sales reporting

Store Eligibility

Use the BundlesFeature GraphQL object to verify whether a store is eligible for bundles. Ineligible stores cannot publish bundles to sales channels.

Bundle Lifecycle

PhaseApp RoleShopify Role
AdminMerchant creates product; app configures bundles per variant; UI ext summarizesN/A
StorefrontCustomized bundles use theme app blocks; fixed bundles work automaticallyN/A
CheckoutN/AGroups bundle products as line collections
OrdersFulfillment apps access bundle dataOrder lines return components with parent ref

Build Surfaces

  • Checkout — Shopify Functions group products into bundles in the cart and at checkout.
  • Admin — Product configuration extensions for merchant bundle setup.
  • Online Store — Theme app blocks for customer bundle selection on product pages.

Sales Channel Support

Bundles work natively on Online Store, Shop, and Shopify POS. Custom storefronts require bundle publishing to be enabled (disabled by default). Publishing is only supported for product fixed bundles — variant fixed bundles cannot be published to custom storefronts. Enablement requires the app to be a sales channel; for third-party apps, activate via Partner Dashboard (App setup → “Sell Bundles”).

Limitations

  • Selling plans — bundles cannot be combined with subscriptions, pre-orders, or try-before-you-buy.
  • Shopify Scripts — line item Scripts don’t apply to bundle line items; operations are discarded. Scripts sunset June 30, 2026 — migrate to Shopify Functions.
  • No nesting — a bundle can’t be a component of another bundle.
  • App-exclusive management — once an app assigns components, only that app can modify them.
  • Quantity options — cannot be combined across components.
  • Custom storefront publishing — only product fixed bundles; variant fixed bundles cannot be published.

Admin UI

Product Configuration Extension

A ui_extension that displays bundle component summaries on product and variant pages. Two targets required:

  • admin.product-details.configuration.render
  • admin.product-variant-details.configuration.render

Generated via shopify app generate extension --template product_configuration. Supports edit links using RFC 6570 URL templates ({product_id} variable) to open the bundle app’s configuration UI. Requires Shopify CLI 3.76+ and API version 2025-01.

  • Migration: extensions created via Partner Dashboard must migrate to CLI — add [extensions.targeting.urls] to TOML and redeploy.
  • Docs: Add Merchant Config UI

Opens the embedded bundle app to create or update bundle components.

See Also