My wife has a lot of essential oils. Like, a lot. Shelves of them. A dedicated cabinet. More arriving in the mail with some regularity. However, she has always had an issue about which oils she has and how much she has left. So I did what any developer-spouse would do: I built her an app.
The Problem Was More Interesting Than It Looked
At first glance this is a solved problem. There are apps for this. But none of them felt right — too many features, too brand-specific, too fussy to actually use in the moment.
What she actually needed was: open the app, point the camera at the bottle, done.
That constraint made it interesting to me. This wasn’t just a CRUD app — it was a chance to build something genuinely useful with the Claude Vision API, which I’d been looking for an excuse to play with anyway.
What This Actually Is
It's a progressive web app (PWA) built on Laravel and Livewire. You open it on your phone, tap the scan button, take a photo of the bottle label, and it uses Claude’s Vision capabilities to extract the oil name, scientific name, brand, and bottle size — then drops you into a confirmation screen where you can fix anything before saving.
It installs on your home screen like a native app. No App Store. No React Native. Just a browser-based PWA that feels like an app because it behaves like one.
The stack is deliberately familiar to me:
- Laravel 12 for the backend
- Livewire for reactive UI without writing a separate frontend
- Tailwind CSS for styling
- MySQL for the database
- Claude API for the actual label-reading magic
The label extraction is handled by a dedicated service class that takes a base64-encoded image, sends it to Claude with a structured prompt, and gets back a JSON object with all the fields pre-filled. It works surprisingly well across different brands and label styles — far better than I expected on the first pass.
What I Learned
Claude Vision is legitimately good at reading product labels. I went in skeptical about edge cases — oils with elaborate script fonts, dark bottles, worn labels — and came out impressed. The prompt took some iteration to get the JSON output clean and consistent, but the underlying capability was there from the start.
This isn’t a product. It’s not going on the App Store. But it’s running, my wife actually uses it, and the frankincense problem has been solved. That’s a win.