Prerequisites
- Node.js
>=20.19 <22or>=22.12(enforced viaengine-strict; other versions are refused). - Shopify CLI installed and authenticated (
shopify app devprompts for login on first use). - A development store you can install the app on.
Install and run
npm run dev starts the Shopify CLI, which in turn runs the app’s own chain:
prisma generate— regenerate the Prisma client.prisma migrate deploy— apply pending migrations to the SQLite database.react-router dev— the application server.
127.0.0.1:9293 URL), and the theme editor link for your store. The app port is chosen dynamically on each boot, so read it from the banner rather than assuming a fixed port.
Secrets and environment
The project intentionally has no committed.env with app secrets. The Shopify CLI injects SHOPIFY_API_KEY, SHOPIFY_API_SECRET, SCOPES, and SHOPIFY_APP_URL into the dev process at runtime. Only DATABASE_URL (a local SQLite file path) exists in .env.
For scripted tests that need real signing secrets (proxy HMAC, webhook HMAC), pipe them from the CLI without persisting them:
Theme preview
The theme app extension (tracker + counter) renders through the CLI’s local theme preview at127.0.0.1:9293 while shopify app dev runs. The blocks must still be enabled in the store’s theme — see Theme setup. Until the extension has been deployed at least once, the local preview may render the host theme without the blocks; the store-domain theme editor preview is the reliable surface during development.
Demo and tooling scripts
All scripts live inscripts/ and are development/QA utilities — none are part of the runtime.
Developer gotchas
The dev server 'wedge': CLI alive, every route 404
The dev server 'wedge': CLI alive, every route 404
The most common false alarm. The Shopify CLI process keeps running while the application server inside it has died — every route (admin, proxy, webhooks) returns 404. Verify with a status check against the app port shown in the CLI banner;
404 means wedged. Fix: stop shopify app dev completely and start it again.Tunnel aborts on restart
Tunnel aborts on restart
The quick tunnel occasionally aborts with a transient error when the dev server restarts. Simply starting the dev server again usually resolves it.
Expired CLI credentials in non-interactive shells
Expired CLI credentials in non-interactive shells
Re-authentication requires a browser prompt. If your CLI session has expired,
shopify app dev fails from background shells and scripts — re-authenticate in an interactive terminal first.shopify app config link can drop the app proxy
shopify app config link can drop the app proxy
Re-linking app configuration can regenerate the config file without the
[app_proxy] block. Storefront tracking silently breaks (requests never reach the app). Always re-check that the block is present after linking, and restart the dev server so the proxy URL re-registers.Disable the scheduler
Disable the scheduler
The in-process cron (insights, order sync, rollups, retention, billing checks) starts on the first admin page load. Set
SCHEDULER_DISABLED=1 to keep it off — useful when seeding data or running tests against a predictable database.Tests use the dev database
Tests use the dev database
Integration suites share the dev SQLite file. Fixture shops and cleanup make this safe, but don’t point
DATABASE_URL at data you care about — see Testing.