Home
Services

E-Commerce Engineering

  • Shopify Theme DevelopmentOptimized Shopify 2.0 theme
  • Shopify App DevelopmentPrivate app for your store
  • Headless Shopify SolutionsLightning-fast Next.js + Hydrogen stores
  • Platform Migration to ShopifyMove to Shopify smoothly
  • Shopify Speed OptimizationImprove Core Web Vitals

Custom Software Development

  • SaaS & Web Applications DevelopmentFull-stack apps with modern frameworks
  • API Development & System IntegrationConnect systems via APIs

Workflow & Data Operations

  • Workflow AutomationEliminate repetitive manual tasks
  • Data Analytics & DashboardsTurn data into dashboards
  • Technical SEO EngineeringSchema, audits, and programmatic SEO

Trusted by leading enterprises in France, UK & Canada.

View all services
BlogAbout
|
Contact

Ready to engineer the future?

Whether you need a full engineering squad or technical consultancy, let's discuss your roadmap.

Book a Technical SEORequest a Migration AuditHire Dedicated Developer

High-end Shopify engineering for brands that refuse to compromise on performance.

Copyright © 2026 Sentinu Solutions.
All rights reserved.

Services

  • Custom App Development
  • Headless Shopify
  • Shopify Migration
  • Shopify Performance Audits

Start Project

  • Shopify Ecommerce Engineering
  • Custom Software Development
  • Automation Workflow Services

Legal

  • Privacy Policy
  • Terms of Service
  • Legal Notice

Connect

  • facebook
  • instagram
  • linkedin
Home/Blog/Shopify Functions: When to Reach for Them, When to Stay in Apps, When to Go Headless
Shopify DevelopmentCustom Software

Shopify Functions: When to Reach for Them, When to Stay in Apps, When to Go Headless

A senior engineer's deep dive into Shopify Functions in 2026. The five extension points, what each one solves, when Functions beat apps, when apps beat Functions, and how Functions fit alongside headless storefronts.

Mar 27, 202614 min read
Shopify Functions: When to Reach for Them, When to Stay in Apps, When to Go Headless

Share this article

Contents

  • What Shopify Functions actually are
  • The five extension points
  • Product discount and order discount
  • Delivery customization
  • Payment customization
  • Cart transform
  • Fulfillment constraints
  • The Function vs app vs headless decision
  • A real-world architecture: B2B with Functions, app, and Hydrogen
  • What Functions cost to ship
  • When you should not use Functions
  • What we ship at Sentinu
  • FAQ
  • Where to take this next

Share this article

Contents

Contents

  • What Shopify Functions actually are
  • The five extension points
  • Product discount and order discount
  • Delivery customization
  • Payment customization
  • Cart transform
  • Fulfillment constraints
  • The Function vs app vs headless decision
  • A real-world architecture: B2B with Functions, app, and Hydrogen
  • What Functions cost to ship
  • When you should not use Functions
  • What we ship at Sentinu
  • FAQ
  • Where to take this next

Three years after Shopify Functions launched, most developers we talk to still describe them as "that thing for custom discounts." It is true that custom discounts is what Functions ship most commonly, and it is also missing the larger point: Functions are the cheapest path to custom commerce logic that Shopify has ever offered, and the merchants who understand the full range of extension points ship competitive advantages that custom apps once required.

This post is the deeper engineering view of Shopify Functions in 2026. It is the post that should accompany our custom app vs public app decision framework earlier this month, because Functions are often the right answer to a problem that custom apps used to claim. It also addresses the question that comes up on every Plus engagement: how do Functions fit alongside headless storefronts, where the front-end runs outside Shopify's runtime but the checkout still depends on Shopify's logic.

What Shopify Functions actually are

Functions are pieces of custom logic, written in Rust, JavaScript, or TypeScript, compiled to WebAssembly, and deployed into Shopify's runtime. They run synchronously at specific extension points in the cart and checkout, with strict execution-time budgets and a deterministic input-output contract. They are not webhooks. They are not server-side code you host yourself. They are not theme extensions. They are platform-native logic that becomes part of how Shopify processes commerce.

The architectural significance of that distinction: a Function runs with the order, not after it. A cart transform Function modifies what the customer sees in the cart in real time. A discount Function applies before the totals render. A delivery Function determines what shipping rates are shown. These are not asynchronous reactions to events; they are synchronous decisions inside Shopify's commerce flow.

The implications for app strategy:

  • Logic that used to require an app with a hosted server (with the cost of hosting, the security surface of OAuth tokens, the maintenance burden of an externally-deployed service) can now run as a few hundred lines of Rust that you deploy and forget
  • Logic that used to require unsupported workarounds (theme code that fights Shopify, JavaScript injected into checkout, manual order modification through admin) now has a supported, documented, performant path
  • For headless storefronts where you already run your own frontend infrastructure, Functions let you keep all the checkout logic on Shopify rather than shipping a parallel checkout

The five extension points

In 2026, Functions ship for five primary extension types. Each solves a different problem and each has its own constraints.

Each extension point is a synchronous hook in Shopify's commerce flow, pick the point that matches the customer-visible decision you need to change.

Product discount and order discount

The original Function category and still the most-used. Replaces Shopify's automatic discount system for any logic that the native discount engine cannot model.

What it can do: Conditional discounts based on cart contents, customer attributes, or metafields. Tiered pricing where the discount changes based on quantity bands. Custom "buy X get Y" logic where the system's native variant cannot capture the rule. Customer-tier discounts that read from a metafield on the customer (loyalty status, B2B tier, contract pricing).

What it cannot do: Calculate based on data outside Shopify (no HTTP calls during execution). Maintain state across cart updates. Apply manually-triggered discounts (Function discounts are automatic by definition).

When it wins versus an app: When the discount logic is rules-based and deterministic from cart state. A "buy two of category A, get one of category B free" rule that Shopify Native cannot model is a Function. A discount tier based on customer metafields is a Function.

When an app wins: When the discount logic requires real-time external data (live competitor pricing, dynamic surge pricing). When the merchant needs a UI for non-technical staff to manage discount rules (Functions ship via code deployment; merchant-managed rules need an app with a dashboard).

Delivery customization

Modifies what shipping options the customer sees at checkout. Hide, rename, sort, or modify shipping methods based on the cart contents, customer attributes, or order value.

What it can do: Hide express shipping for orders containing oversized items. Sort shipping options by price ascending or by delivery date. Rename shipping options based on the destination country. Apply free shipping thresholds with non-trivial logic (free shipping only on certain product categories above a certain spend).

What it cannot do: Add new shipping rates that do not exist as carrier-calculated or manually configured rates. Modify the actual rate values (a separate Function type, "delivery method customization," is in progress at Shopify but limited). Call external shipping APIs during execution.

When it wins: When the logic is "show or hide existing rates based on cart state." Replaces a category of apps that did exactly this through fragile checkout script injection.

When an app wins: When you need carrier-calculated rates from a non-supported carrier, which still requires an app integrating with the Shopify Carrier Service API.

Payment customization

Modifies what payment methods the customer sees at checkout. Hide, rename, sort, or modify payment options based on the cart contents.

What it can do: Hide credit card payment for orders above a certain value (forcing wire transfer for high-value B2B orders). Hide buy-now-pay-later options for restricted product categories. Rename payment options for B2B accounts. Sort payment methods to surface the highest-margin option first.

What it cannot do: Add new payment methods (payment gateway integrations are still apps). Reject orders based on payment method (use a Function in cart transform to do this earlier).

When it wins: When the logic is "show or hide existing payment options." B2B stores routinely use this to enforce payment terms based on customer tier or order value.

When an app wins: When you need new payment method integrations or complex fraud detection that requires external data.

Cart transform

The most powerful and most complex Function type. Modifies the cart contents themselves before discounts and totals are calculated. Replaces a category of work that previously required either custom apps with cart API mutations or fragile JavaScript that fought Shopify's native cart.

What it can do: Bundle products into a virtual single line item (a bundle that appears as one line at one price but contains multiple SKUs for inventory and fulfillment). Expand a single line into multiple lines (the inverse: a "starter kit" bundle that decomposes into its components on add-to-cart). Add free gifts based on cart contents (the "buy this, get free X" pattern, but as actual cart line items rather than a discount). Update line item properties based on cart-level logic.

What it cannot do: Read external data during execution. Operate across multiple carts (each Function call sees only the current cart). Modify customer or shipping address.

When it wins: Bundle logic that the native bundle product type cannot model. Free gift logic that needs to appear as actual line items rather than discounts. Any cart manipulation that previously required cart API mutations from a hosted app.

When an app wins: When the bundle composition needs to come from an external system (a configurator that builds custom kits based on user input not in Shopify). When the logic requires UI for the customer to interact with mid-cart.

Fulfillment constraints

The newest Function category. Enforces rules about what can ship together based on inventory location, product attributes, or order configuration.

What it can do: Prevent fragile and heavy items from shipping in the same parcel. Route fulfillment to the closest warehouse based on shipping address. Block orders that cannot be fulfilled from any single location.

What it cannot do: Call a warehouse management system during execution. Override carrier shipping decisions.

When it wins: When the fulfillment logic is rules-based and deterministic from order state.

When an app wins: When the logic requires real-time inventory data from a non-Shopify source or complex routing that needs an external optimization engine.

The Function vs app vs headless decision

The framework for choosing among these three paths for a given commerce logic problem:

  1. Can the logic be expressed as deterministic rules over Shopify-known data? If yes, Function. If no, consider app or external integration.
  2. Does the logic need to run inside checkout (where customer-facing decisions happen)? If yes, Function. If the logic can run before or after (in a separate workflow), consider an app or an external automation like n8n.
  3. Does the logic need a UI for merchant staff to configure? If yes, you need an app with admin pages (a Function alone has no admin UI; the merchant configures it through metafields, which is acceptable for technical teams and unacceptable for non-technical ops).
  4. Does the logic need to read external data in real time? If yes, you need an app with hosted backend. Functions have no network access during execution.
  5. Is the storefront headless? Functions still apply; they run in Shopify's checkout regardless of where the storefront is hosted. A headless Hydrogen or Next.js front-end plus Functions for checkout logic is a coherent architecture, often more so than headless plus custom checkout logic.

The framework dramatically narrows the "what tool" question. The right answer is often "Function for the rules engine, app for the merchant UI, headless storefront for the customer-facing presentation, and they all coexist."

A real-world architecture: B2B with Functions, app, and Hydrogen

To illustrate how the pieces fit together, the architecture for a recent B2B Shopify Plus client at Sentinu:

Same stack as the ASCII sketch above: Hydrogen for the portal, Functions inside Shopify for checkout rules, custom app where sales managers maintain B2B tier data.

Three Functions handle the commerce logic at checkout. One custom app handles the merchant-facing administration (because sales managers need to update B2B tier assignments without engineering involvement). A Hydrogen storefront handles the customer-facing UX with branded design and the B2B catalog navigation.

Each piece does what it does best. Functions for fast, deterministic, in-checkout logic. App for the admin UI that non-developers need to operate. Headless for the customer presentation that needed brand-specific design.

We covered the B2B portal architecture in detail in our Shopify Plus B2B post; this is the same architecture with the Function layer made explicit.

What Functions cost to ship

Honest cost ranges for Function development engagements:

Project shapeCost
Single discount Function (rules-based, modest complexity)$3K to $6K
Single delivery customization Function$3K to $5K
Cart transform Function with bundle logic$6K to $12K
Suite of 3 to 5 Functions for a B2B portal$15K to $30K
Function plus admin app for merchant configuration$20K to $50K

The variance is in the input data model and the testing surface. Functions are stateless and well-typed, which makes the code itself fast to write. The work is in defining the metafield schema, testing the edge cases, and verifying the Function does not regress on existing orders.

Ongoing maintenance is minimal compared to apps. A Function does not have a hosted backend to maintain, no API key rotation, no server outages. The main maintenance concern is the Shopify API version that the Function targets, which deprecates on the same 12-month cycle as the rest of the Shopify platform.

💡

The biggest under-appreciated benefit of Functions versus apps is the operational simplicity. An app that handles discount logic for a Shopify store is a service you must monitor, update, secure, and pay to host. The equivalent Function is a compiled WebAssembly module that Shopify runs on your behalf. The total cost of ownership over three years is dramatically lower for Functions, and the failure modes are dramatically simpler.

When you should not use Functions

The honest counter-cases. Functions are not the right answer to every commerce problem.

When you need a merchant-facing UI. Functions have no admin interface. The merchant configures them through metafields, which is acceptable when the merchant is a developer or working with a dedicated agency but unacceptable when the merchant wants to change a discount rule from the Shopify admin without filing a ticket. For merchant-configurable logic, you build an admin app on top of the Function (the architecture pattern from the B2B example above).

When the logic requires real-time external data. Functions have no network access during execution. If your discount rule needs to call a competitor-pricing API in real time, you cannot use a Function alone. You either pre-compute the data and store it in metafields that the Function reads (good for daily-refreshed data) or you use an app with a hosted backend (good for true real-time).

When you need merchant-managed configuration with high frequency. A Function deployment is a code deployment. A merchant who wants to change a rule daily should not be deploying Functions daily. The same Function plus a metafield-driven configuration solves this, but it means design work to define the configuration schema.

When the merchant has zero engineering capacity. Functions are code. Someone has to write them, test them, and maintain them. For a merchant whose team is entirely non-technical, the app store path remains correct because the maintenance cost is the app vendor's problem, not the merchant's.

What we ship at Sentinu

Recent Function engagements illustrate the range:

  • A French D2C brand with seasonal "buy 3 in this collection, the cheapest one free" promotions that the native discount engine could not model cleanly. Single cart transform Function plus product discount Function, deployed once, configured via metafields on collections, has run for 18 months without modification.
  • A UK B2B parts distributor with tiered pricing that depended on customer contract terms stored in metafields. Three Functions (product discount, order discount, delivery customization) replaced a $400/month app subscription that had been struggling with the merchant's specific tier logic. Payback in 5 months.
  • A Canadian fulfillment-constrained merchant whose products had specific shipping incompatibilities (chemicals that could not ship air, fragile items that needed dedicated parcels). Two fulfillment constraint Functions plus a small admin app for the operations team to manage the constraint rules. Replaced a manual order-review process that had been catching errors after they shipped.

The pattern: Functions are the answer when the logic is rules-based, deterministic, and lives at checkout. They are not the answer when the logic needs UI, external data, or operational flexibility that only an app provides. The architecture is usually some mix of the two, and the discipline is knowing which part goes where.

FAQ

Are Shopify Functions Plus-only?

No, not entirely. Discount Functions and delivery customization Functions are available on all plans. Payment customization Functions and cart transform Functions are Plus-only. Fulfillment constraint Functions are Plus-only. For non-Plus stores, the available Function categories cover the most common use cases.

What language should I write Functions in?

Rust is the official primary language and the most-supported in the documentation. TypeScript and JavaScript are also supported and ship to the same WebAssembly target. For most teams, JavaScript or TypeScript is the right call because the hiring pool is larger and the Shopify SDK examples cover them well. Rust is the better choice for teams that already use Rust elsewhere or for Functions that need maximum performance.

How do Functions interact with Shopify Flow?

Flow is asynchronous; Functions are synchronous. Flow runs after events happen (order placed, customer created); Functions run during the event (cart updated, checkout viewed). They complement each other. A Function can apply a discount during checkout; a Flow can send the customer a thank-you email after the order completes. We covered Flow indirectly in our workflow automation comparison, where the same operational principles apply.

Can I test Functions locally before deploying?

Yes. Shopify ships a CLI that runs Functions against sample inputs locally. The development loop is similar to writing serverless functions in other ecosystems: write, test against fixtures, deploy, verify in a development store. Production-grade Function development at our scale uses CI/CD that runs the Function against a battery of test cases before deploying.

What is the execution time budget for a Function?

Strict. Functions must complete within a small number of milliseconds (the exact number varies by Function type but is generally under 50ms). Functions that exceed the budget are killed and the merchant's checkout proceeds without the Function's logic, which is often a worse experience than the merchant designed. This is why Functions cannot make network calls; the latency budget would be exceeded by any external dependency.

Are Functions versioned?

Yes. Each Function deployment creates a new version. Older versions remain associated with their deployment date and can be rolled back to. This is one of the operational advantages over apps, where rolling back to a previous version often requires coordinating with the app vendor.

Will Shopify Functions replace Shopify Flow?

No. They solve different problems. Flow is the asynchronous workflow tool for post-event automation. Functions are the synchronous extension points inside Shopify's commerce flow. A modern Shopify Plus store typically uses both.

Where to take this next

If you are scoping a commerce logic problem and Functions look like the right path but you want validation against your specific business shape, that is what our Shopify app development practice covers. We have shipped Functions, custom apps, and headless storefronts in every combination, and we will tell you honestly which combination fits the problem. If the broader question is whether Functions, custom apps, or headless commerce is the right architectural fit for your store, our custom app vs public app post and Hydrogen vs Next.js post are the companion reads. The right architecture for a modern Shopify Plus store is rarely one of these tools; it is the right combination of all three.

Related Topics

shopify-functionsshopify-app-developmentheadless-shopifycheckout-extensions

Related posts

View all articles
Custom Shopify App vs Public App: When to Build, When to Install, When to Extend
Shopify DevelopmentMar 3, 2026

Custom Shopify App vs Public App: When to Build, When to Install, When to Extend

A senior engineer's decision framework for Shopify app strategy in 2026. When to build a custom app, when to install from the App Store, when to extend an existing app, and the real cost math behind each path.

14 min read
Shopify Scripts Are Dead in 48 Days: The Functions Migration Playbook for Plus Stores
Shopify DevelopmentMay 12, 2026

Shopify Scripts Are Dead in 48 Days: The Functions Migration Playbook for Plus Stores

June 30, 2026 is a hard wall. Scripts editing is already locked. If your checkout discounts, shipping rules, or payment logic still run on Scripts, here is the migration playbook, the failure modes, and what it costs.

13 min read
Shopify Metaobjects and Metafields: A Developer's Guide to Structured Content in 2026
Shopify DevelopmentApr 21, 2026

Shopify Metaobjects and Metafields: A Developer's Guide to Structured Content in 2026

Metafields attach data to existing resources. Metaobjects are standalone records you can reference anywhere. Here is when to use which, how to model them, and the API patterns that scale across thousands of products.

12 min read