If you're running a Shopify Plus store with custom Scripts, you have 4 days left.
June 30, 2026 is Shopify's hard deprecation date for Shopify Scripts — the Ruby-based customization layer powering custom discounts, shipping rules, and payment logic for thousands of merchants. After this date, every Script stops executing. Silently. With no fallback. Your checkout reverts to Shopify's defaults as if your custom logic never existed.
Critical: As of April 15, 2026, the Script Editor is already locked. You can no longer edit or publish Scripts. Any Script still running in production is frozen code — bugs cannot be patched. June 30 is when execution stops entirely. If you haven't started migrating, you are running unmodifiable code in production right now.
This isn't a "we'll get to it eventually" situation. It's a breaking change with a hard deadline days away.
In this guide I'll walk you through:
What's actually changing and why
- The direct replacement for each Script type
- A step-by-step migration path with corrected CLI commands
- Real code examples showing before and after
Let's move fast.
What Are Shopify Scripts?
Shopify Scripts were introduced as a Shopify Plus-only feature that let developers write Ruby code to customize the cart and checkout experience. Three types existed:
- Line Item Scripts — modify prices, apply discounts, bundle logic
- Shipping Scripts — customize shipping rates, hide or rename options
- Payment Scripts — show or hide payment methods based on conditions
They were powerful for their time, but they carried serious limitations: Ruby-only, Plus-only, slow to test, no version control, and fundamentally incompatible with Shopify's Checkout Extensibility architecture that replaced checkout.liquid for Plus merchants in 2023–2024.
Why Shopify Is Deprecating Them
Three reasons, in plain terms:
1. Checkout Extensibility replaced checkout.liquid — Scripts are architecturally incompatible with the new checkout model
2. Performance — Ruby Scripts ran server-side with cold-start delays. Shopify Functions compile to WebAssembly and run under a strict 5ms execution cap. Rust Functions typically execute in 3–5ms; JavaScript Functions run 10–30ms in real-world use and should be used only for simpler logic
3. Platform-wide access — Shopify Functions are available to all plan levels via installed apps, not just Shopify Plus subscribers
Scripts vs. Functions: What Actually Changed

Here's the architectural shift. Scripts were a Plus-only workaround bolted onto an older platform. Functions are native, WebAssembly-powered infrastructure available on every plan.
What Gets Replaced by What?
Enter Shopify Functions
Shopify Functions are the modern replacement. You write them in JavaScript/TypeScript or Rust — the two officially maintained, first-class languages in 2026. Any language that compiles to WebAssembly is technically supported, but Rust and JavaScript are the only paths with active Shopify CLI tooling and official support.
Choose based on your use case:
1. JavaScript/TypeScript — good for prototyping, simpler discount logic, teams without Rust experience. Compiled via Shopify's Javy toolchain.
2. Rust — recommended for complex logic, large carts, public apps, or any Function near the 256KB binary size limit. Runs 3–5ms versus 10–30ms for JavaScript.
Platform limits (as of 2026): Each store can run a maximum of 5 Discount Functions, 1 Cart Transform Function, and 5 Validation Functions. Plan your migration with these caps in mind if you have many Scripts.
Migration: Step by Step
Step 1: Audit your current Scripts
Go to Shopify Admin → Apps → Script Editor. The editor is now read-only (locked since April 15), but you can still view all active Scripts, export the customizations report, and read the source logic.
List every active Script, what business rule it enforces, and every edge case it handles.
Pay attention to:
- Is this Script still being used in production?
- What customer-facing behaviour does it produce?
- Are there conditional rules — customer tags, order thresholds, product exclusions, B2B rules?
Use the Shopify Scripts customizations report (available from the Script Editor page) to export the full list automatically.
Step 2: Set up your Shopify Functions environment
You need Shopify CLI 4.0 or higher:
# Verify CLI version
npm install -g @shopify/cli
shopify version # confirm 4.0+
Create a new app or add a Function extension to an existing one:
# Create a new app (correct CLI 4.0 syntax)
npm init @shopify/app@latest
# Or add an extension to an existing app
shopify app generate extension
# Choose: Discount, Cart Transform, Delivery Customization, or Payment Customization
Step 3: Scaffold the right Function type
shopify app generate extension
# Select "Discount - Order discounts" → for order-level discount Scripts
# Select "Discount - Product discounts" → for variant/product-level logic
# Select "Delivery customization" → for Shipping Scripts
# Select "Payment customization" → for Payment Scripts
# Select "Cart transform" → for bundle/kit Line Item Scripts
Step 4: Rewrite your logic in JavaScript or Rust
Here's a real before/after for the most common migration case — 10% off all orders over $100:
Before (Ruby — Shopify Script)
Input.cart.line_items.each do |line_item|
if Input.cart.subtotal_price >= Money.new(cents: 100_00)
line_item.change_line_price(
line_item.line_price * 0.9,
message: "10% bulk discount"
)
end
end
Output.cart = Input.cart
After (JavaScript — Shopify Order Discount Function)
// run.js — Order Discount Function
export function run(input) {
const subtotal = parseFloat(
input.cart.cost.subtotalAmount.amount
);
if (subtotal >= 100) {
return {
discounts: [
{
targets: [
{ orderSubtotal: { excludedVariantIds: [] } }
],
value: { percentage: { value: "10.0" } },
message: "10% bulk discount"
}
],
discountApplicationStrategy: "FIRST"
};
}
return {
discounts: [],
discountApplicationStrategy: "FIRST"
};
}
The business logic is the same. The architecture is fundamentally better — compiled to WebAssembly, version-controlled, deployable via CI/CD, and accessible on all Shopify plans.
Using Rust instead? The logic structure is similar. Shopify's CLI scaffolds a full Rust project with the shopify_function crate when you select Rust at the extension type prompt. For complex discount engines with large catalogs, Rust is the safer choice as JavaScript Functions can exceed the 5ms execution cap on heavy carts.
Step 5: Test in a development store
shopify app dev
This deploys your Function to a development store in draft mode. Create a discount in Shopify Admin that uses your new Function, then test it across all cart scenarios — especially every edge case from the original Script.
Step 6: Deploy to production and monitor
shopify app deploy
Link your Function to a discount or customization in Shopify Admin (or via the Admin API). Monitor checkout conversion rate carefully for the first 48 hours after going live. A measurable drop typically signals a missed edge case, not a platform issue.
Common Migration Pitfalls
1. Scripts that relied on execution order
Scripts ran sequentially and could interact with each other. Functions run independently in parallel. If you had two Line Item Scripts that stacked or modified each other's output, refactor the logic into a single Function or control stacking behaviour explicitly with discountApplicationStrategy.
2. Bundle logic mapped to the wrong Function type
Bundle discounts in Line Item Scripts map to Cart Transform Functions, not Discount Functions. These are a completely separate extension type — selecting the wrong one at scaffold time means you're building against the wrong API schema.
3. Assuming Shipping Scripts are low priority
All three Script types — line item, shipping, and payment — stop executing on June 30. Shipping Scripts are often lower revenue impact than discount Scripts, but if your store hides express shipping for fragile items, shows different carrier options by customer tag, or applies shipping discounts conditionally, those rules disappear on the deadline. Migrate them before June 30, not after.
4. Edge cases left uncoded
Ruby Scripts accumulated implicit logic over years — gift card exclusions, B2B pricing tiers, free shipping thresholds, variant-level carve-outs. Functions are explicit. Every condition your business requires must be coded. The audit in Step 1 is your safety net here.
5. JavaScript Functions on complex carts
JavaScript Functions run 10–30ms in real-world use. Shopify's 5ms execution cap means JavaScript Functions can be aborted on heavy carts, leaving the checkout in its default state. For stores with large catalogs or many line items, write in Rust. For simple rules (e.g. flat percentage discount on all orders), JavaScript is fine.
6. Not reading the GraphQL input schema
Each Function type has a defined input schema. You control what data your Function receives by editing run.graphql. If your logic needs metafields, customer tags, or product attributes, add them to the input query — do not assume they arrive automatically.
What If You're Already Behind?
If you're reading this with four days on the clock and active Scripts still in production, here's the prioritisation:
1. Revenue-critical Scripts first — discount Scripts affecting checkout conversion and payment Scripts controlling visible gateways go first
2. Stub before you optimise — a working Function that matches the Script's behaviour is better than a perfectly architected one that isn't deployed
3. Migrate all Script types before June 30 — Line Item, Shipping, and Payment Scripts all stop on the same date. Don't assume Shipping Scripts can wait; schedule them in the same sprint
4. Use Shopify's migration docs at shopify.dev — the customizations report and Function input schemas are well-documented
If you have a complex store with multiple interdependent Scripts and the timeline feels impossible, working with a certified Shopify expert agency is the fastest path. Teams like Lucent Innovation — 10+ years as a Shopify Plus partner, 12+ years in ecommerce, 5,000+ stores delivered — can run a focused Functions migration sprint with proper QA, significantly faster than doing this under pressure in-house.
Quick Recap
- Shopify Scripts deprecate June 30, 2026 — no extension, no fallback, no grace period
- Script Editor locked since April 15, 2026 — existing Scripts are frozen and cannot be modified
- Shopify Functions replace Scripts with WebAssembly execution, all-plan access, and full CI/CD support
- Write Functions in JavaScript/TypeScript (simpler logic) or Rust (complex logic, large carts)
- Per-store limits apply: 5 Discount Functions, 1 Cart Transform, 5 Validation Functions
- Migration path: audit via customizations report → scaffold correct type → rewrite → test → deploy
Start with the audit. Everything else follows from there.
Already migrated? What was the trickiest Script to convert? Drop it in the comments — would love to hear real-world edge cases.
About the author: This post was written by the engineering team at Lucent Innovation, a certified Shopify Plus partner with 10+ years on the platform and 12+ years building and scaling ecommerce stores.


Top comments (0)