Swipe Watch
Can a streaming service learn your taste before you press play? An independent swipe-based discovery prototype built on the Disney+ and Hulu catalog.
The hypothesis
Streaming recommendations learn from expensive signals. A start, a finish, an abandon—each one costs the viewer a real commitment of attention, and the system has to wait for it. That makes preference data sparse and late: you browse for ten minutes and teach the recommender nothing until you actually commit.
A swipe costs a gesture. So the question is not whether a better model could rank the catalog, but whether discovery itself could be the preference-gathering loop—an interface that asks for taste directly instead of inferring it from what you finished last month.
Swipe Watch is that question, built. Real Disney+ and Hulu titles with real key art, dealt as cards: swipe left to dismiss, right for interested, up to flag one for later. Each gesture is a low-stakes signal, given before any viewing commitment.
- 3 dayscore build
- 106 titleshand-curated
- 10 cardsper session
- No backenddevice-local
The prototype
The first version was built to test exactly one thing: does swiping feel natural for expressing taste in a streaming catalog? That question is answerable at prototype fidelity—it needs real titles, real art and card physics, and nothing else. It does not need a recommendation engine, which is why there is not one.
Then the first version revealed its own gap. Sessions deal ten cards, and when the deck ran out you hit a dead-end screen. A preference-gathering loop that terminates after ten signals is not a loop. So the second iteration added an economy: swipes earn coins, coins unlock further discovery modes, and the end of a deck becomes a reason to keep going rather than a wall.
That is the meaningful product change on this project—not a feature added to a list, but a response to watching the core mechanic run out of room.


- FidelityValidated
No stack until the feel earns one
- What I encountered
- The question was whether a swipe feels like a natural way to express taste in a streaming catalog. The default way to build a card UI is a framework scaffold—React, a bundler, a build pipeline—before the first card ever moves.
- Over
- A framework scaffold. The larger application projects in this portfolio use one, and for anything meant to outlive a prototype it is usually the right call.
- What I decided
- Vanilla JavaScript, no framework, no build step. Firebase Hosting serves the repo root as-is, because there is no build output to serve.
- Why
- Interaction feel was the entire question, so everything between an edit and a reload was overhead. If the swipe felt wrong, the total loss was thirteen commits.
- Cost
- The prototype cannot grow into the product. Everything the scaffold would have supplied—types, components, a build step—is still missing, so the route from here is a rewrite rather than an extension, and the thing still running today is the throwaway.
- What it changed
- The constraint never had to be unwound. The first commit already carried a working swipe UI, session management and analytics, and the prototype still runs on it today with no build script and no runtime dependency.
- InterpretabilityMixed
Let the prototype fake its payoff
- What I encountered
- The loop being tested ends in a payoff—swipe, and the recommendations get better—and the back half of that loop was out of scope by design: no ML, no personalization. A prototype that says nothing after a swipe is testing a different, deader product.
- Over
- Honest copy—a plain session summary instead of a promise—which keeps every reaction interpretable, at the cost of demoing a loop with a visible hole in it.
- What I decided
- Copy that simulates the missing half, so the product demos as the thing it proposes rather than the fraction it implements.
- Why
- A prototype has to be shown to people who must imagine the finished version. Demoing the fraction asks them to imagine it anyway, and gives them less to react to while doing it.
- Cost
- Every reaction becomes uninterpretable. A response to the prototype cannot be separated from a response to the idea, because what people are reacting to is a payoff the software does not produce—and that is a ceiling on what any demo of this thing can establish, permanently.
- What it changed
- It demoed as the thing it proposes, which is what let the signal-density argument land in a conversation with Disney's EVP of Product. That is my own account of a conversation rather than a measurement, and by construction it could not have been one.
- LoopPending
Give the deck a bottom
- What I encountered
- The first build proved the swipe and then stopped: work through ten cards and you hit a dead end. Preference gathering that ends in a wall gathers preferences once.
- Over
- Keeping the prototype single-variable. A one-question experiment stays cleaner without a second untested mechanic layered on, and holding the economy back would have widened the coin-free baseline.
- What I decided
- An economy. Swipes earn coins and coins unlock further discovery modes, so the end of a deck becomes a reason to keep going rather than a wall.
- Why
- The price was legible—one coin per swipe makes an unlock cost exactly 25 swipes—and it was cheap to build on counters that already existed.
- Cost
- Adding a second mechanic compromised the baseline for the first. A coin-free production window does exist, but it is short and has never been examined, so whether the swipe alone sustains attention is now a question the prototype cannot answer about itself.
- Validation boundary
- Unresolved by construction. Whether the loop sustains engagement is a before-and-after question, and no flag, variant or cohort was ever set up to answer it. The mechanic's honest shape is also worth stating: an unlock opens another view over the same catalog rather than adding titles to it.
What I learned
The insight is signal density, and it is not “Tinder for streaming.”
An interface built explicitly to gather preferences produces far more signal for the same attention than one that waits for viewing behaviour, because it asks for something cheap. Ten cards is ten preference statements before the viewer has committed to anything. A browsing session produces one at most, and only if it ends in a play.
That changes what is upstream of a recommender. Instead of a model inferring taste from scarce, expensive, ambiguous events, it could be fed dense, explicit, deliberately given ones—collected at the moment a viewer is already deciding what to watch.
I demoed Swipe Watch to Disney’s EVP of Product, and the signal-density argument is what landed. That is the outcome this prototype was built to produce: it made an abstract argument about preference data concrete enough to react to. It is my own account of a conversation rather than a measurement, and it is evidence that the question is worth asking—not evidence that the answer is yes. No result from the prototype’s analytics has ever been published, and the save gesture, despite its label, files a title under a heading the app forgets when the session ends.
What the prototype does establish is that the interaction holds up: the gesture is legible, the deck is quick, and the loop has somewhere to go. What it cannot establish is whether the resulting signal actually beats viewing history, because it observes no viewing history to compare against.
Swipe Watch is not a recommendation engine. It is the interaction layer I would put upstream of one.

