Agent skill

shopify

Shopify app and storefront development. Use when writing, reviewing, or scaffolding Shopify apps (Remix/React Router), Hydrogen storefronts, theme app extensions, checkout UI extensions, Shopify Functions, or any code that touches Shopify APIs (Admin GraphQL, Storefront, App Bridge, Polaris). Triggers on shopify.app.toml, @shopify/* imports, Polaris components, Shopify CLI commands, Hydrogen/Oxygen, metafields/metaobjects, webhooks, or any Shopify development task.

Stars 2
Forks 0

Install this agent skill to your Project

npx add-skill https://github.com/JoaquinCampo/Skills/tree/main/shopify

SKILL.md

Shopify Development (2026)

Comprehensive guide for building Shopify apps, extensions, Hydrogen storefronts, and integrations using current best practices.

DevMCP Server

Shopify provides an official MCP server for AI-assisted development. If not already configured:

bash
# Claude Code
claude mcp add --transport stdio shopify-dev-mcp -- npx -y @shopify/dev-mcp@latest

The DevMCP server provides tools to search Shopify docs, explore API schemas (Admin GraphQL, Storefront, Functions, Liquid, Polaris, POS UI Extensions), and get up-to-date answers. Use it for API field lookups and schema exploration.

Stack & Tooling

Layer Current (2026)
App framework React Router (formerly Remix) via @shopify/shopify-app-react-router
Scaffold shopify app init → React Router template
CLI @shopify/cli — init, dev, deploy, generate extension
UI (embedded apps) Polaris Web Components (not Polaris React — deprecated)
UI (extensions) Polaris Web Components + Preact (not React) — 64KB bundle limit
App Bridge CDN v4 — https://cdn.shopify.com/shopifycloud/app-bridge.js
APIs Admin GraphQL (primary), Storefront GraphQL, Functions API
Custom data Metafields + Metaobjects via TOML or GraphQL
Headless Hydrogen + Oxygen (React Router v7, Vite, edge rendering)
Functions Wasm — Rust (recommended) or JavaScript (Javy)
Config shopify.app.toml — single source of truth

Critical:

  • REST Admin API is legacy since October 1, 2024. As of April 1, 2025, all new public apps must use GraphQL Admin API exclusively.
  • Shopify Scripts: no editing/publishing after April 15, 2026; all scripts stop executing June 30, 2026. Migrate to Functions now.
  • Polaris React (@shopify/polaris) is deprecated (maintenance mode only). Use Polaris Web Components.
  • UI Extensions (checkout, admin, POS) must use Preact (not React) for API 2025-10+. 64KB bundle size limit enforced at deploy.

Scaffolding

bash
shopify app init                        # Interactive — choose React Router template
shopify app dev                         # Local dev with tunnel + hot reload
shopify app generate extension          # Add extensions (checkout UI, functions, theme, admin, POS)
shopify app deploy                      # Deploy app version (config + all extensions)

Directory Structure (React Router template)

my-app/
├── shopify.app.toml          # App config, scopes, webhooks, metaobjects
├── app/
│   ├── entry.server.tsx      # Server entry
│   ├── root.tsx              # Root layout
│   ├── routes/
│   │   ├── app.tsx           # Authenticated layout (App Bridge + Polaris)
│   │   ├── app._index.tsx    # App home page
│   │   └── webhooks.tsx      # Webhook handler
│   └── shopify.server.ts     # shopifyApp() config — auth, session storage
├── extensions/               # All extensions live here
│   ├── checkout-ui/
│   ├── theme-extension/
│   └── my-function/
├── prisma/
│   └── schema.prisma         # Session table (required)
└── package.json

Authentication & Sessions

  • App Bridge v4 (CDN) automatically handles session tokens — no manual JWT fetch needed. The manual setup guide is for legacy App Bridge 2.0 only.
  • Embedded apps use session tokens (JWT, 1-minute lifetime). Third-party cookies are blocked by browsers.
  • @shopify/shopify-app-react-router (recommended) or @shopify/shopify-app-remix (v4, still works) handle OAuth + token exchange automatically.
  • Session storage: Prisma adapter (@shopify/shopify-app-session-storage-prisma) — the Session table is required.
  • Use authenticate.admin(request) in loaders/actions for authenticated Admin API access.
  • Use authenticate.public.checkout(request) for checkout extension requests.
  • Never expose Admin API tokens in client-side code.
  • Use offline access tokens for bulk operations and webhooks (online tokens expire in 24h).
typescript
// app/shopify.server.ts
import { shopifyApp } from "@shopify/shopify-app-react-router";
import { PrismaSessionStorage } from "@shopify/shopify-app-session-storage-prisma";
import prisma from "./db.server";

const shopify = shopifyApp({
  sessionStorage: new PrismaSessionStorage(prisma),
  // API key, secret, scopes, and app URL are read from
  // shopify.app.toml + environment variables automatically
});
export default shopify;
export const authenticate = shopify.authenticate;

// In a route loader:
export async function loader({ request }: LoaderFunctionArgs) {
  const { admin } = await authenticate.admin(request);
  const response = await admin.graphql(`{ shop { name } }`);
  const { data } = await response.json();
  return { shopName: data.shop.name };
}

Migration note: If on @shopify/shopify-app-remix, migrate to @shopify/shopify-app-react-router — see migration guide.

Polaris Web Components (NOT Polaris React)

Polaris React is deprecated. Use Polaris Web Components — framework-agnostic custom HTML elements.

Setup

html
<head>
  <meta name="shopify-api-key" content="%SHOPIFY_API_KEY%" />
  <script src="https://cdn.shopify.com/shopifycloud/app-bridge.js"></script>
  <script src="https://cdn.shopify.com/shopifycloud/polaris.js"></script>
</head>

Usage in React (App Home)

tsx
function ProductForm() {
  const [name, setName] = useState("");
  return (
    <s-page title="New Product">
      <s-layout>
        <s-layout-section>
          <s-card>
            <s-form-layout>
              <s-text-field
                label="Product name"
                value={name}
                onInput={(e) => setName(e.currentTarget.value)}
                required
              />
              <s-button variant="primary" type="submit">Save</s-button>
            </s-form-layout>
          </s-card>
        </s-layout-section>
      </s-layout>
    </s-page>
  );
}

Key Patterns

  • Elements are prefixed with s- (e.g., s-card, s-button, s-badge, s-data-table).
  • Use onInput for real-time updates, onChange for on-blur/enter validation.
  • All form values are strings — parse numbers/booleans yourself.
  • tone applies semantic color (critical, success, info); variant sets visual weight (primary, secondary).
  • Links with target="auto" auto-detect internal (_self) vs external (_blank).
  • Do not apply custom CSS to Polaris components — they have built-in design system styling.

Navigation (App Bridge)

tsx
// Handle Shopify navigation events in Remix/React Router
useEffect(() => {
  const handler = (event) => {
    const href = event.target.getAttribute("href");
    if (href) navigate(href);
  };
  document.addEventListener("shopify:navigate", handler);
  return () => document.removeEventListener("shopify:navigate", handler);
}, [navigate]);

Use <s-navigation-menu> for sidebar nav. Use shopify.navigate() for programmatic navigation. Never use <a> tags or redirect from react-router in embedded apps — use Link from react-router or the redirect helper from authenticate.admin.

Admin GraphQL API

Query Patterns

typescript
// Simple query
const response = await admin.graphql(`
  query {
    products(first: 10) {
      edges {
        node { id title handle }
      }
    }
  }
`);

// Mutation with variables
const response = await admin.graphql(`
  mutation createProduct($input: ProductInput!) {
    productCreate(input: $input) {
      product { id title }
      userErrors { field message }
    }
  }
`, { variables: { input: { title: "New Product" } } });

// Always check userErrors
const { data } = await response.json();
if (data.productCreate.userErrors.length > 0) {
  throw new Error(data.productCreate.userErrors[0].message);
}

Rate Limiting

  • Admin GraphQL uses calculated query cost (cost points, not request count).
  • Complex queries with nested connections cost more points.
  • Use cursor-based pagination for large datasets.
  • For bulk data: use bulk operations (bulkOperationRunQuery / bulkOperationRunMutation) — up to 5 concurrent queries and 5 concurrent mutations per shop in API 2026-01+ (previously 1 each).
  • Use offline access tokens for bulk operations (online tokens expire before completion).

API Version

Always pin to a stable version (e.g., 2026-01). Set in shopify.app.toml:

toml
[webhooks]
api_version = "2026-01"

Storefront API

  • For all customer-facing data: products, collections, cart, checkout.
  • No rate limits on request count — scales for buyer traffic surges.
  • Requires Storefront access token (public, safe for client-side).
  • Use in Hydrogen storefronts, mobile apps, or headless frontends.

Metafields & Metaobjects

When to Use Which

Use Case Tool
Add custom field to existing resource (product, order, customer) Metafield
Create standalone reusable structured data Metaobject
App-internal data model Metaobject with $app: prefix in TOML

App-Owned Metafields (TOML)

toml
# shopify.app.toml — auto-created on `shopify app dev`
[[metaobjects]]
type = "$app:qrcode"

  [metaobjects.access]
  admin = "merchant_read_write"
  storefront = "public_read"

  [[metaobjects.fields]]
  key = "title"
  type = "single_line_text_field"
  name = "Title"
  required = true

  [[metaobjects.fields]]
  key = "product"
  type = "product_reference"
  name = "Product"

Merchant-Owned Metafields (GraphQL)

graphql
mutation {
  metafieldDefinitionCreate(definition: {
    name: "Warranty Info"
    namespace: "custom"       # NOT $app — merchant-owned
    key: "warranty_info"
    type: "multi_line_text_field"
    ownerType: PRODUCT
    access: { storefront: PUBLIC_READ }
  }) {
    createdDefinition { name namespace key }
  }
}
  • $app namespace = app-owned (read-only in admin by default).
  • custom or other namespaces = merchant-owned.
  • Use TOML for app-owned; GraphQL for merchant-owned.

Webhooks

Configuration (TOML)

toml
[webhooks]
api_version = "2026-01"

[[webhooks.subscriptions]]
topics = ["orders/create", "products/update"]
uri = "/webhooks"

[[webhooks.subscriptions]]
compliance_topics = ["customers/data_request", "customers/redact", "shop/redact"]
uri = "https://app.example.com/webhooks"

Mandatory Compliance (Required for App Store)

Every public app must handle these three webhooks:

  1. customers/data_request — respond with customer data you store
  2. customers/redact — delete customer personal data
  3. shop/redact — delete all shop data after uninstall

Validate HMAC on every webhook. Return 401 for invalid HMAC, 200 for valid.

GraphQL Subscriptions

graphql
mutation {
  webhookSubscriptionCreate(
    topic: ORDERS_CREATE
    webhookSubscription: {
      callbackUrl: "https://app.example.com/webhooks"
      format: JSON
    }
  ) {
    webhookSubscription { id }
    userErrors { field message }
  }
}

Shopify Functions (Wasm)

Extend Shopify backend logic (discounts, validation, delivery, payment customization) as sandboxed WebAssembly modules.

Language Choice

  • Rust: 3x faster than JS. Required for public apps with complex logic or high line-item counts. Stays within instruction count limits.
  • JavaScript (via Javy → Wasm): Viable for prototyping and simple logic (<5ms realistic cases). Lower barrier to entry.

Execution Order in Checkout

  1. Cart Transform → 2. Discount (cart lines) → 3. Fulfillment/Order Routing → 4. Delivery Customization → 5. Discount (delivery) → 6. Payment Customization → 7. Cart Validation

Scaffold & Build

bash
shopify app generate extension    # Choose function type
shopify app function schema       # Regenerate GraphQL schema
shopify app function run          # Test locally

Structure

extensions/my-discount/
├── shopify.extension.toml     # Extension config (target, API version)
├── src/
│   ├── run.graphql            # Input query — what data the function receives
│   └── run.rs (or run.js)     # Function logic
├── schema.graphql             # Generated API schema
└── Cargo.toml (or package.json)

Performance: Functions run during checkout — delays block purchases. Minimize instruction count. Avoid unnecessary data in run.graphql.

Extensions

Types

Extension Purpose
theme_app_extension Liquid blocks/snippets in Online Store themes
checkout_ui_extension Custom UI at checkout extension points
admin_action Dropdown actions on admin resource pages
admin_block Embedded blocks on admin resource pages
pos_ui_extension POS interface extensions
Functions Backend logic (discounts, delivery, validation, payments)

Theme App Extensions

Required for all new App Store apps (replaces manual theme code editing).

extensions/theme-extension/
├── shopify.extension.toml
├── blocks/
│   └── rating.liquid
├── snippets/
├── assets/
└── locales/

Checkout UI Extensions

20+ extension points (e.g., Checkout::Dynamic::Render). Use Polaris Web Components. Keep lightweight — mobile-first.

Critical: React is deprecated for UI extensions as of API 2025-10. Must use Preact for any API version 2025-10+. Vanilla React + ui-react package exceeds the 64KB bundle limit.

toml
# shopify.extension.toml
api_version = "2026-01"

[[extensions]]
name = "my-checkout-ext"
handle = "my-checkout-ext"
type = "ui_extension"
json
// package.json dependencies for UI extensions
{
  "dependencies": {
    "preact": "^10.10.x",
    "@preact/signals": "^2.3.x",
    "@shopify/ui-extensions": "2026.1.x"
  }
}
json
// tsconfig.json for Preact JSX
{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "preact"
  }
}

Hydrogen & Oxygen (Headless)

Stack

  • Hydrogen: React framework (React Router v7 + Vite) with Storefront API utilities, streaming SSR, granular caching.
  • Oxygen: Shopify's edge runtime (based on Cloudflare workerd). Multiple preview environments. CI/CD via GitHub.
  • Vite-first: Legacy Remix compiler no longer supported — must use Vite.

Key Patterns

typescript
// Caching — be explicit
const { storefront } = await context.storefront.query(PRODUCT_QUERY, {
  cache: CacheLong(),    // or CacheShort(), CacheNone(), CacheCustom()
});

// Streaming for performance
export default function Product() {
  return (
    <Suspense fallback={<ProductSkeleton />}>
      <Await resolve={recommendedProducts}>
        {(products) => <ProductGrid products={products} />}
      </Await>
    </Suspense>
  );
}

AI Integration (2026)

Hydrogen on Oxygen supports Storefront MCP — build AI agents into storefronts for personalized recommendations and checkout guidance using real-time Storefront API data.

App Store Submission Checklist

  1. GraphQL only — no REST API calls
  2. Session tokens — no cookie-based auth
  3. Mandatory compliance webhooks — all three implemented and HMAC-validated
  4. Theme app extensions — no manual theme code injection
  5. Polaris Web Components — consistent admin UI
  6. Performance — must not reduce Lighthouse score by >10 points
  7. Privacy — GDPR/CCPA compliant, data handling documented
  8. Credentials — provide valid test credentials with full feature access
  9. Screencast — complete walkthrough of setup + functionality
  10. No Shopify trademarks in app icon/banner/screenshots
  11. Review timeline: 7–14 days. Statuses: Draft → Submitted → Reviewed → Published.

Common Pitfalls

  • Using <a> or bare redirect() in embedded apps (breaks iframe). Use Link from react-router or the redirect helper from authenticate.admin.
  • Using Polaris React (@shopify/polaris) instead of Polaris Web Components — deprecated, maintenance-only.
  • Using React in UI extensions targeting API 2025-10+ — must use Preact (64KB bundle limit).
  • Exposing Admin API tokens client-side.
  • Using REST API in new apps (legacy since Oct 2024; blocked for new public apps since April 2025).
  • Not validating webhook HMAC.
  • Using online access tokens for bulk operations (they expire in 24h).
  • Heavy checkout extensions that slow mobile performance.
  • Not handling userErrors in GraphQL mutations.
  • Missing the $app: namespace prefix for app-owned metaobjects.
  • Forgetting to run shopify app function schema after changing API version.
  • Using @shopify/shopify-app-remix for new projects instead of @shopify/shopify-app-react-router.

Expand your agent's capabilities with these related and highly-rated skills.

JoaquinCampo/Skills

sparse-retrieval-eval

Evaluate sparse retrieval models on standard IR benchmarks (BEIR, MIRACL, mMARCO). Covers all IR metrics (nDCG@k, Recall@k, MAP, MRR), dataset loading, sparse corpus encoding to CSR matrices, IDF-weighted retrieval, caching, and result interpretation. Triggers on: evaluate retrieval, BEIR benchmark, nDCG, recall@k, sparse retrieval evaluation, MIRACL evaluation, information retrieval metrics, IR evaluation, search quality metrics.

2 0
Explore
JoaquinCampo/Skills

wandb-plot

Download and generate plots from Weights & Biases runs. Use when you need to: - List projects you have access to - List runs in a W&B project - Inspect available metrics for a run - Download existing plot images from a run - Generate line plots from metric history (loss, accuracy, etc.)

2 0
Explore
JoaquinCampo/Skills

go

Go engineering best practices and idioms. This skill should be used when writing, reviewing, or refactoring Go code. Triggers on any .go file work, Go module operations, go test, go build, go run, go vet, go generate, or when the user mentions Go, golang, goroutines, channels, context, Go interfaces, Go error handling, Go testing, or Go concurrency. ALWAYS use this skill when Go code is involved, even for simple functions.

2 0
Explore
JoaquinCampo/Skills

fastapi

FastAPI best practices and conventions. Use when working with FastAPI APIs and Pydantic models for them. Keeps FastAPI code clean and up to date with the latest features and patterns, updated with new versions. Write new code or refactor and update old code.

2 0
Explore
JoaquinCampo/Skills

kvpress

kvpress (NVIDIA) KV-cache compression for HuggingFace LLMs. Use when: kvpress imports, compression_ratio, press(model) context managers, StreamingLLMPress, SnapKVPress, ExpectedAttentionPress, TOVAPress, KnormPress, KV-cache eviction, token pruning during generation, or attention sink methods.

2 0
Explore
JoaquinCampo/Skills

plantuml

Create, edit, and render PlantUML diagrams. Triggers on: architecture diagrams, flowcharts, sequence diagrams, data models, state machines, visual documentation.

2 0
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results