Portfolio Project · Built in Claude Code

Lash Consultation
+ AR Try-On

A photo-based consultation tool with a built-in AR try-on. Clients get a safety-checked lash recommendation from a few reference photos and a few questions, preview it live on their own face, then leave with an exportable spec sheet and signed consent form, ready to share with their lash technician at the appointment.

6
features in a single consultation flow
22
research-sourced wispy style variants
6+
years lash expertise powering the logic
Solo
designed and built in Claude Code
The Problem

Clients book lash styles they have never actually seen on themselves

Lash consultations typically happen verbally: a client describes what they want, the artist interprets it, and the result is a coin flip. Mismatched expectations lead to unhappy clients, costly corrections, and low rebooking rates. Worse, an artist has no way to verify what "medium fullness" or "almond eyes" actually means for a specific client, and an over-eager recommendation can genuinely damage natural lashes. There is no tool that replaces guesswork with measurement, caps the result at what's actually safe, and lets a client see it on their own face before committing. Every feature below exists because of a specific piece of that problem.

Six Features, One App

What's in the app, and why it's built that way

Feature 01 · Smart Intake
Photos Aren't Optional: They're the Instrument

The problemClients describe their own eye shape and lash condition inconsistently, and an artist can't verify "medium fullness" or "almond eyes" before the appointment. A naive version of this also has an equity problem: any measurement built on raw photo brightness gets less reliable on darker skin, where a natural lash and the skin behind it sit closer together in tone: exactly the clients a one-size-fits-all detector would under-serve.

The decisionMade reference photos mandatory and camera-only, no file upload, so an on-screen guide can fix the mm scale and enforce the lighting/no-makeup conditions the measurement depends on. Then used MediaPipe face landmarks to auto-detect eye shape and an auto-measurement step that recalibrates its own contrast to each individual photo rather than a fixed brightness cutoff, so accuracy holds across skin tones instead of only the lightest ones. The exact calibration method is part of the app's engine and isn't detailed here, for the same reason the recommendation logic lives server-side (see Feature 02).

MediaPipe face landmarks Skin-tone-adaptive measurement mm-calibrated auto-measurement Camera-only capture, no upload
Feature 02 · Recommendation Engine
A Deterministic Engine, Not an AI Guess

The problemVerbal consultations are a coin flip, and swapping that for an LLM call just trades one kind of guessing for a slower, costlier, unverifiable one.

The decisionEncoded real lash-application logic as deterministic rules: zero marginal cost, instant, no hallucination risk. When the entire ruleset turned out to be readable in browser devtools, the engine was moved behind a thin serverless relay: the client sends only anonymised answers, the server returns the result, and the proprietary logic never ships in the bundle.

Deterministic rules Zero marginal cost Server-side IP protection
Feature 03 · Safety Engine
The Engine Can't Recommend an Unsafe Set

The problemExtensions that are too long or too heavy for a client's natural lash cause real damage, and it's an easy mistake to make when a client just says "make it dramatic."

The decisionHard-coded the industry length rule (natural length +3mm or 1.5x, whichever is smaller) and a physics-based weight model (weight scales with diameter²) that caps how many fans the natural lash can carry; the engine silently downgrades an unsafe request and explains why.

Length cap (+3mm / 1.5x) Weight-capacity model Auto-downgrade + explanation
Feature 04 · AR Try-On
See It Before You Book It

The problemEven a perfect recommendation is just words and numbers until a client sees it on their own face. That's the original problem this project set out to solve.

The decisionChose a lightweight, real-time canvas overlay mapped to MediaPipe eyelid landmarks (the same technique behind Snapchat/Meitu-style filters) over a heavier 3D face mesh, so try-on runs smoothly on an ordinary phone camera. Lash length is drawn true to the recommended mm against the eye's own measured width, not a stylized approximation, so the length slider changes what a client sees at real scale.

MediaPipe tracking Live volume/length sliders Recording + snapshot
Feature 05 · 3D Style Preview
Inspect the Style, Not Just the Fit

The problemLive AR is great for "does this suit my face," but poor lighting or tracking jitter can obscure the actual shape and density of the fan itself.

The decisionPaired the live AR with a separate, pre-baked 3D model viewer (rotatable GLB models per style and diameter, tilted to match the recommended curl) so a client can inspect the exact geometry of a recommendation independent of camera conditions.

three.js / react-three-fiber Rotatable GLB style models
Feature 06 · Spec Sheet & Waiver
A Portable Record, Not Just a Conversation

The problemA recommendation is easy to lose between the consultation and the actual appointment, especially with a different technician, and lash extensions are a medical-adjacent service with real contraindications, usually gated by a paper waiver disconnected from everything else.

The decisionGenerate an exportable spec sheet (style, curl, lash map, diameter, aftercare; exported as PDF, image, text, or native share) so the recommendation survives the handoff, and built a full digital health-screening and consent waiver with an on-screen signature pad into the same flow.

PDF / image / text export Signature pad Health screening & consent
How It Works

Four steps, real names from the app

01
The Eyes
Required reference photos auto-detect eye shape and auto-measure natural lash length in mm, instead of self-reporting.
02
The Look + Lifestyle
A short set of questions on desired look, fullness, natural lash thickness/density, growth direction, experience, and lifestyle, with no lash expertise required.
03
Safe, Explained Recommendation
The rule-based engine returns style, curl, a 5-zone length map, and fan diameter, capped by the safety guardrails, with a plain-language reason behind every choice.
04
Try It, Save It
Live AR try-on and a rotatable 3D preview let the client see the style, then an exportable spec sheet and signed waiver travel with them to the appointment.
Why This Exists as a PM Project

Domain expertise turned into product

Real problem, real domain knowledge6+ years as a lash technician means I know exactly where consultation breaks down. This is not a hypothetical user problem; it is one I observed and experienced directly.
End to end product ownershipI scoped the problem, defined the user flow, designed the intake logic, and built the app solo in Claude Code. Discovery, design, and delivery.
On-device ML and AR integrationDemonstrates comfort working with on-device ML (MediaPipe face-landmark detection) and emerging technologies (AR camera overlay, 3D model preview) in a real product context, not just a tutorial project, and choosing a rule-based, not AI-call, architecture deliberately, for zero marginal cost and a stronger privacy story.
Caught and fixed an IP exposure after shippingThe recommendation ruleset was originally fully inspectable in the browser bundle. Recognising that as a real risk to the product's differentiation, I moved the engine behind a serverless relay so the client only ever sends and receives data, never the logic itself.
Risk management built into the productExtension length and weight are hard-capped by the engine itself, and informed consent is captured in the same digital flow via a signed waiver: treating a beauty service with the same seriousness as a health-adjacent one, instead of leaving safety to a verbal reminder.
Clear commercial impactReduced client-artist misalignment leads to higher client satisfaction, lower correction rates, and better rebooking. The product metric is clear before a single line is written.
Tech Stack

Built solo in Claude Code

React / Vite Rule-based engine (server-relayed) MediaPipe face landmarks Canvas AR overlay three.js / react-three-fiber jsPDF / html2canvas Capacitor (iOS / Android) Tailwind CSS Claude Code