Shopify App and Extension Development
Overview
Shopify's app ecosystem enables developers to extend every aspect of the commerce platform -- from the admin dashboard and online storefront to checkout, fulfillment, and payments. The ecosystem supports three primary app types:
- Public apps -- Listed on the Shopify App Store, installable by any merchant. Require Partner Dashboard submission and review. Must implement OAuth for authentication and mandatory GDPR webhooks.
- Custom apps -- Built for a single merchant or organization. Created directly in the store admin or via the Partner Dashboard. Provide API access tokens without the full OAuth flow. Not listed on the App Store.
- Private apps (legacy) -- Deprecated in favor of custom apps. Existing private apps continue to function, but new private apps cannot be created.
Shopify apps are web applications hosted externally (not on Shopify infrastructure) that communicate with Shopify through APIs and embed into the Shopify Admin via App Bridge. Extensions, by contrast, run on Shopify infrastructure and extend specific surfaces like checkout, admin pages, and themes.
The modern Shopify development stack centers on Remix as the default app framework, App Bridge 4.x for embedding, and a rich extension model for customizing merchant-facing surfaces without requiring full app installations.
App Architecture
The default Shopify app template uses Remix (React-based full-stack framework) with the @shopify/shopify-app-remix adapter handling authentication, session management, and API client creation.
Key Architectural Components
- shopify.app.toml -- The app manifest defining configuration, scopes, extensions, and webhooks. This is the single source of truth for app configuration, deployed via
shopify app deploy. - App Bridge 4.x -- The library that embeds the app within the Shopify Admin. Handles session token exchange, navigation, modal dialogs, resource pickers, and toast notifications. Version 4.x is CDN-loaded and requires no npm package.
- Session token authentication -- Replaces cookies for embedded apps. Shopify issues a JWT session token via App Bridge; the app server verifies it on each request. The
@shopify/shopify-app-remixpackage handles this automatically. - OAuth flow -- Required for public apps. The merchant installs the app, Shopify redirects to the app's auth callback with an authorization code, and the app exchanges it for an access token. Offline tokens persist; online tokens expire.
The Remix app structure follows conventions: app/routes/ contains page routes, extensions/ holds extension source code, and shopify.server.ts initializes the Shopify API client with authentication middleware.
For complete details on app structure, OAuth, session management, and App Bridge integration, see references/app-architecture.md.
Development Setup
Shopify CLI 3.x is the primary tool for creating, developing, and deploying Shopify apps and extensions.
Getting Started
- Install Shopify CLI:
npm install -g @shopify/cli - Create a new app:
shopify app init - Create a development store in the Partner Dashboard (or use an existing one)
- Start local development:
shopify app dev
The shopify app dev command creates a tunnel (Cloudflare by default), configures the app URLs on the Partner Dashboard, installs the app on the dev store, and starts the local server. Hot module replacement is available for the Remix app; extensions reload automatically on file changes.
Configuration
The shopify.app.toml file defines the app name, client ID, scopes, webhooks, and extensions. Environment variables (API keys, secrets) are managed through .env files locally and through the hosting provider in production.
For CLI commands, dev store setup, tunneling configuration, and deployment procedures, see references/shopify-cli-and-dev.md.
Extension Model
Shopify's extension model allows apps to inject functionality directly into Shopify surfaces without iframes. Extensions run on Shopify infrastructure and are sandboxed for security. The major extension types are:
Checkout UI Extensions
React-based components rendered within the Shopify checkout flow. Target specific render points (cart line items, shipping options, payment method, order summary) using extension targets like purchase.checkout.block.render. Built with a restricted set of Checkout UI components (Banner, BlockStack, Button, Text, etc.) for a consistent checkout experience. These extensions can read and modify checkout data through hooks like useApplyCartLinesChange and useShippingAddress.
For complete checkout extension documentation, see references/checkout-extensions.md.
Admin Extensions
Extend the Shopify Admin with custom blocks, actions, and navigation links. Admin action extensions create modal interfaces triggered from resource pages (orders, products, customers). Admin block extensions add persistent content sections to resource detail pages. Built with the Polaris design system for visual consistency.
For admin extension patterns and Polaris integration, see references/admin-extensions.md.
Theme App Extensions
Inject app functionality into Online Store 2.0 themes without editing theme code. App blocks appear in theme sections; app embed blocks load globally (analytics, chat widgets). Developers write Liquid, CSS, and JavaScript. Merchants add and configure blocks through the theme editor.
For theme extension development, Liquid patterns, and Storefront API usage, see references/storefront-and-themes.md.
Shopify Functions
Server-side logic running on Shopify infrastructure for backend customizations. Compile to WebAssembly (Wasm) from Rust, JavaScript, or TypeScript. Support discount calculations (order, product, shipping discounts), payment customizations, delivery customizations, cart transforms, and fulfillment constraints. Receive input via GraphQL queries and return structured output.
For Shopify Functions details, see the Functions section in references/checkout-extensions.md.
Web Pixel Extensions
Client-side tracking extensions that run in a sandboxed iframe on the storefront. Subscribe to standard e-commerce events (page view, product viewed, added to cart, checkout completed) and forward data to analytics providers. Respect customer privacy consent signals.
API Overview
Shopify provides several APIs for different use cases:
| API | Protocol | Authentication | Primary Use Cases |
|---|---|---|---|
| Admin API | GraphQL + REST | OAuth access token | Product management, order processing, customer data, inventory, metafields |
| Storefront API | GraphQL | Storefront access token (public) | Headless commerce, custom storefronts, buy buttons, product browsing |
| Customer Account API | GraphQL | Customer access token | Customer self-service, order history, account management |
| Payments Apps API | GraphQL | App access token | Payment processing, credit card, offsite, and custom payment methods |
| Checkout Branding API | GraphQL | Admin access token | Checkout visual customization |
Admin API (GraphQL and REST)
The GraphQL Admin API is the primary API for app development. It uses versioned endpoints (e.g., 2025-01) with a quarterly release cadence. Key resource areas include products, orders, customers, collections, inventory, fulfillments, and metafields. Rate limiting uses calculated query cost rather than simple request counts.
The REST Admin API remains available for resources not yet in GraphQL and for simple CRUD operations. Prefer GraphQL for complex queries, bulk operations, and accessing newer features.
For detailed Admin API patterns, queries, mutations, pagination, bulk operations, and rate limiting, see references/graphql-admin-api.md.
Payment and Fulfillment APIs
The Payments Apps API enables building payment gateways that integrate natively with Shopify checkout. It supports credit card, offsite, and manual payment methods with session-based lifecycle management.
For payment app development, see references/payment-apps.md.
For fulfillment services, carrier APIs, and shipping integration, see references/fulfillment-and-shipping.md.
Key Patterns
Authenticated Admin API Calls
In a Remix app, authenticated API calls follow a standard pattern. The authenticate.admin(request) function verifies the session token, retrieves the access token, and returns a preconfigured GraphQL client:
export async function loader({ request }: LoaderFunctionArgs) {
const { admin } = await authenticate.admin(request);
const response = await admin.graphql(`
query { shop { name currencyCode } }
`);
const data = await response.json();
return json({ shop: data.data.shop });
}
Billing API
Monetize apps through Shopify's billing system. Create recurring charges (appSubscriptionCreate), usage charges, or one-time charges. Shopify handles payment collection and pays developers through the Partner program. Always test billing in development stores where charges are simulated.
App Proxy
Route requests from the storefront through Shopify to the app server. The app receives the request with Shopify's signature for verification. Use app proxies for customer-facing features that need app server logic (loyalty points display, custom product configurators, wishlists).
Webhooks
Subscribe to events (order created, product updated, app uninstalled) via the CLI configuration or API. Mandatory GDPR webhooks (customers/data_request, customers/redact, shop/redact) must be implemented for App Store approval. Verify webhook signatures with HMAC-SHA256.
For webhook implementation patterns, GDPR compliance, and event handling, see references/webhooks-and-gdpr.md.
Anti-Patterns
Avoid these common mistakes when developing Shopify apps:
- Using REST when GraphQL is available -- GraphQL returns only requested fields, supports nested queries, and provides bulk operations. REST is appropriate only for simple operations or resources not yet in GraphQL. Mixing both APIs unnecessarily increases maintenance burden.
- Ignoring rate limits -- The Admin API uses calculated query cost. A single complex GraphQL query can consume the entire throttle bucket. Monitor the
X-Shopify-Shop-Api-Call-Limitheader (REST) orthrottleStatusin GraphQL responses. Implement exponential backoff on 429 responses. - Non-idempotent webhook handlers -- Shopify may deliver webhooks more than once. Track processed webhook IDs and skip duplicates. Design handlers so that processing the same webhook twice produces the same result.
- Missing GDPR webhooks -- Apps submitted to the Shopify App Store must implement all three mandatory GDPR endpoints. Missing them is a guaranteed rejection reason.
- Hardcoding API versions -- Use the current stable version and update quarterly. Stale versions are eventually removed, breaking the app. Subscribe to the developer changelog for version deprecation notices.
- Storing access tokens insecurely -- Encrypt tokens at rest. Never log tokens. Use the session storage adapters provided by
@shopify/shopify-app-session-storage-*packages. - Polling instead of subscribing -- Use webhooks and bulk operations instead of polling the API for changes. Polling wastes rate limit budget and creates unnecessary latency.
- Ignoring pagination -- All list endpoints return paginated results. Always handle pagination with cursor-based connections in GraphQL or Link headers in REST. Never assume all results fit in one response.
App Store Publishing
Publishing to the Shopify App Store requires meeting listing requirements, implementing mandatory webhooks, and passing the app review process. The review evaluates security, performance, UX quality, and compliance.
For listing requirements, review process, common rejection reasons, and billing integration, see references/app-store-publishing.md.
Example Files
- examples/basic-app/shopify.app.toml -- Minimal Shopify app configuration file
- examples/basic-app/app-routes-example.tsx -- Remix route with authenticated Admin API call
- examples/checkout-extension/checkout-example.tsx -- Checkout UI extension with banner component
Reference Files
- App Architecture -- Remix app structure, OAuth, session tokens, App Bridge 4.x, scopes, session management
- Shopify CLI and Development -- CLI commands, dev store setup, tunneling, environment configuration, deployment
- GraphQL Admin API -- Queries, mutations, pagination, bulk operations, rate limiting, metafields, REST fallback
- Storefront and Themes -- Theme App Extensions, Online Store 2.0, Liquid, Storefront API, app-owned metafields
- Checkout Extensions -- Checkout UI extensions, extension targets, components, Shopify Functions, post-purchase
- Admin Extensions -- Admin actions, blocks, links, navigation, Polaris design system, embedded app patterns
- Payment Apps -- Payments Apps API, credit card, offsite, custom methods, session lifecycle, sandbox testing
- Fulfillment and Shipping -- Fulfillment services, carrier APIs, delivery profiles, tracking, local delivery
- Webhooks and GDPR -- Webhook subscriptions, GDPR compliance, HMAC verification, event topics, retry policies
- App Store Publishing -- Listing requirements, review process, billing API, rejection reasons, versioning