Shopify Functions: The Complete Guide to Checkout Customization
Shopify Functions replaced Scripts with better performance, more extension points, and a cleaner developer experience. Here's everything you need to know.
If you've used Shopify Scripts, you know the pain: Ruby-based, limited to Plus merchants, deployed through a clunky UI, and restricted to a few checkout hooks. Shopify Functions are the successor — and they're a massive upgrade. Functions run as WASM modules on Shopify's edge infrastructure, support multiple extension points, and work for all merchants (not just Plus). Let's dive in.
What Are Shopify Functions?
A Shopify Function is a small, deterministic program that runs on Shopify's infrastructure during specific commerce operations. You write the logic, define the input/output schema in GraphQL, compile to WASM, and deploy. When a merchant's customer hits checkout, your Function executes with the order data as input and returns modifications (discounts, payment rules, delivery options) as output. Execution time is budgeted at 10ms — which sounds tight until you realize WASM is incredibly fast.
Extension Points
Functions can hook into four areas: (1) Discount functions — create custom discount logic like BOGO, tiered pricing, or customer-segment-specific deals. (2) Payment customization — hide, reorder, or rename payment methods based on cart contents, customer tags, or any logic. (3) Delivery customization — modify shipping rates, add surcharges, or restrict delivery options. (4) Order routing — determine which fulfillment center handles an order based on inventory, location, or custom rules. Each extension point has a specific GraphQL input/output schema.
Writing Your First Function
Functions can be written in Rust (recommended for performance) or JavaScript. The Shopify CLI scaffolds the project: `npm run shopify app generate extension` and choose your function type. The generated code includes an `input.graphql` file (defining what data your Function receives), a `run.ts` or `run.rs` file (your logic), and a configuration file. The input query determines what cart data, customer data, and shop data is available to your Function at runtime.
The Input/Output Contract
This is the most important concept: your Function's behavior is entirely defined by its GraphQL input query and output type. The input query runs against Shopify's store data and provides your Function with exactly the data it needs — no more, no less. The output type defines what your Function can modify. For a discount function, the output is a discount application (percentage, fixed amount, or custom). For payment customization, the output is a list of operations (hide, rename, reorder) on payment methods.
Testing and Deployment
The Shopify CLI includes a local testing environment. You can run your Function locally with sample input data, verify the output, and iterate quickly. Once ready, `npm run shopify app deploy` compiles your Function to WASM and uploads it to Shopify. The Function is then associated with an app installation via the Admin API. Version management is built in — you can deploy updates without downtime, and Shopify handles the rollout.
Best Practices
Keep Functions small and focused — one Function per business rule. Avoid complex loops or heavy computation (you have a 10ms budget). Use the `input.graphql` query to request only the data you need — over-fetching slows down execution. Handle edge cases: empty carts, missing customer data, zero-quantity items. And always test with realistic cart scenarios before deploying. The ShopForge scaffold includes pre-built Function templates for discounts and checkout extensions that you can use as starting points.