examples/storefront Public
id: local-dev
type: guide
owner: justin
describes:
- wrangler.jsonc
- workers/*/wrangler.jsonc
- scripts/seed.sql
reviewed: 2026-10-16
Running the shop locally
You need Node 24 and, for checkout, a Stripe account in test mode. Everything else runs in wrangler's local mode.
The API
npm install
npm run db:migrate # applies migrations/ and search/migrations/ to the local D1s
npm run db:seed # six products, one of them out of stock
echo 'ADMIN_TOKEN=dev-admin-token' > .dev.vars
npm run dev # storefront-api on localhost:8787
The seed writes straight to the database, so the search index is empty until you rebuild it:
curl -X POST localhost:8787/admin/search/rebuild -H 'authorization: Bearer dev-admin-token'
curl 'localhost:8787/search?q=linen'
curl localhost:8787/products lists all six; the candle is out of stock, so adding it to a cart fails. Add STRIPE_SECRET_KEY (a test mode secret key) to .dev.vars to try checkout.
Image URLs point at IMAGES_URL from wrangler.jsonc. Locally the upload works but the URL does not resolve, because the custom domain serves the production bucket ([[product-images]]). Set IMAGES_URL in .dev.vars to another origin if you want working links.
The other Workers
Each has its own config, so run it in a second terminal from the repository root:
npx wrangler dev -c workers/stripe-webhook/wrangler.jsonc --port 8788
npx wrangler dev -c workers/fulfilment/wrangler.jsonc --port 8789
wrangler connects the ORDERS service bindings to the storefront-api you started first, and the order-events queue between storefront-api and fulfilment. See [[payment-webhook]] for forwarding Stripe's test events and [[fulfilment]] for the warehouse settings.
Cron
The unpaid order expiry runs on a cron trigger. To run it once by hand:
npx wrangler dev --test-scheduled
curl 'localhost:8787/__scheduled?cron=*/5+*+*+*+*'
Tests
The tests need none of this; see [[testing]].