Help us improve
Share bugs, ideas, or general feedback.
From shopify-pack
Sets up local Shopify app development with Shopify CLI scaffolding, ngrok tunneling for webhooks, hot reload, and Vitest testing.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin shopify-packHow this skill is triggered — by the user, by Claude, or both
Slash command
/shopify-pack:shopify-local-dev-loopThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Set up a fast, reproducible local development workflow using Shopify CLI, ngrok tunneling for webhooks, and Vitest for testing against the Shopify API.
Onboards Shopify developers: detects IDE/client, installs Shopify CLI and AI toolkit plugin, guides on building apps/themes, creating dev stores/partner accounts.
Sets up Shopify dev environment: CLI install/auth, Partner account, dev stores, env vars, structures for Remix apps, Liquid themes, Hydrogen storefronts.
Creates minimal Shopify app querying products and store info via GraphQL Admin API. Use for new integrations, setup testing, or learning API patterns.
Share bugs, ideas, or general feedback.
Set up a fast, reproducible local development workflow using Shopify CLI, ngrok tunneling for webhooks, and Vitest for testing against the Shopify API.
shopify-install-auth setupnpm install -g @shopify/cli)# Create a new Remix-based Shopify app (recommended)
shopify app init
# Or scaffold manually
mkdir my-shopify-app && cd my-shopify-app
npm init -y
npm install @shopify/shopify-api @shopify/shopify-app-remix \
@shopify/app-bridge-react @remix-run/node @remix-run/react
my-shopify-app/
├── app/
│ ├── routes/
│ │ ├── app._index.tsx # Main app page
│ │ ├── app.products.tsx # Products management
│ │ ├── auth.$.tsx # OAuth callback
│ │ └── webhooks.tsx # Webhook handler
│ ├── shopify.server.ts # Shopify API client setup
│ └── root.tsx
├── extensions/ # Theme app extensions
├── shopify.app.toml # App configuration
├── .env # Local secrets (git-ignored)
├── .env.example # Template for team
└── package.json
# shopify.app.toml — central app configuration
name = "My App"
client_id = "your_api_key_here"
[access_scopes]
scopes = "read_products,write_products,read_orders"
[auth]
redirect_urls = [
"https://localhost/auth/callback",
"https://localhost/auth/shopify/callback",
]
[webhooks]
api_version = "2024-10"
[webhooks.subscriptions]
# Mandatory GDPR webhooks
[[webhooks.subscriptions]]
topics = ["customers/data_request"]
uri = "/webhooks"
[[webhooks.subscriptions]]
topics = ["customers/redact"]
uri = "/webhooks"
[[webhooks.subscriptions]]
topics = ["shop/redact"]
uri = "/webhooks"
# Shopify CLI handles ngrok tunnel + OAuth automatically
shopify app dev
# This will:
# 1. Start your app on localhost:3000
# 2. Create an ngrok tunnel
# 3. Update your app URLs in Partner Dashboard
# 4. Open your app in the dev store admin
# 5. Hot reload on file changes
// tests/shopify-client.test.ts
import { describe, it, expect, vi, beforeEach } from "vitest";
// Mock the Shopify API client
vi.mock("@shopify/shopify-api", () => ({
shopifyApi: vi.fn(() => ({
clients: {
Graphql: vi.fn().mockImplementation(() => ({
request: vi.fn().mockResolvedValue({
data: {
products: {
edges: [
{ node: { id: "gid://shopify/Product/1", title: "Test Product" } },
],
},
},
}),
})),
},
session: {
customAppSession: vi.fn(() => ({ shop: "test.myshopify.com" })),
},
})),
}));
describe("Shopify Integration", () => {
it("should fetch products", async () => {
// Test your product-fetching logic here
});
it("should handle GraphQL errors", async () => {
// Test error handling
});
});
{
"scripts": {
"dev": "shopify app dev",
"build": "remix vite:build",
"test": "vitest",
"test:watch": "vitest --watch",
"lint": "eslint app/",
"shopify": "shopify",
"deploy": "shopify app deploy"
}
}
# Open the Shopify GraphiQL explorer for your store
# Navigate to: https://your-store.myshopify.com/admin/api/2024-10/graphql.json
# Use the Shopify Admin GraphiQL app (install from admin)
# Or use curl to test queries directly:
curl -X POST \
"https://your-store.myshopify.com/admin/api/2024-10/graphql.json" \
-H "Content-Type: application/json" \
-H "X-Shopify-Access-Token: shpat_xxx" \
-d '{"query": "{ shop { name } }"}'
| Error | Cause | Solution |
|---|---|---|
Could not find a Shopify partner organization | CLI not logged in | Run shopify auth login |
Port 3000 already in use | Another process on port | Kill process or use --port 3001 |
Tunnel connection failed | ngrok issues | Check ngrok status or use --tunnel-url |
App not installed on store | First time setup | Open the URL CLI provides, accept install |
SHOPIFY_API_KEY not set | Missing .env | Copy from .env.example and fill in values |
// Enable verbose request logging in development
import { LogSeverity } from "@shopify/shopify-api";
const shopify = shopifyApi({
// ... other config
logger: {
level: LogSeverity.Debug, // Logs all requests/responses
httpRequests: true,
timestamps: true,
},
});
// scripts/seed-dev-store.ts — create test products
async function seedStore(client: any) {
const products = [
{ title: "Test Widget", productType: "Widget", vendor: "Dev" },
{ title: "Test Gadget", productType: "Gadget", vendor: "Dev" },
];
for (const product of products) {
await client.request(`
mutation { productCreate(product: {
title: "${product.title}",
productType: "${product.productType}",
vendor: "${product.vendor}"
}) {
product { id title }
userErrors { field message }
}}
`);
}
}
See shopify-sdk-patterns for production-ready code patterns.