If your Shopify Plus store has been running custom discount or shipping logic through the Script Editor, this affects you directly. Shopify moved to Functions as the platform standard, and the Script Editor is no longer getting updates. Scripts that existed before the cutoff may still be running, but they're unsupported — and any checkout platform update could quietly break them with no fix coming.
This post covers what changed, who needs to act, and what migration actually looks like — including a real before/after code example.
What Were Shopify Scripts?
Shopify Scripts were small Ruby programs that ran server-side at checkout. They gave Shopify Plus merchants the ability to build custom discount and shipping logic that Shopify's native discount tools couldn't handle at the time.
Common things Scripts handled:
- Buy X Get Y with complex product conditions
- Tiered discounts based on cart quantity or subtotal
- Free shipping for customers with specific tags
- Hiding certain shipping rates based on what was in the cart
- Stacking multiple discounts in a specific order
They were locked to Shopify Plus, couldn't be tested locally, had a 5-second execution limit, and were frustrating to debug — failures often showed up silently at checkout with no useful error message.
What Are Shopify Functions?
Functions are the replacement. They run as WebAssembly modules on Shopify's infrastructure — faster, more predictable, and available on all Shopify plans, not just Plus.
You write them in JavaScript, Rust, or AssemblyScript. You can test them locally with Shopify CLI. And they cover most of what Scripts used to do, plus more:
- Discount Functions — product, order, and shipping discounts
- Shipping Functions — custom delivery options and rate logic
- Payment Customization — hide, rename, or reorder payment methods at checkout
- Cart Transform — modify line items before checkout
- Fulfillment Constraints — control how orders are split across locations
Functions are deployed through a Shopify app — either a custom app installed on your store, or a public app. For most merchants, a custom app is the simpler path.
Who Actually Needs to Do Something?
If you're on Shopify Plus and used the Script Editor app, check whether you have active Scripts. That's the group affected here. Standard plan merchants never had Script access, so this doesn't apply to them.
The good news is that not all Scripts need to be rebuilt as Functions. Some can be replaced with Shopify's native discount tools:
- Basic percentage discounts — native automatic discounts handle this now
- Simple BXGY — Shopify's built-in Buy X Get Y discount covers most standard cases
- Fixed amount off an order — native discount codes and automatic discounts work fine
What still needs a Function:
- Tiered discounts based on quantity thresholds (buy 3 get 10%, buy 6 get 20%)
- Tag-based pricing — different discounts for wholesale vs. retail customers
- Shipping logic that depends on cart contents or customer segments
- Multi-condition stacking that Shopify's native tools can't replicate
Audit your Scripts first. You may have less to migrate than you think.
What Happens If You Leave Old Scripts Running?
Shopify stopped accepting new Scripts and blocked editing existing ones through the Script Editor. Scripts that were in place before the cutoff continue to run for now — but the risks are real:
- Shopify is not actively maintaining the Scripts runtime
- Bugs in your Scripts won't be fixed on Shopify's end
- A platform update could break your checkout logic quietly, with no rollback path
- You can't access new checkout features (UI extensions, checkout extensibility) while Scripts are still in place
If a Script fails at checkout, customers can't complete purchases. Since there's no active maintenance on the runtime, you're depending on nothing changing — which isn't a position you want to be in.
Before and After: Tiered Discount in Scripts vs. Functions
Here's a concrete example — a tiered discount that applies 10% off when the cart subtotal exceeds $100.
The Old Script (Ruby)
Input.cart.line_items.each do |line_item|
if Input.cart.subtotal_price >= Money.new(cents: 10000)
line_item.change_line_price(
line_item.original_line_price * 0.9,
message: "10% off orders over $100"
)
end
end
Output.cart = Input.cart
The Function (JavaScript)
export function run(input) {
const subtotal = parseFloat(input.cart.cost.subtotalAmount.amount);
if (subtotal >= 100) {
return {
discounts: [
{
targets: input.cart.lines.map(line => ({
cartLine: { id: line.id }
})),
value: { percentage: { value: "10" } },
message: "10% off orders over $100",
}
],
discountApplicationStrategy: "FIRST",
};
}
return { discounts: [], discountApplicationStrategy: "FIRST" };
}
The logic is identical. What changes is the structure — Functions use a typed input/output model based on GraphQL rather than directly mutating a cart object. Once you understand the pattern, most Scripts translate fairly cleanly.
Migration Checklist
- Open Script Editor and list every active Script
- For each Script, check if native Shopify discounts can replace it (many can)
- Document the conditions and outputs for Scripts that need custom logic
- Create a custom app to house your Functions (no App Store listing needed)
- Install Shopify CLI and scaffold a Function extension
- Write and test the Function locally using
shopify app function run - Deploy to a dev store and test checkout end-to-end before touching production
- Deploy to production and monitor closely for the first few days
- Only remove old Scripts after confirming Functions are working correctly
A Few Things to Know Before You Start
Function limits exist. Functions have a 5MB memory cap and a 10ms instruction limit. This is fine for almost all discount and shipping logic, but if you have deeply nested conditions processing large datasets, test early — don't find out at launch.
Discount stacking works differently. Scripts could chain discounts sequentially on the same items. Functions use a discountApplicationStrategy field (FIRST, MAXIMUM, or ALL) to control how multiple discounts interact. If your Scripts had stacking logic, this needs careful planning before you rebuild.
Custom apps are enough. You don't need a public Shopify app to use Functions. A custom app installed directly on your store is the standard approach for merchants migrating their own Scripts — simpler, faster to deploy, and no App Store review required.
Need a Hand With This?
If you've inherited Scripts you didn't write, or you're dealing with multiple Scripts with overlapping discount logic, the migration can get complicated quickly. We've worked through this with a number of Shopify Plus merchants — auditing what exists, deciding what can be replaced natively, and rebuilding the rest as Functions with proper testing before anything goes live.
If you want someone to look at your Scripts before you start, get in touch and we'll take a look.


