AAOA.studio · Case Study · iOS · SwiftUI
Most fragrance apps want you to buy more. Prefume is built on the opposite premise: your collection is already full of things you love and forgot about. Use them. Remember them.
01 · The Journal
Fragrantica, Parfumo, the fragrance forums: they are discovery machines optimised for the next purchase. The business is surface area (new releases, new houses, trending notes, community wishlists) and they are very good at telling you about the next thing to smell, but none of them help with the forty things already on your shelf. The result is a familiar situation, bottles worn twice and shelved, a sample from six months ago with no memory attached to it, the collection growing faster than the attention it receives. Prefume started from exactly that shelf: a decant rediscovered at the studio in early 2025, with no memory of how it had worn. The first sketch of the timeline view was made that afternoon in a SwiftUI file.
The goal was not to help you find more. It was to help you remember what you already have.
Prefume meets the natural cadence of the practice: a journal that captures the full testing arc from first spray to collection decision. Every fragrance gets a timeline (first test, 2-hour check-in, end-of-day impression, the compliment in November, the decision to repurchase) so impressions do not fade and opinions do not shift without a record.
02 · Today
The Today view answers a simple question: given your collection, the weather, and what you wore recently, what should you reach for this morning? It only recommends from bottles you already have, a deliberate constraint that keeps the focus on using your backlog rather than growing it. The design question was not how to surface the best new scent, but how to help someone rediscover the one they already bought.
The first version of the recommendation system was too complex too early, using nine scoring dimensions that required months of journal data to mean anything. For a new user with twenty fragrances, nine dimensions of signal were nine dimensions of noise. The rebuild used three honest inputs: collection status, weather fit, and aggregate preference patterns. Additional complexity was only added where it had a clear design justification: suppressing fragrances you rated poorly yesterday and scaling the repeat window as your collection grows. The system became simpler and more useful at the same time.
The rebuild to three inputs was not giving up on quality. It was making the system honest about what data was actually available.
Each fragrance in the reference catalogue carries pre-computed context affinities (weather, time of day, season) so recommendations feel contextual without pretending to know you better than your journal does. The catalogue itself sits at 40,593 fragrances across 1,671 brands, and coverage is still the main gap: in a niche this deep, even forty thousand entries is not enough for a collector looking for a regional house or an obscure extrait.
03 · Craft
Fragrance collecting is sensory, and the app needed to match that register not just in what it does but in how it feels. Every craft decision starts from the same design principle: the interface should feel like the practice it serves, translating physical rituals into digital interactions that collectors immediately recognise.
Logging a wear triggers a SpriteKit dual-emitter spray animation that fires from the bottom of the screen, droplets and mist dissipating at the edges. Getting the mist right took longer than the rest of the logging flow combined; the emitter values were eventually tuned against slow-motion footage of an actual atomiser filmed on a desk and I'm still working on it. It matches the physical act of applying a fragrance, and collectors noticed immediately: the gesture signals that the app understands the ritual, not just the data model. A small interaction that became one of the most referenced details in user feedback.
Every view has a background that responds to what is in your collection. Colours extracted from perfume notes blend into ambient gradients (warm ambers after a morning wear, cool blues after fresh citrus, deep purples after a patchouli-heavy evening). The app's visual temperature shifts with the day's wears the way a collection does, making the interface feel alive and connected to the content rather than a static container.
The spray gesture, the gradient backgrounds, the paper-like entry cards: they are not individual features but a consistent design language built on the same data the journal collects. Every surface speaks the same vocabulary (collection, wear history, preferences, visualised consistently) because the system is consistent, not the individual screen. The result is an interface where design decisions reinforce each other rather than competing for attention.
04 · Model
Most collectors have fewer than fifteen fragrances they wear regularly. The free tier is designed around that reality: up to twelve in the collection, twelve on the wishlist, the full journal, the full recommendation engine, the full catalogue search. Everything that makes the app worth using is free. The bet is that collectors who commit to the practice will pay to remove limits, not to unlock core features behind a paywall. It is the same reasoning as the missing discovery feed: the app earns trust by refusing to squeeze money out of users.
Extract is a one-time lifetime purchase, no subscription. It removes the collection cap and enables bigger CSV import for users migrating from spreadsheets. The name is deliberate: in perfumery, extract is the highest concentration. It signals purity, not just more features. Revenue so far is modest, ~$300 at $25/user, which may be honest pricing for a niche tool, or a signal that the addressable market is smaller than the depth of the product suggests.
Outcomes
Engagement: 5 sessions per day is not manufactured, it maps directly to how collectors already think about a fragrance. The structured testing workflow (first spray, 2h, 4h, end-of-day) gives the existing practice somewhere to go instead of inventing new habits.
Positioning: users named the absence of commercial pressure as the primary reason they trusted the app, confirming that saying no to discovery and ads was the defining product decision. That conviction was not assumed in isolation; it was validated through a daily public build log on TikTok where users watched features take shape and responded in real time. The recommendation engine rebuild from nine scoring dimensions to three honest inputs was accelerated by that same channel, with users calling out complexity in their first two weeks.
Onboarding lesson: the testing workflow, recommendation system, and wrapped review are each defensible individually but together they create a steep first impression. The collectors who push through become devoted users, but some leave before seeing what the app becomes after a few weeks of journaling. Depth is the product's strength and also its onboarding friction.
Scope: 390 commits across SwiftUI, SwiftData, and GRDB. A SpriteKit spray animation, a recommendation engine spanning three architectural iterations, and a reference catalogue of 40,593 entries across 1,671 brands. The most important version numbers are not the build iterations but the design revisions: nine scoring inputs down to three, a discovery strategy replaced with a journaling one, an app that helps you use what you already own instead of buying more.
View on App Store