Inspiration

I honestly didn't know about Perfect Corp APIs until i came across this hackathon. I quickly explored the capabilities of each and every endpoint that Perfect offers and then sat down to do some more research. I found out that skincare is a $200B industry built on confusion. Walk into any pharmacy and you're faced with hundreds of products, zero guidance, and a receipt that could rival a car payment. Most people either overspend on products they don't need, or give up entirely because they don't know where to start.
I wanted to flip that. What if your phone could do what a dermatologist consultation does: analyze your skin, identify real concerns, and build a routine around your face, not a generic skin type? And what if it cost nothing upfront? That's SkinBudget: expert-level skin intelligence, zero gatekeeping.


What it does

SkinBudget is a mobile-first AI skincare advisor built on React Native (Expo). I also built a web version but it's just a dashboard at the moment that shows the same data as the app itself.

Here's what it delivers:

  • AI Skin Scan — Take a selfie and get a full breakdown across 13 metrics: acne, wrinkles, pores, oiliness, radiance, moisture, dark circles,
    eye bags, redness, texture, firmness, age spots, and blackheads. Each metric is scored, graded, and visualized with a heatmap overlay showing exactly where the concern appears on your face.
  • Personalized Routine — Based on your scan results, the app generates a tailored AM/PM skincare routine with product-type recommendations matched to your top concerns.
  • Progress Tracking — Data form every scan is saved. Track how your skin health evolves over time and maintain a daily streak to build consistency.
  • PDF Report — Download a shareable, professionally formatted skin health report with your scores, concern breakdown, and recommendations.
  • AR Ring Try-On — Virtual try-on for jewelry using 2D hand image analysis — see how rings look on your hand before buying.
  • Web Dashboard — A companion Next.js web app where users can view their skin score, weekly streak, and routine progress from any browser.

How I built it

Mobile app: React Native with Expo (SDK 54), using Expo Router for file-based navigation. The UI is built entirely with React Native's
StyleSheet API — no third-party component libraries.

AI Skin Analysis: I integrated Perfect Corp's AI Skin Analysis API via a 4-step
async flow:

  1. POST /file/skin-analysis — request a pre-signed S3 upload URL
  2. PUT <s3_url> — upload the image binary directly to S3
  3. POST /task/skin-analysis — submit the task with 13 metric targets
  4. GET /task/skin-analysis/{id} — poll until task_status === "success"

Each metric returns a score, severity level, and a mask URL for the heatmap overlay rendered in SVG on the results screen.

AR Ring Try-On: Built on Perfect Corp's 2D Virtual Try-On API using the same async task
pattern against the /file/2d-vto and /task/2d-vto/ring endpoints.

Backend: Supabase (PostgreSQL) for storing scan results and routine logs. Clerk for authentication across both mobile and web. EAS (Expo Application Services) for cloud builds and distribution.

Marketing site: Next.js 16 with Tailwind CSS, deployed on Vercel. Includes a protected dashboard powered by Clerk + Supabase server-side data
fetching.


Challenges I ran into

Binary image upload to S3 was trickier than expected on Android. The pre-signed URL flow requires sending raw image bytes — not base64, not FormData — which behaves differently across platforms and Expo's file system APIs.

Android standalone builds exposed a gap we hadn't hit in Expo Go: without the expo-camera plugin declared in app.json, the CAMERA permission was never injected into the Android manifest. The app worked perfectly on iOS (Expo Go pre-grants everything) but crashed silently on Android until we identified the missing native config.

Async polling UX required careful state management. The Perfect Corp API is genuinely async — analysis can take 3–8 seconds — so we built a progress indicator with an animated scan-line overlay and stage-based messaging (uploading → analyzing → done) to keep the experience from feeling broken during the wait.

CNG vs. committed native folders — we had a committed ios/ folder that caused EAS Build to silently ignore all app.json plugin configuration. Took some debugging to realize the native folder was overriding the managed config.


Accomplishments that I am proud of

  • A genuinely useful 13-metric skin analysis that produces actionable, personalized output — not just a gimmick
  • The heatmap visualization: SVG overlays on the original selfie showing exactly where acne, pores, wrinkles, and redness appear
  • End-to-end flow from selfie → AI analysis → routine → PDF report in a single session
  • A polished UI that feels like a real consumer product, not a hackathon prototype
  • Cross-platform delivery: iOS, Android, and web all sharing the same Supabase data layer

What I learned

  • Perfect Corp's S2S API is powerful but async-first — you have to build for polling from the start, not as an afterthought
  • Expo's CNG (Continuous Native Generation) model is the right default for projects using managed plugins; committed native folders cause subtle, hard-to-diagnose config sync failures
  • EAS environment variables are baked at build time, not injected at runtime — a distinction that only hurts you when you discover it in production
  • SVG-based overlays in React Native (react-native-svg) are surprisingly capable for data visualization without reaching for a charting library

What's next for SkinBudget

  • Trend analysis — graph your scores over time to see whether your routine is actually working
  • Product database — link metric recommendations to specific affordable products, fulfilling the "Budget" in SkinBudget
  • Face comparison — side-by-side before/after visualization between two scan dates
  • Routine reminders — push notifications for AM/PM routine check-ins
  • More try-on categories — expand beyond rings to other jewelry and accessories using additional Perfect Corp VTO endpoints

Built With

Share this project:

Updates