Case study 03

Mind the Product · June 2026

Vibeshelf

A recommendation engine that takes "cozy adventure like a Miyazaki film" and returns books, films and games in one place. Built with one other person over a hackathon weekend — I owned the framing, scope and design, she owned the backend.

My role
Ideation, design, user research, deployment
Team
2 — Shreya Sinha owned the backend
Timeline
Jun 2026, one weekend
Built for
Mind the Product World Product Day hackathon

Llama 3.3-70B · Groq · Jaccard similarity · 547 titles, in memory

Vibeshelf home screen: the headline Your next obsession is one vibe away over three category cards — Books, Movies and TV, and Games.

The home screen. Books, films and games sit at the same level because the thing being matched is the feeling, not the medium.

The problem

Everyone has closed Netflix after ten minutes without picking anything. The problem is not a shortage of options, it is that the search vocabulary is wrong. Nobody wakes up wanting "Drama." They want something like Narnia but with real stakes, or something dark and melancholic in the way NieR is dark and melancholic.

Vibeshelf is a recommendation engine built around that. You describe a mood in plain language and get ranked results across books, films and games together, rather than three separate apps that each pretend your taste stops at their category boundary.

It was built over a weekend at Mind the Product's World Product Day hackathon, by two of us. I owned the framing, scope and design; my teammate owned the backend and the server logic. It is live and it works, but it has no real users, so nothing below is validated by anything except our own testing.

A text box instead of a genre tree

My first instinct was that recommendation algorithms are bad. That framing is wrong, and it leads somewhere useless — it points you at building a better ranking model, which is not a thing two people can do in a weekend and not actually where the failure is.

That reframing is what made the project tractable. Translating messy human phrasing into structured tags is exactly what a language model is good at, and it meant the hard part became prompt design rather than model training.

The second thing I decided early was that this had to work across books, films and games at once. Every existing product is siloed by category, but taste is not — someone who wants melancholic and atmospheric wants it in a novel and a game equally. Crossing the silos was the actual product idea; the vibe search was the mechanism.

Vibeshelf movies page: a large free-text field labelled Describe the vibe you're after, three example prompts, a grid of 18 vibe chips, and a Find my vibe button.

Naming the model on the chip — Llama 3.3-70B via Groq — was deliberate. It sets the expectation that this is interpretation, not lookup, before anyone judges the first result set.

Show the match, then let people argue with it

A vibe description goes to Llama 3.3-70B, served through Groq's free tier, which extracts structured tags. Those tags get scored against a curated library of 547 titles using Jaccard similarity, and results render as an interactive constellation — closer to the centre means a stronger match. Because a fixed library would otherwise cap what you can be shown, the system also generates fresh picks live, so a search never comes back thin.

Rating a result with a thumbs up or down adjusts the weighting on its tags, so later searches re-rank in your direction. It is a feedback-weighted re-ranker rather than anything trained, and I want to be accurate about that — it is a simple mechanism, and the interesting part was tuning how hard a single rating should push. Too aggressive and one bad rating poisons everything after it; too gentle and rating things feels pointless.

Vibeshelf results: 192 matches shown as cards, each with a category label, match percentage ring, title, one-line synopsis, matched vibe tags, and thumbs up or down feedback controls.

192 matches from 547 curated titles. The count is high on purpose — breadth first, then the feedback signal narrows it, rather than a confident top three we could not justify.

The loop has to pay off beyond one search

Around that sits the part that makes it feel like a product rather than a search box: saved shelves, custom named lists, a radar chart of your taste profile, and a light social layer where you can look at other people's shelves.

Vibeshelf taste profile: a genre affinity radar chart beside a ranked You Love list — Sci-Fi and Futuristic at 100 percent down to Political Intrigue at 33 percent — and a separate Not Your Vibe row showing Epic Fantasy at 12 percent.

Giving "not your vibe" a row of its own is the call I would defend hardest. Epic Fantasy at 12% proves the system heard the negatives, and a profile that only lists what you love can never be visibly wrong.

What broke

A 547-title library on purpose

The obvious way to build a recommendation engine is to plug into a real catalog API and get hundreds of thousands of titles. We hand-curated 547 instead, so the vibe matching — the part that had to work — could be tested in a weekend. Coverage is the ceiling everything else hits.

The fallback is doing too much work

Ask for something outside the curated set and you fall through to live AI generation: no scoring, no constellation position, less confidence. That fallback is doing more work than I would like, and it is the first thing I would fix.

Nothing survives a restart

Everything is in memory, so state does not survive a restart. For a weekend demo that is fine. For anything real it is the first blocker.

The rest of the product

It shipped as a product rather than a demo: accounts and handles, saved shelves, custom lists per medium, the taste profile as a tab rather than a settings page, and a social layer for finding other people's shelves — all on free infrastructure. Endorsements are "stamps received", not likes, because a stamp is something you press onto a thing you have actually read.

One search across all three media, but three separate shelves. Mixing the results is the whole point; mixing what you have saved is just mess — that split was the easiest call on the project to defend.

What we cut to ship in a weekend

Messaging between users
The social layer only had to prove that finding someone else's shelf was worth doing. An inbox brings moderation, notifications and abuse handling with it — none of which a weekend build can answer honestly, and none of which change whether the idea works.
Adding a book by photographing it
Snapping the cover of a book you have just finished is the nicer gesture, but it needs an image pipeline and a matching step that fails exactly where it is used — a paperback held at an angle in bad light. Search-and-save is two taps and never misses.

Both are on the list for a version with more than a weekend in it. Cutting them was not the hard part; agreeing they were cuts rather than failures was.

See it running

Walkthrough

A short pass through vibe search, the ranked results, and the taste profile — recorded on the live build, not a deck.

Watch on YouTube ↗ (opens in a new tab)

What I'd change, and what's next

I would replace the hand-curated set with a real catalog API and keep the hand-tuned tag vocabulary as the scoring layer on top, so coverage stops being the ceiling.

I would test the tag translation against people other than us. We validated that the vibe search worked by trying it ourselves, which tells you it works for two people who already know what it is supposed to do.

And I would move off in-memory storage before adding a single new feature. Persistence is not interesting to build and it is the thing standing between this and being usable by anyone.

Getting structured output from a language model is a design problem rather than an intelligence problem. Llama kept wrapping its JSON in conversational text, so we had to parse defensively. That is what happens when you ask a chat-shaped thing for a machine-shaped answer.