I lost a deal last month.
Prospect told me my competitor had dropped
their pricing two weeks earlier. Found out
during a live demo. Looked completely
unprepared.
Started looking for a tool to automate this.
Found Visualping, alerts on every pixel
change, completely noisy. Found enterprise
tools at $500+/year. Nothing in between.
So I built one.
The stack
- Next.js 16 (App Router)
- Playwright for scraping
- Supabase for storage
- Resend for emails
- vercel for hosting and cron worker
The hardest part: signal vs noise
Generic page monitoring is easy. Meaningful
change detection is hard.
A pricing page changes constantly, rotating
banners, timestamps, cookie notices, ad content.
If you alert on every pixel diff you're just
building a noise machine.
I built a classification engine that categorizes
changes before deciding whether to alert:
- PRICE_CHANGE — dollar amounts moving
- PLAN_CHANGE — plans appearing or disappearing
- FEATURE_CHANGE — features shifting between tiers
- COSMETIC — everything else (ignored)
The key insight: normalize the text before diffing. Strip dates, times, navigation text, cookie notices, social handles. Then run a line-by-line diff on what's left.
Only PRICE_CHANGE, PLAN_CHANGE, and FEATURE_CHANGE trigger an email.
Why Playwright over Puppeteer
Pricing pages are almost always JS-heavy SPAs. Puppeteer struggles with modern React apps,content loads after the initial HTML response.
Playwright with waitUntil: 'networkidle' plus a 2 second additional wait handles even the most aggressive lazy-loading. Worth the slightly heavier dependency.
The cron worker
Runs at 9am daily. Processes monitors sequentially with a 3 second delay between each — not parallel. Parallel scraping gets you rate-limited and blocked fast.
On first run: saves a baseline snapshot. On subsequent runs: diffs against the previous snapshot, classifies the change, sends alert if significant
What I'd do differently
The diff algorithm is the weakest part right now. Line-by-line text diff catches most changes but misses subtle restructuring, when a competitor moves a feature to a different plan section without changing the text, the diff doesn't catch it cleanly.
Next step is extracting structured data (plan name → price → features[]) and diffing the structure instead of raw text.
It's live and free
https://priceblind.vercel.app/
No account, no credit card. Paste a URL, get emailed when pricing changes.
Happy to answer questions about any part of the implementation, the scraping, the diff engine, or the email delivery.
What would you build differently?





















