Complete Shopify Scripts Migration Guide (2026)
Everything you need to know about migrating from Shopify Scripts to Shopify Functions — with code examples, timelines, and a free migration tool.
⚠️ Key Date: Shopify is deprecating Script Editor and all Ruby-based Shopify Scripts on June 30, 2026. After this date, your discount, shipping, and payment scripts will stop running. This guide helps you migrate before the deadline.
What's Happening?
Shopify Scripts — the Ruby-based customization layer that powers custom discounts, shipping rules, and payment logic — is being replaced by Shopify Functions. Functions are faster (WebAssembly-based), more scalable, and support the new checkout extensibility platform.
If you use the Script Editor app, or if your store relies on any of these script types, you need to migrate:
- Line Item Scripts → Product Discounts, Order Discounts, Cart Transform
- Shipping Scripts → Delivery Customization
- Payment Scripts → Payment Customization
Timeline
Step 1: Audit Your Scripts
First, identify all scripts running on your store. Go to Settings → Apps and sales channels → Script Editor and document each script's:
- Type (Line item, Shipping, or Payment)
- What it does (discount logic, shipping rules, etc.)
- Complexity (simple rule vs. multi-condition logic)
Or use ScriptShift's free analyzer — paste your Ruby code and get an instant analysis of patterns, complexity, and target Functions.
Step 2: Understand the Mapping
Line Item Scripts → Multiple APIs
Line item scripts are the most common and map to several Function APIs depending on what they do:
| Script Pattern | Target Function |
|---|---|
| Percentage/fixed discounts | Product Discounts |
| BOGO / Buy X Get Y | Product Discounts |
| Tiered volume discounts | Product Discounts |
| Customer segment pricing | Product Discounts |
| Bundle discounts | Cart Transform |
| Gift with purchase | Cart Transform + Discounts |
| Cart validation / blocking | Cart Validation |
| Order-level discounts | Order Discounts |
Shipping Scripts → Delivery Customization
All shipping scripts map to the Delivery Customization Function API. This covers hiding, renaming, and reordering shipping rates.
Payment Scripts → Payment Customization
All payment scripts map to the Payment Customization Function API. This covers hiding, renaming, and reordering payment methods at checkout.
Step 3: Generate Function Code
For each script, you need to create a Shopify Function with three files:
src/run.js— Your function logicinput.graphql— What data the function receivesshopify.extension.toml— Configuration
ScriptShift generates all three files automatically from your Ruby script. Paste your code, click "Generate Function Code", and get ready-to-deploy files.
Example: Bulk Discount Migration
Here's what a common tiered discount script looks like before and after migration:
Before (Ruby Script):
TIERS = [
{ threshold: 10, discount: 0.20 },
{ threshold: 5, discount: 0.10 },
]
Input.cart.line_items.each do |item|
tier = TIERS.find { |t| item.quantity >= t[:threshold] }
if tier
item.change_line_price(
item.line_price * (1 - tier[:discount]),
message: "#{(tier[:discount] * 100).to_i}% bulk discount"
)
end
end
Output.cart = Input.cartAfter (Shopify Function - JavaScript):
export function run(input) {
const TIERS = [
{ minQty: 10, discount: 20 },
{ minQty: 5, discount: 10 },
];
const discounts = [];
for (const line of input.cart.lines) {
for (const tier of TIERS) {
if (line.quantity >= tier.minQty) {
discounts.push({
targets: [{ cartLine: { id: line.id } }],
value: {
percentage: { value: tier.discount.toString() },
},
message: `${tier.discount}% off (qty ${tier.minQty}+)`,
});
break;
}
}
}
return { discounts, discountApplicationStrategy: "FIRST" };
}Step 4: Test on Development Store
Never deploy untested Functions to production. Use a Shopify development store to verify:
- Discounts apply correctly for all product/quantity combinations
- Shipping rules match your original script behavior
- Payment methods show/hide correctly at checkout
- Edge cases are handled (empty cart, high quantities, specific customer tags)
Step 5: Deploy to Production
Once testing passes, deploy your Functions and disable the corresponding Scripts. We recommend running both in parallel for 1-2 weeks to catch any discrepancies.
Common Pitfalls
- External API calls: Scripts that call external APIs won't work in Functions — they run in a sandboxed WebAssembly environment with no network access. Use metafields to pass configuration data instead.
- Dynamic Ruby (eval, method_missing): These patterns can't be directly translated. You'll need to refactor the logic.
- Multiple scripts combining: If you have overlapping scripts, you may need to consolidate logic into fewer Functions.
Start Your Migration Now
Don't wait until June. Use ScriptShift to analyze your scripts and generate Function code in minutes — not days.
⚡ Analyze Your Scripts Free