Inspiration
Shoppers who buy lipstick online hit the same two problems: a website swatch rarely matches real life, and they often already own something close. Reddit and Google threads describing this are anecdotal evidence, not a measured market, and this project does not claim that it reduces purchases. It starts from that problem and adds a way to keep the evidence behind a purchase decision.
What it does
Swatchbook lets you:
- Choose the exact candidate. Pick one of eight source-checked shades, paste a supported official variant link, or enter your own swatch. Unsupported links open manual entry and nothing is guessed.
- Add a product you own. One relevant product is enough. Suggestions use image color and the recorded finish, never a "dupe percentage".
- Compare the evidence. Website swatches, your sampled swatch photos, source links and notes stay together. The app states plainly that website colors are approximate.
- Optionally preview on a face (YouCam API). With explicit consent, the same photo is sent twice to the YouCam Makeup Virtual Try-On task API, once per shade, with the original lip shape kept and smoothing and reshaping set to zero. Names, prices and reasons can be hidden for a name-hidden A/B choice, then revealed.
- Save a decision. Use what I own, shortlist, try in store, or decide later. The record keeps product snapshots, sources and your reasons. Later real-use reports are labelled as your own report.
How we built it
- React 19 and TypeScript front end. Products, swatches and decisions stay in the browser (IndexedDB) with JSON export and import.
- The public demo runs on Cloudflare Workers (Vinext) with D1 for task state and encrypted R2 storage for temporary photos (AES-GCM, viewing expires after 30 minutes).
- YouCam file and task APIs are called server side. A durable lease, request keys and atomic quotas prevent duplicate paid submissions, and an unknown paid POST outcome is never automatically resubmitted. Known task IDs are recovered by GET polling.
- The original local version (Express, SQLite) is in the repository root. The deployed source is in
hosted/. - Checks: 29 automated tests plus 11 browser workflows for the local app, and 21 offline tests (including Workerd and R2 regressions) for the hosted app.
Challenges
Workers do not support some Node APIs the local app used (native fetch receiver, redirect: "error", file system storage), so the hosted port needed its own storage, quota and cleanup design. We also kept the product honest: virtual color is an approximation and is never presented as a calibrated prediction of a physical shade.
Accomplishments
A complete path from product choice to a saved, evidence-backed decision. A public demo works without login and was tested with the provider's official sample photo, including recovery of the same job after a reload.
What we learned
Comparison needs evidence more than another filter. Showing sources, limits and the original image beside AI previews builds more trust than a confident match score.
What's next
More supported products, calibrated swatch capture, and diverse-face testing. Those are unverified today: the demo was exercised on one official sample face, and physical shade accuracy and diverse-user performance have not been measured.
Notes for judges
- The public demo allows one free AI comparison per browser per rolling 24 hours while a limited shared allowance lasts. Source comparison and decisions work without AI previews.
- The project was built during the submission period. No purchase impact has been measured.
Built With
- cloudflare-d1
- cloudflare-r2
- cloudflare-workers
- node.js
- react
- typescript
- youcam-api
Log in or sign up for Devpost to join the conversation.