Shopify app notes · 02

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.

Shopify CLI 4.x Prisma

First, four words explained

These come up constantly and nobody defines them for you.

WordWhat it means
CLI"Command Line Interface" — a program you type commands into instead of clicking buttons.
Dev storeA free, fake Shopify store for testing. Real products, no real money. Never develop against a live shop.
TunnelYour 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 versionA 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.

Starting from zero

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:

  1. Starts your app locally.
  2. Creates a tunnel so Shopify can reach your laptop.
  3. Temporarily points your app's URLs at that tunnel address.
  4. Pushes your shopify.app.toml settings to your dev store only.
  5. 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

FlagUse when
--store=my-shop.myshopify.comYou have several dev stores and want a specific one.
--config=stagingYou want to run against a different config file.
--resetThings 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.
The tunnel address changes every run

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.

CommandWhat it does
shopify app config linkConnects this folder to an app in your Shopify dashboard and creates a TOML file for it. Run once per environment.
shopify app config useSwitches which TOML is active. Everything else acts on the active one.
shopify app config pullRefreshes the local file from Shopify, without prompts.
shopify app config validateChecks 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
Trap — deploying to the wrong app

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
Trap — this does NOT deploy your code

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

CommandWhy you'd reach for it
shopify app info"Which app and store am I actually pointed at?"
shopify app env showShows the API key/secret values Shopify has for this app.
shopify app env pullWrites those values into a local env file for you.
shopify app generate extensionScaffolds a new extension (theme, checkout, admin).
shopify app logsStreams live logs — useful for debugging webhooks and functions.
shopify app graphiqlOpens a browser tool to try Admin API queries against your store. Excellent for learning.
shopify app webhook triggerFires a fake webhook at your app so you can test a handler without waiting for a real event.
Two that save real time

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
The "why is db.something undefined?" bug

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?

CommandProductionWhy
prisma migrate deploySAFEApplies migrations only. Built for this.
prisma generateSAFEOnly regenerates code. Touches no data.
prisma migrate statusSAFERead-only.
shopify app deployCAREChanges the live app's settings. Check app info first.
prisma studioCARELets you edit live rows by hand, with no undo.
prisma migrate devNEVERCan decide your database is out of sync and offer to reset it.
prisma migrate resetNEVERDeletes every row in the database.
prisma db pushNEVERChanges tables with no migration record. Can drop columns silently.
The one that ends careers

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 → restart shopify app dev, or deploy for non-dev stores.
  • schema.prisma → run npx 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