Shopify CLI Essentials
The handful of terminal commands you will actually run while building a Shopify app — what each one really does, and which ones can destroy a production database.
First, four words explained
These come up constantly and nobody defines them for you.
| Word | What it means |
|---|---|
| CLI | "Command Line Interface" — a program you type commands into instead of clicking buttons. |
| Dev store | A free, fake Shopify store for testing. Real products, no real money. Never develop against a live shop. |
| Tunnel | Your app runs on your laptop, which the internet cannot reach. A tunnel gives you a temporary public web address that forwards to your laptop, so Shopify can talk to it. |
| App version | A snapshot of your app's settings stored by Shopify. Deploying creates a new one. |
Setup, once
# Install globally
npm install -g @shopify/cli
# Check it worked
shopify version
# Log in (opens your browser)
shopify auth login
You can skip the global install and prefix every command with npx instead — npx shopify app dev. Slightly slower, but guarantees you use the version pinned in the project.
shopify app init creates a brand-new app from a template and walks you through it. If you are joining an existing project, skip it — the project already exists.
The one you will live in
shopify app dev
This is your whole development session. Run it and leave it running. It does five things at once:
- Starts your app locally.
- Creates a tunnel so Shopify can reach your laptop.
- Temporarily points your app's URLs at that tunnel address.
- Pushes your
shopify.app.tomlsettings to your dev store only. - Reloads the app whenever you save a file.
It prints a link. Open it and your app loads inside the Shopify admin. Press Ctrl + C to stop.
Flags worth knowing
| Flag | Use when |
|---|---|
--store=my-shop.myshopify.com | You have several dev stores and want a specific one. |
--config=staging | You want to run against a different config file. |
--reset | Things are confused — it re-asks which app and store to use. |
--tunnel-url=https://... | You have your own fixed tunnel (ngrok) instead of the random one. |
Each shopify app dev usually gives you a different random address. That is why automatically_update_urls_on_dev = true exists in the TOML — the CLI rewrites your URLs for you. It also means a URL you bookmarked yesterday will not work today. Use a fixed tunnel if that annoys you.
Config commands
Your app's settings live in shopify.app.toml. Real projects have several — one per environment.
| Command | What it does |
|---|---|
shopify app config link | Connects this folder to an app in your Shopify dashboard and creates a TOML file for it. Run once per environment. |
shopify app config use | Switches which TOML is active. Everything else acts on the active one. |
shopify app config pull | Refreshes the local file from Shopify, without prompts. |
shopify app config validate | Checks your TOML for mistakes before you deploy. Cheap insurance. |
shopify app config use production # now "production" is active
shopify app config validate # check it's valid
shopify app info # confirm which app/store you're pointed at
Deploy commands act on whichever config is currently active. If you last ran config use production and then deploy while thinking you are on dev, you have just changed the live app.
Habit to build: run shopify app info before every deploy and read which app it names.
Deploying
shopify app deploy
This is the single biggest beginner misunderstanding. shopify app deploy sends your settings and extensions to Shopify: scopes, webhook topics, app URLs, app proxy config, checkout/theme extensions.
It does not upload your route files, your server, or your database. Your actual application code is deployed the normal way for wherever it is hosted — Docker, a VPS, Heroku, Fly, whatever you use.
A change to a route file needs your hosting deploy. A change to shopify.app.toml needs shopify app deploy. Many changes need both.
Related commands:
shopify app versions list # every settings snapshot you've deployed
shopify app release # make a specific version the live one
Because versions are kept, a bad settings deploy can be rolled back by releasing the previous one.
Occasionally useful
| Command | Why you'd reach for it |
|---|---|
shopify app info | "Which app and store am I actually pointed at?" |
shopify app env show | Shows the API key/secret values Shopify has for this app. |
shopify app env pull | Writes those values into a local env file for you. |
shopify app generate extension | Scaffolds a new extension (theme, checkout, admin). |
shopify app logs | Streams live logs — useful for debugging webhooks and functions. |
shopify app graphiql | Opens a browser tool to try Admin API queries against your store. Excellent for learning. |
shopify app webhook trigger | Fires a fake webhook at your app so you can test a handler without waiting for a real event. |
app graphiql lets you build and test a query with autocomplete before pasting it into your code. app webhook trigger means you no longer have to uninstall your app just to test the uninstall handler.
Prisma: the database commands
Different tool, same terminal. These are the ones you run weekly.
After changing schema.prisma
npx prisma migrate dev --name add_product_table
Three things happen: a migration file is written, your local database is updated, and the Prisma client is regenerated. Development only.
After pulling someone else's changes
npx prisma generate # rebuild the client from schema.prisma
npx prisma migrate dev # apply any migrations you don't have
If db.myNewTable is undefined even though it is clearly in the schema, your generated client is stale — usually after switching branches. npx prisma generate fixes it. This will happen to you, probably more than once.
On production
npx prisma migrate deploy
Applies pending migrations and nothing else. It never asks questions and never resets. This is the only migrate command that belongs near production data.
Looking at your data
npx prisma studio # opens a browser table editor
npx prisma migrate status # which migrations have been applied?
Which commands are safe near production?
| Command | Production | Why |
|---|---|---|
prisma migrate deploy | SAFE | Applies migrations only. Built for this. |
prisma generate | SAFE | Only regenerates code. Touches no data. |
prisma migrate status | SAFE | Read-only. |
shopify app deploy | CARE | Changes the live app's settings. Check app info first. |
prisma studio | CARE | Lets you edit live rows by hand, with no undo. |
prisma migrate dev | NEVER | Can decide your database is out of sync and offer to reset it. |
prisma migrate reset | NEVER | Deletes every row in the database. |
prisma db push | NEVER | Changes tables with no migration record. Can drop columns silently. |
prisma migrate reset drops your database and rebuilds it empty. It is completely normal in development and catastrophic anywhere else.
Before running any prisma command, check which database DATABASE_URL points at. If your terminal can reach production, assume it will.
A normal working day
# 1. Get the latest code
git pull
# 2. Install anything new
npm install
# 3. Sync the database with the schema
npx prisma generate
npx prisma migrate dev
# 4. Start working — leave this running all day
shopify app dev
Then edit files. The app reloads by itself. Stop with Ctrl + C when you are done.
When something goes wrong
shopify app dev asks me to pick an app every time
The link between this folder and the app was lost. Run shopify app config link to reconnect, or shopify app dev --reset to start the selection fresh.
My changes are not showing in the Shopify admin
Work out which kind of change it was:
- Route or component file → should reload automatically. Hard-refresh the browser.
shopify.app.toml→ restartshopify app dev, or deploy for non-dev stores.schema.prisma→ runnpx prisma migrate dev..env→ always requires a full restart.
"App not installed" or a blank screen
Usually the app URL no longer matches the tunnel. Stop the CLI and start shopify app dev again — it rewrites the URLs. If it persists, add --reset.
A brand new CLI version broke something
It happens. Pin a known-good version instead of always taking the newest:
npm install -g @shopify/cli@4.7.0
Then check the CLI's changelog before upgrading again.
Weird, unexplainable CLI errors
If you run through npx, its cache can corrupt. Clearing it fixes a surprising number of "impossible" errors:
rm -rf ~/.npm/_npx
Cheat sheet
# daily
shopify app dev start working
npx prisma generate after pulling changes
npx prisma migrate dev --name thing after editing the schema
# checking
shopify app info which app am I on?
shopify app config validate is my TOML valid?
npx prisma studio browse the data
# shipping
shopify app config use production switch environment
shopify app deploy push SETTINGS (not code)
npx prisma migrate deploy apply migrations safely
# never on production
npx prisma migrate reset deletes everything
npx prisma db push silent schema changes