Distributing Your App
Getting your app onto real merchants' stores — whether that is one client you built it for, or the whole Shopify App Store.
First, the naming
Older articles talk about "private apps". That type no longer exists — Shopify deprecated it in 2022 and converted the remaining ones to custom apps. If you are following a tutorial that says "create a private app", it is out of date.
Today there are three ways an app gets onto a store:
| Type | Who can install it | Built where |
|---|---|---|
| Custom app | The specific store(s) you generate a link for | Your code + Dev Dashboard |
| Public app | Anyone, from the Shopify App Store | Your code + Dev Dashboard |
| Merchant custom app | Only that one store | Inside the store's own admin |
A merchant can create an app directly in their admin (Settings → Apps and sales channels → Develop apps) to get API credentials. It is quick, but limited: no extensions, and no access to protected scopes.
Use it for a private script that just needs API access. For anything with a real interface — like everything in this series — build a proper custom app instead.
Choosing between custom and public
Built for specific clients
- No Shopify review.
- No App Store listing to write.
- You bill the client directly — Shopify's billing is not required.
- Install by sending a link.
- Can cover several stores in one Plus organization.
Sold to any merchant
- Must pass Shopify's app review.
- Needs a full listing: screenshots, copy, demo store.
- Charges must go through Shopify's billing system.
- Found by merchants in the App Store.
- Ongoing quality requirements after launch.
You select a distribution method once per app and confirm it. It is not a setting you casually flip afterwards.
If you are genuinely unsure, or you want to serve one client now and sell publicly later, consider keeping them as two separate apps. Two client IDs is a small cost next to being stuck.
Path A — a custom app for a client
This is the common case for agency work: you built something for one merchant and need it on their store.
-
Finish the production setup
Your app must be deployed and reachable on a real HTTPS domain, with production environment variables in place (Note 11). The install will fail against a tunnel URL that is no longer running.
-
Choose the distribution method
Dev Dashboard → your app → Home → the Distribution card → Select distribution method → Custom distribution → confirm.
-
Generate the install link
Enter the store's
myshopify.com(oradmin.shopify.com) domain, then Generate link and copy it.There is an option allowing installs across multiple stores in one Plus organization. Clear it if you want the app locked to a single store.
-
Release a version
shopify app deploy, so the app has a released version with the right URLs and scopes. Without one, the link will not install anything. -
Send the link to the store owner
They open it, review the permissions, and click install. It must be the store owner or a staff member with permission to install apps.
-
Verify together
Open the app in their admin and use the main feature. Confirm webhooks arrive (
shopify app logs) and check your server logs for errors.
Custom apps are not required to use Shopify's billing. You invoice the client directly, which is usually simpler for agency work — and means no revenue share.
Path B — publishing to the App Store
Longer, and the review is a real gate. Budget weeks, not days — including time for a rejection and a resubmission.
-
Meet the technical requirements first
Before writing any listing copy, make sure the app itself qualifies:
- Installs cleanly via OAuth, and re-installs cleanly for a returning merchant.
- If embedded, uses App Bridge and session token authentication.
- No broken UI, no 404s or 500s in normal use.
- Any storefront/theme changes use theme app extensions — not direct theme edits (Note 17).
- All charges go through Shopify's billing system, tested end to end (Note 16).
- Subscribed to the three compliance webhooks and responding correctly — apps are rejected without them (Note 15).
- It is a finished, stable product — not a beta.
-
Select public distribution
Dev Dashboard → app → Home → Distribution card → Select distribution method → Public distribution → confirm.
-
Prepare a demo store
A development store set up to showcase the app, linked so reviewers and merchants can see it working. Point it at the page that best demonstrates the value, with a little guidance on what to do there.
-
Build the listing
- Screenshots: 3–6 desktop images at 1600×900. Crop out browser chrome. No personal data, no pricing claims, no fake reviews. Include mobile/POS shots if relevant.
- App introduction: 100 characters, benefit-led. "We package and ship your orders. Fast fulfillment can boost sales" beats "A creative solution for your needs."
- Write plainly about outcomes. Avoid keyword stuffing and unprovable claims.
-
Write the testing instructions
The most commonly underestimated step. Reviewers need test credentials and clear steps to reach your app's main feature. A short screencast helps a lot. Apps get rejected purely for being hard to test.
-
Submit, and expect a conversation
Your submission moves through statuses: Submitted → possibly Paused (core requirements missing — you fix and resubmit) → Reviewed (the reviewer needs to discuss something — you must reply) → Published.
You can withdraw at any point. Rejection is normal on a first attempt; read the email carefully, fix exactly what it lists, and resubmit.
Requirements are updated over time and quality checks happen regularly. An app that passed review two years ago is still expected to meet today's standards.
A public app is an ongoing commitment: support, reviews, API version upgrades, and keeping up with changing rules. A custom app has none of that overhead.
Updating an app that is already installed
Once merchants have your app, releasing changes means remembering both deploys (Note 11):
# code → your server
git pull && docker compose up -d --build
# settings → Shopify
shopify app deploy
Release a version with extra permissions and installed stores do not get them automatically. Each merchant must approve the update in their admin.
So your feature is not live when you deploy — it is live when they click approve. For a public app with many merchants, that rollout is gradual and partly out of your hands. Write code that copes with both states.
If a settings release goes wrong, roll back to the previous version:
shopify app versions list
shopify app release --version=<previous>
Common questions
Can I switch from custom to public later?
Treat the choice as fixed. If both futures are realistic, keep two apps — one custom for the client, one public. Sharing a codebase between them is easy; unpicking a wrong distribution choice is not.
Can one custom app serve several stores?
Yes, when those stores belong to the same Plus organization — there is an option for it when generating the link. Unrelated merchants need a public app.
Does a custom app have to use Shopify billing?
No. Invoice the client however you normally do. Public apps must use Shopify's billing system.
The install link does not work
- No released version yet — run
shopify app deploy. - The app URL points at a dead tunnel instead of your production domain.
- The person opening it lacks permission to install apps on that store.
My app was rejected
Normal. The email lists what to fix. Address exactly those points and resubmit with Submit fixes. The most frequent causes are poor testing instructions, broken installs, and theme edits that should be theme app extensions.
Before you send an install link to a real client
- App deployed and reachable at its production HTTPS domain.
- Production config active —
shopify app infonames the right app. - A version released with the correct URLs and scopes.
- Scopes match in the TOML and the server's environment variables.
- Tested on a dev store using the production build, not a tunnel.
- Uninstall and reinstall tested — no data lost (Note 04 and 05).
- Webhooks confirmed arriving.
- You have a rollback plan and a recent database backup.
Cheat sheet
# three ways onto a store
custom app install link → specific store(s) no review
public app Shopify App Store review required
merchant custom built in the store admin no extensions,
no protected scopes
# "private app" — deprecated in 2022, now custom apps
# custom distribution
Dev Dashboard → app → Home → Distribution → Select method
→ Custom → enter store domain → Generate link → send to owner
(needs a released version: shopify app deploy)
# public distribution
technical requirements → select Public → demo store
→ listing (3-6 screenshots @1600x900, 100-char intro)
→ test credentials + screencast → submit
Submitted → Paused → Reviewed → Published
# updating merchants
code → your host
config → shopify app deploy
new scopes → EACH merchant must approve in their admin