Building a Shopify app opens the door to a merchant base of millions. Whether you want to solve a workflow gap, extend store functionality, or launch a SaaS business, a well-built app can reach stores across the globe. But the path from idea to live listing involves several moving parts: authentication, API access, webhooks, hosting, and review.

This guide walks you through the full journey. You will learn how to build a Shopify app from scratch, test it locally, and deploy it to production. Let us get started.

What Is a Shopify App and Why Build One?

A Shopify app is a standalone web application that connects to a merchant’s store through Shopify’s APIs. It can read and write store data, add features to the admin, extend the checkout, or run background jobs.

There are three main app types:

App Type Best For Distribution
Public app Multiple merchants, App Store listing Shopify App Store
Custom app A single merchant or client Direct install link
Plus/Partner app Enterprise clients, advanced needs Custom agreement

Public apps earn revenue through the App Store. Custom apps serve one store and skip the review process. Most of this tutorial applies to both, with notes where they differ.

Prerequisites Before You Start

Before you write a line of code, set up your tools. You will need:

  • A Shopify Partner account (free to create)
  • A development store for testing
  • Node.js 18 or later installed
  • Basic knowledge of JavaScript or a backend language
  • The Shopify CLI installed globally

Create your Partner account at the Shopify Partners portal. Inside, you can generate development stores that behave like real stores without billing.

Install the Shopify CLI with npm:

npm install -g @shopify/cli @shopify/app

Verify the install:

shopify version

The CLI scaffolds projects, runs local servers, and manages deployment. It is the backbone of modern Shopify app development.

Step 1: Scaffold Your App with the Shopify CLI

The fastest way to create a Shopify app is through the CLI template. Run the init command:

shopify app init

The CLI prompts you to name your app and pick a template. For most projects, choose the Remix template. It ships with authentication, session storage, and a working admin page out of the box.

After scaffolding, move into the project folder:

cd your-app-name

Install dependencies:

npm install

The generated structure looks like this:

Folder/File Purpose
app/ Remix routes and React components
shopify.app.toml App configuration and scopes
prisma/ Database schema for session storage
extensions/ Theme and checkout extensions
.env API keys and secrets

This layout keeps your frontend, backend, and config separate. You can swap the default SQLite database for PostgreSQL or MySQL later. For guidance on that, review these database optimization techniques.

Step 2: Understand App Authentication with OAuth

Every Shopify app authenticates through OAuth. When a merchant installs your app, Shopify redirects them to an authorization screen. Once they approve, Shopify returns an access token.

The Remix template handles this flow automatically. Still, you should understand what happens under the hood:

  1. The merchant clicks install.
  2. Shopify sends them to your app’s OAuth endpoint.
  3. Your app requests specific scopes.
  4. The merchant grants access.
  5. Shopify issues an access token tied to that store.

Define your scopes in shopify.app.toml:

[access_scopes]
scopes = "read_products,write_products,read_orders"

Request only the scopes you need. Merchants and reviewers distrust apps that ask for broad permissions without reason. You can add scopes later through an update flow.

Session tokens power embedded apps inside the Shopify admin. The template stores these securely so you do not manage raw tokens by hand.

Step 3: Work with the Shopify API

Shopify offers two main APIs: REST and GraphQL. Shopify now recommends GraphQL for new apps because it returns exactly the fields you request and reduces round trips.

Here is a simple GraphQL query to fetch products:

query {
  products(first: 10) {
    edges {
      node {
        id
        title
        handle
      }
    }
  }
}

In a Remix loader, you call the admin API like this:

export const loader = async ({ request }) => {
  const { admin } = await authenticate.admin(request);
  const response = await admin.graphql(`
    query {
      products(first: 10) {
        edges { node { id title } }
      }
    }
  `);
  const data = await response.json();
  return json(data);
};

As your app grows, raw API calls become a bottleneck. Learn to design high-performance Shopify API clients that batch requests and respect rate limits. For heavy workloads, the Bulk Operations API processes large datasets without hitting throttles.

Caching also matters. Repeated queries for the same data waste quota. Explore caching strategies for Shopify GraphQL to cut response times and API usage.

Step 4: Build Your App’s Interface

Embedded apps live inside the Shopify admin using App Bridge and Polaris. Polaris is Shopify’s design system, and it gives your app a native look.

The Remix template includes Polaris components. Here is a basic page:

import { Page, Card, Text } from "@shopify/polaris";

export default function Index() {
  return (
    <Page title="My App">
      <Card>
        <Text as="p">Welcome to your Shopify app.</Text>
      </Card>
    </Page>
  );
}

Polaris handles spacing, buttons, tables, and forms with consistent styling. Merchants feel at home because your app matches the admin they already use.

If your app extends the storefront or checkout, you will work with different tools. The checkout flow uses Shopify checkout UI extensions for custom fields and content. Theme-facing features may rely on custom Shopify sections built with Liquid and JSON schema.

Step 5: Run and Test Locally

Start the development server with the CLI:

shopify app dev

The CLI creates a secure tunnel, updates your app URLs, and gives you an install link. Open the link to install the app on your development store.

Changes reload automatically. You can edit a route, save, and see the result in the admin within seconds.

Test with real scenarios. Create products, place test orders, and confirm your app responds correctly. For reliability, build a proper testing strategy early. These reliability testing practices for Shopify apps help you catch failures before merchants do.

Step 6: Handle Webhooks for Real-Time Events

Webhooks let your app react to store events like order creation, product updates, or app uninstalls. Instead of polling the API, Shopify pushes events to your endpoint.

Register a webhook in shopify.app.toml:

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

Then handle the payload in a route:

export const action = async ({ request }) => {
  const { topic, shop, payload } = await authenticate.webhook(request);
  if (topic === "ORDERS_CREATE") {
    // process the order
  }
  return new Response();
};

Always verify the webhook signature. The authenticate helper does this for you. Never trust an unverified payload.

Webhooks fail sometimes. Networks drop, servers restart, and payloads arrive out of order. To stay resilient, study how to build reliable Shopify webhook consumers and how Shopify webhooks fit an event-driven architecture.

For failed deliveries, a dead letter queue for Shopify webhooks captures messages you could not process so you can retry them safely. As volume grows, an event-driven architecture keeps your app responsive under load.

Step 7: Add Background Jobs and Queues

Many app tasks should not run in the request cycle. Syncing thousands of products or sending bulk notifications belongs in the background.

A queue system decouples slow work from user requests. The user gets an instant response while a worker processes the job.

Common queue patterns include:

Pattern Use Case
Simple job queue One-off background tasks
Scheduled jobs Periodic syncs and reports
Fan-out Processing many items in parallel
Retry with backoff Handling transient failures

For a deeper look, see how to design queue infrastructure for Shopify apps and async architectures for Shopify operations. These patterns become essential when you move data between systems. If your app syncs with external platforms, review CRM synchronization strategies and ERP integration architecture with Shopify.

Step 8: Store and Map Your Data

Your app needs a database for sessions, settings, and cached store data. The template uses Prisma with SQLite by default. For production, switch to PostgreSQL.

When you pull data from Shopify into your own schema, mapping matters. Fields do not always align one to one. Thoughtful data mapping strategies prevent bugs and data loss during sync.

If your app transforms data at scale, you may build a pipeline. Learn how to construct Shopify ETL pipelines that extract, transform, and load store data reliably.

For storing custom structured data inside Shopify itself, metafields and metaobjects are powerful. This complete guide to Shopify metafields and metaobjects shows when to use each.

Step 9: Deploy Your Shopify App to Production

Now comes the moment to deploy your Shopify app. You need two things: a hosting platform and your app config pushed to Shopify.

Popular hosting options include:

Platform Strengths
Fly.io Global edge, simple deploys
Railway Fast setup, managed databases
Render Free tier, auto deploys
AWS/GCP Full control, enterprise scale

First, build your app:

npm run build

Set your production environment variables on the host. These include your Shopify API key, API secret, app URL, and database connection string.

Then push your config to Shopify:

shopify app deploy

This command uploads your app configuration, extensions, and webhook subscriptions. Update your app URLs in the Partner Dashboard to point at your live domain instead of the local tunnel.

Run a smoke test. Install the app on a fresh development store from the production URL and confirm OAuth, pages, and webhooks all work.

Step 10: Scale and Harden Your App

Once merchants start installing, traffic grows. A single server can only do so much. Plan for scale before you hit limits.

Add caching layers across your Shopify ecosystem to reduce database and API pressure. Design for failure so one slow dependency does not take down the whole app. These guides on designing fault-tolerant Shopify integrations and preventing cascading failures cover the defensive patterns you need.

For global merchants, latency matters. A multi-region Shopify infrastructure serves users closer to home. And when you reach serious volume, learn how teams approach scaling Shopify apps to millions of requests using proven scalable integration patterns.

Self-healing systems reduce your on-call burden. Explore how to build self-healing Shopify integrations that recover from faults without manual intervention.

Submitting a Public App to the App Store

If you built a public app, you must pass Shopify’s review before listing. The review checks security, performance, billing, and merchant experience.

Prepare these items:

  • A clear app listing with screenshots
  • A privacy policy and GDPR webhooks
  • Billing through the Shopify Billing API
  • Fast load times and no console errors
  • A demo video or test instructions for reviewers

Reviews can take days to weeks. Address feedback quickly and resubmit. Custom apps skip this entirely since they install directly on one store.

Common Mistakes to Avoid

New developers often stumble on the same issues. Watch out for these:

Mistake Fix
Requesting too many scopes Ask only for what you use
Ignoring rate limits Batch calls and add backoff
Skipping webhook verification Always validate signatures
Blocking requests with slow work Move tasks to a queue
No error handling on sync Build retries and logging

Avoiding these early saves hours of debugging and improves your chances of passing review.

Conclusion

You now know how to build a Shopify app from scratch, from scaffolding with the CLI to deploying in production. The core steps stay the same across projects: authenticate with OAuth, query the API, build a Polaris interface, handle webhooks, and host your code reliably.

The hard part is not the first install. It is building an app that stays fast and resilient as merchants pile on. Invest in queues, caching, and testing early, and your app will grow without breaking.

Start small, ship a focused feature, and iterate. The Shopify ecosystem rewards apps that solve real merchant problems with care.

Frequently Asked Questions

How long does it take to build a Shopify app?

A simple app with basic features takes a few days to a couple of weeks. A full public app with billing, extensions, and App Store review can take one to three months depending on complexity.

Do I need to know a specific programming language?

No. Shopify supports any language that can serve HTTP. The official templates use Node.js with Remix, but you can build in Ruby, Python, PHP, or others using the REST or GraphQL APIs.

Is a Shopify Partner account free?

Yes. Creating a Partner account and development stores costs nothing. You only pay for your own hosting and any paid tools you choose to use.

Should I use REST or GraphQL?

Use GraphQL for new apps. Shopify recommends it because you request only the fields you need, which reduces data transfer and round trips. Some legacy endpoints still use REST.

What is the difference between a public and custom app?

A public app lists on the App Store and serves many merchants after passing review. A custom app installs on a single store through a direct link and skips the review process.

How do I test my app before going live?

Use a development store with the Shopify CLI dev command. Create test products and orders, trigger webhooks, and confirm every flow works before you deploy to production.

Can I update my app’s permissions later?

Yes. You can add or change access scopes after launch. Merchants will see a prompt to approve the new permissions the next time they open your app.

Your Trusted Shopify Partner.

Get in touch with our expert Shopify consultants today and let’s discuss your ideas and business requirements.