2025 · Solo developer
A Shopify app that keeps catalogues in sync from a master store to many expansion storefronts: products, variants, collections, inventory and more, with per-field mapping for what travels, exclusion rules for what doesn't, and price transformations along the way. An advanced job queue keeps it accurate on the busiest days.
When a brand expands into new markets, each storefront needs its own product catalogue, but keeping them in sync with a master store is a manual, error-prone process. Products drift, prices diverge, inventory lags behind. The more stores you add, the worse it gets.
Expansion Store Sync watches the master store for changes and propagates them automatically to each connected expansion storefront. Per-field mapping controls exactly what travels: titles, descriptions, images, variants, collections, inventory levels and metafields. Exclusion rules let you skip products or fields that shouldn't sync, and price transformations handle currency conversions and markups on the fly.
A Redis-backed BullMQ job queue processes sync events in order, with automatic retries and dead-letter handling. The system has synced over 1.5 million product updates from a single store network in under 24 hours.
Built on Next.js with a PostgreSQL database (via Prisma) for configuration and sync state, Redis for the job queue, and Shopify GraphQL Admin API for reading and writing catalogue data. The app runs on DigitalOcean with Docker, fronted by a Shopify Polaris admin interface that lets merchants configure field mappings and monitor sync status in real time.
Shopify doesn't expose what changed. You just get the current state. So the first real problem was building something that quickly and efficiently calculates what's different, and what needs to update on the other stores. The second problem was inventory. When an inventory change hits one store in a network of 10+ stores, it needs to propagate to the others, but those updates themselves trigger new events, which trigger new updates. In the beginning it looped. Building a system that handles that cascade without tripping over itself was the hardest part of the entire project.