Most Shopify wishlist apps have the same quiet flaw: the wishlist data lives in the app, and the merchant's email platform never sees it. The store knows who wants what β but can't email on it.
We built WishList Ninja to fix exactly that. Here's how the interesting bits work.
The core idea: profile properties, not just events
Everyone fires events ("Added to Wishlist"). Events are fine for triggering flows, but useless for segmentation β you can't build a clean segment of "people with items saved right now" from a two-month-old event.
So on every save/remove we write profile properties to Klaviyo, Mailchimp or Omnisend in real time:
-
has_active_wishlistβ true only while the wishlist has items in it -
wishlist_countβ items currently saved -
wishlist_valueβ what they're worth -
top_saved_itemβ the product they want most
That first flag sounds trivial. It isn't.
Why a boolean was the hard part
**
has_active_wishlist has to flip **false again β otherwise it's just "has ever used the wishlist," which is worthless. So every path that empties a wishlist has to re-evaluate it:
- shopper removes the last item β
- shopper buys the last item (orders webhook marks items purchased) β
- guest list merges into an account β
- and the subtle one: saved collections don't count. A shopper following a collection but holding zero items is not "active intent." Items only.
One rule, five code paths. The rule lives in exactly one function so the paths can't drift apart.
*7 flow triggers from 2 webhooks
*
The email moments merchants actually want are mostly store-side changes, not shopper actions:
Added to Wishlist Β· Price Drop Β· On Sale Β· Low Stock Β· Back in Stock Β· Collection Saved Β· New in Saved Collection
Five of those seven come from diffing products/update webhooks against what shoppers have saved: price went down β find everyone holding that product β fire Price Drop into their ESP. No polling, no cron scanning the catalog.
*Multi-ESP fan-out without domino failures
*
Supporting three ESPs means three APIs that can each be down, rate-limited, or misconfigured. Early version: Klaviyo throwing meant Mailchimp and Omnisend never got the event. Bad.
Now each delivery is isolated β a failure is caught and logged, and the job only retries if nothing was delivered. One dead API key can't block the other platforms.
*The storefront budget: ~12KB
*
The whole storefront (hearts on product cards, slide-out drawer, wishlist page, share links, save-for-later on the cart) is vanilla JS, minified to under ~12KB. No framework, no fonts, no CSS libraries. Core Web Vitals are a ranking signal; an app that slows the store is stealing from the merchant to fund itself.
*Stack
*
Laravel + MySQL + Redis on Cloudways, Shopify theme app extension for the storefront, Mailjet for transactional email β and a large amount of Claude Code for the build itself.
Launching on the Shopify App Store now. If you run (or build for) a Shopify store, I'd love your take: wishlist-ninja.com π₯·
Happy to go deeper on any of this in the comments β especially the webhook diffing.
United States
NORTH AMERICA
Related News
π I Built a Dropshipping Automation Pipeline β Here's What I Learned (and What I'd Do Differently)
11h ago
How I Cut My LLM API Bill by 40x: A Freelancer's Migration Story
11h ago

Mattress Firm Coupons: Save up to $600
3h ago
Google Ordered to Pay $2 Billion For Anti-Competitive Practices By Swedish Court
20h ago
The Censorship Wall: Why Every AI Companion App Ends Up Filtering You
20h ago