Skip to content
Back to skills

Shopify Functions

ASecurity

Build Shopify Functions — serverless WebAssembly extensions for discounts, delivery customization, payment customization, cart validation, cart transforms, and order routing. Use when extending Shopify's backend logic.

  • 39 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added May 29, 2026
ai-agentsjavascripttypescriptrustgojavanodeapibackendperformancedocumentation

Works with

  • api

Security analysis

A100/100

Scanned September 22, 2026

npx -y skills add OrcaQubits/agentic-commerce-skills-plugins --skill shopify-functions --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Shopify Functions?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Shopify Functions
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/orcaqubits-shopify-functions/badge)](https://www.skillsdirectory.com/skills/orcaqubits-shopify-functions)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: shopify-functions
description: >
  Build Shopify Functions — serverless WebAssembly extensions for discounts,
  delivery customization, payment customization, cart validation, cart
  transforms, and order routing. Use when extending Shopify's backend logic.
---

# Shopify Functions (Serverless Wasm Extensions)

## Before writing code

**Fetch live docs**:
1. Fetch `https://shopify.dev/docs/apps/build/functions` for Functions overview
2. Web-search `site:shopify.dev shopify functions input output` for I/O schemas
3. Web-search `site:shopify.dev shopify functions api reference` for function types

## What Are Shopify Functions

Serverless extensions that run on Shopify's infrastructure:
- Written in JavaScript or Rust
- Compiled to **WebAssembly** (Wasm)
- Execute within Shopify's checkout and backend pipeline
- **11 million instruction limit** and **5ms execution time limit** — must be extremely fast
- No network access, no filesystem — pure computation on provided input
- Wasm binary size limit: 256 KB, input JSON size limit: 64 KB

## Function Types

| Type | Purpose | Example |
|------|---------|---------|
| **Discount** | Custom discount logic | Buy X get Y, tiered discounts |
| **Delivery customization** | Modify shipping options | Rename, reorder, hide methods |
| **Payment customization** | Modify payment methods | Hide, reorder, rename gateways |
| **Cart validation** | Block or warn on cart conditions | Quantity limits, product combos |
| **Cart transform** | Modify cart contents | Bundle expansion, auto-add items |
| **Fulfillment constraints** | Control fulfillment behavior | Location priority, restrictions |
| **Order routing** | Direct orders to locations | Closest warehouse, priority |

## Input/Output Model

Functions receive structured JSON input and return structured JSON output:

### Input (simplified)

```json
{
  "cart": {
    "lines": [
      {
        "id": "gid://shopify/CartLine/1",
        "quantity": 2,
        "merchandise": {
          "__typename": "ProductVariant",
          "id": "gid://shopify/ProductVariant/123",
          "product": {
            "id": "gid://shopify/Product/456",
            "hasAnyTag": true
          }
        },
        "cost": {
          "amountPerQuantity": { "amount": "29.99", "currencyCode": "USD" }
        }
      }
    ]
  },
  "discountNode": {
    "metafield": {
      "value": "{\"percentage\": 10}"
    }
  }
}
```

### Output (discount example)

```json
{
  "discounts": [
    {
      "value": { "percentage": { "value": "10.0" } },
      "targets": [
        { "productVariant": { "id": "gid://shopify/ProductVariant/123" } }
      ],
      "message": "10% loyalty discount"
    }
  ],
  "discountApplicationStrategy": "FIRST"
}
```

## Project Structure

```
extensions/my-discount/
├── src/
│   └── run.js          # Function entry point
├── input.graphql       # Defines what data the function receives
├── shopify.extension.toml  # Extension configuration
└── package.json
```

### Configuration (shopify.extension.toml)

```toml
api_version = "<latest-stable>"  # e.g. 2026-07 — Shopify ships a new stable version quarterly
#                                (2026-01 / 2026-04 / 2026-07 / 2026-10) and supports each for ~12 months.
#                                Resolve the current one from https://shopify.dev/docs/api/usage/versioning
#                                before writing this file. Never copy a version literal from an example.

[[extensions]]
name = "My Discount"
handle = "my-discount"
type = "function"

  [extensions.build]
  command = "npm exec -- shopify app function build"
  path = "dist/function.wasm"

  [extensions.ui]
  handle = "my-discount-ui"

  [extensions.input.variables]
  namespace = "my-app"
  key = "discount-config"
```

### Input Query (input.graphql)

Defines what Shopify data the function receives:

```graphql
query Input {
  cart {
    lines {
      id
      quantity
      merchandise {
        ... on ProductVariant {
          id
          product {
            id
            hasAnyTag(tags: ["vip"])
          }
        }
      }
      cost {
        amountPerQuantity {
          amount
          currencyCode
        }
      }
    }
  }
  discountNode {
    metafield(namespace: "my-app", key: "discount-config") {
      value
    }
  }
}
```

## JavaScript Example

```javascript
// src/run.js
export function run(input) {
  const config = JSON.parse(input.discountNode.metafield?.value || '{}');
  const percentage = config.percentage || 0;

  const targets = input.cart.lines
    .filter(line => line.merchandise?.product?.hasAnyTag)
    .map(line => ({
      productVariant: { id: line.merchandise.id }
    }));

  if (targets.length === 0) {
    return { discounts: [], discountApplicationStrategy: "FIRST" };
  }

  return {
    discounts: [{
      value: { percentage: { value: String(percentage) } },
      targets,
      message: `${percentage}% VIP discount`,
    }],
    discountApplicationStrategy: "FIRST",
  };
}
```

## Performance Constraints

- **11 million instruction limit** — function fails with `InstructionCountLimitExceededError` if exceeded
- **5ms execution time limit** — Wasm module is killed if it runs longer
- **Input JSON size limit: 64 KB** — large carts may hit this
- No async operations (no Promises, no setTimeout)
- No network calls (no fetch, no HTTP)
- No filesystem access
- No global state between invocations
- Wasm binary size limit: 256 KB
- Rust is more instruction-efficient than JavaScript — consider Rust for complex logic
- Pre-compute and store config in metafields

## Best Practices

- Keep function logic simple — no complex algorithms
- Use metafields for configuration (read via input query)
- Test with `shopify app function run` locally
- Use TypeScript for type safety (compiled to JS then Wasm)
- Handle edge cases: empty carts, missing metafields, zero quantities
- Return early when no action is needed (return empty discounts array)
- Validate all input — metafield values may be malformed JSON

Fetch the Shopify Functions documentation for exact I/O schemas, supported function types, and API version requirements before implementing.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…