The problem
Every skin app hands you a score. The score changes. You have no idea why.
Was it the serum you started last week? Or did you just sleep better? Is the bathroom light different today? Did you stand a bit closer to the camera than last time?
Here is the thing I kept coming back to. Photograph the same face twice in different light and the same analyser gives you different numbers. So an app that calls every difference a change is not measuring your skin. It is measuring your bathroom.
That matters when you are about to spend £40 on a serum and you cannot answer one simple question: did the last one do anything? Nobody can answer it. So people buy on marketing and quit on doubt.
What I built instead
Glowdays is a private skin diary that treats every comparison as a measurement, with all the uncertainty that comes with one. It is willing to tell you no.
It says no when it should. Before comparing two check-ins it grades five things about how the photos were taken: how bright the light was, how evenly it fell, how much of the frame your face filled, and how your head was turned and tilted. Every comparison arrives with one of four confidence labels. If the two photos came from different analysis tiers, it refuses outright instead of fudging it. The refusal gets its own screen and its own explanation, because "I cannot tell you" is a real answer and pretending otherwise is how this whole category lost people's trust.
It never makes a number up. Most phone browsers cannot measure your head angle or how far away you are. I could have sent zero for those. But zero means "perfectly square on, identical distance", which is the strongest possible evidence, invented out of nothing. So signals that were not measured get left out of the grading and cap the label at "directional check". The capture screen tells you which ones it managed to measure before you upload anything.
You commit before you get to conclude. When you start a trial you name one metric you think a product will move, and how long you will give it. That gets recorded before any evidence exists. Start a trial from a check-in you already took and the server marks it exploratory, permanently, because a guess made after seeing the data is a different kind of guess. Only one trial runs at a time. That is a database rule, not advice. Run two products together and you cannot tell which one did anything.
The diary tracks what else was going on. Twenty-two stickers in three groups: what you noticed, what happened to you, what you did to your skin. The last two count against a result. What you noticed never does, because "my skin stung" is the thing that needs explaining, not the explanation. Three taps and you are done, no typing. Add a photo and it sits on the page like an instant print, taped at the corner. Then when a trial ends, the verdict tells you how many days of that window had something else going on and why each one matters. Log nothing and it says so, because an empty diary is not the same as a quiet month.
Nothing is ever green or red. A number going down is not a failure. There is no green or red version of the change indicator to reach for. Only a sign, an arrow and a word.
Which YouCam APIs I used
| API | What it does here |
|---|---|
| AI Skin Analysis, HD and SD | Every reading in the app. The server picks HD or SD by measuring the short side out of the image bytes, never by trusting what the phone claims. |
| File API | Upload, then create the analysis task against the file_id it hands back. |
| Detection masks | Copied into my own storage the moment they arrive, so they outlive the provider's retention window and a diary entry never breaks because a link expired. |
Analysis is charged by how many concerns you ask for, not per call. HD costs 12, 16, 20 or 22 units for 1 to 4, 5 to 8, 9 to 12 or 13 to 16 concerns. I was asking for all sixteen while the app only showed eight, which is 22 units instead of 16. On a 1,000 unit allowance that is 45 scans instead of 62. There is now a function that prices a call before it goes out.
Three APIs I deliberately did not use. Photo Enhance, Color Correction and Photo Lighting all change the pixels I am trying to measure, so they would quietly corrupt the reading. Skin Simulation shows someone a better version of their face before anything has actually worked, and this app is about not doing that.
Who it is for
If you buy skincare: a straight answer to "did that do anything", and permission to stop paying for something that did not. Most routines are an unmeasured experiment costing a few hundred a year.
If you sell it: real evidence per product, from people who agreed to give it, with the photo conditions attached to every reading. That is worth far more than a star rating. It is also what you would need to honestly say "this worked for people like you" instead of guessing from what they bought before.
If you run a clinic: something to look at together between appointments, and refusals that stop a patient reading too much into a change their holiday caused.
Proof, not promises
I tested the whole pipeline against the deployed app using a face generated by YouCam's own text to image endpoint, so no real person's photo was involved. Eight concerns scored, eight detection masks stored, overall 73.25, photo and masks both loading through signed links, done in about nine seconds.
The scripts that do this are in the repo, so you can run them yourself: probe-live-face.mjs, probe-e2e.mjs, probe-join.mjs, probe-oauth.mjs, probe-diary.mjs, probe-note-photo.mjs.
There are 85 tests. Three worth actually reading:
- one proves two otherwise identical scans only reach full confidence when the pose was genuinely measured
- one proves a photo is never rejected because of a signal nothing ever measured
- one runs in its own process with the development flag switched off, proving those endpoints cannot be reached without it
How it is built
React, Vite and Tailwind on the front. Hono on the back, running as a normal Node server on my laptop and as a bundled AWS Lambda when deployed, behind an API Gateway, with a private S3 bucket and Neon Postgres. The confidence engine and the metric registry are a separate package that touches no network and no database, which is why they are properly tested.
The API serves the web app from the same address as itself. That is not laziness. Camera access needs HTTPS, so a phone needs one secure address, and serving only the compiled output means a dev server never exposes the project folder, which is where .env lives.
Three ways in: Google, an email and password, or a shared code for reviewers. Google and email both go through Neon Auth. I use it to check who you are and then issue my own session, because the token it hands back expires after fifteen minutes and I am not signing people out halfway through a check-in.
Try it
Open the link, tap Continue with Google, and you are in. Or use the reviewer code in the notes below. No verification email, nothing to wait for.
Built With
- amazon-web-services
- api-gateway
- aws-lambda
- cloudformation
- drizzle-orm
- hono
- neon
- neon-auth
- node.js
- perfect-corp
- postgresql
- react
- skin-analysis
- tailwindcss
- typescript
- vite
- youcam-api
- zod
Log in or sign up for Devpost to join the conversation.