Who or What is it?: A Vibe-Coded Quiz App With 1 Sale (Postmortem)
October 7, 2026 · 1352 words
| Question | Answer |
|---|---|
| What it is | A picture quiz: see a person or a thing, name it. Scientists are the biggest category. A paid unlock adds all pictures and categories. |
| Builder | Developer (20+ years) |
| AI tool | Claude (he names Claude Fable and Opus), plus some GPT for App Store screenshots |
| Stack | Cloudflare Workers + Durable Objects, React 19, TypeScript 5.9, Vite 8, Capacitor 8, native Swift/StoreKit |
| Time to launch | Not disclosed |
| Revenue | 1 purchase, from a friend testing (self-reported, Sept 2, 2026). Unlock price not disclosed. |
| Source | Show HN, Sept 2, 2026 |

Most case studies on this site start with a revenue number. This one starts with a very honest one. A developer with more than 20 years of experience vibe-coded a picture quiz app, added a paid unlock, and posted it on Show HN. His sales count at the time: one purchase. In his words, it came from "a friend testing :p".
That is not a failure story in the dramatic sense. The app is still live, and he is still working on it. But it is the most common outcome in indie apps, and almost nobody writes it down. So it is worth a close look.
A note on timing: the sales number is a snapshot from the September 2, 2026 Show HN post. The app's age at that point isn't disclosed, the builder hasn't confirmed anything newer, and sales may have changed since.
What he built
"Who or What is it?" is a simple game. You see a picture of a person or a thing, and you name it. The idea started small. He wanted a quiz of scientists he admires, like Lee Smolin and Max Tegmark. He is a big fan of science interviews on YouTube. Over time it grew to many categories, but scientists is still the biggest one.
He calls it one of his first apps that was purely vibe coded. Vibe coding means you describe what you want to an AI model and let it write most of the code. He says he mainly used Claude models, which he names as Claude Fable and Opus. He used some GPT for the App Store screenshots.
The stack is serious for a quiz game:
- Cloudflare Workers and Durable Objects for the backend. Workers are small server functions that run close to users. Durable Objects add storage with a single source of truth.
- React 19, TypeScript and Vite for the web app.
- Capacitor 8 to wrap that web app as a native mobile app.
- Native Swift and StoreKit for Apple's in-app purchases.
The privacy policy adds a few details. There is no account and no sign-up. Play data stays on the device by default. Purchases go through Apple or Google. On iOS, the app sends Apple's signed proof of purchase to the game's server once and gets back an unlock token. Unlock codes can also be redeemed on the web.
What he expected
He did not post a revenue goal. He said the app turned into a halfway commercial product because it sells a full version. That wording matters. The paid unlock came after the idea, not before it. The app started as something he wanted for himself.
He asked HN for feedback and, if people enjoyed it, some nice reviews. An Android version was planned for the following weeks.
What happened
- The Show HN post got 2 points and no comments.
- Sales: one purchase, from a friend.
- Since then, the original domain,
whoorwhatisit.com, redirects to quiz.pictures. The new page describes it as "a picture quiz you can play with friends." - The privacy policy now describes a web app, an iOS app and an Android app.
I couldn't find a newer sales number.
The real reason (my read)

He did not write a postmortem, so this part is my opinion, not his.
The build was not the problem. The stack is modern, the purchase flow is thought through, and the privacy stance is strong. The problem is that a paid unlock needs people to see the free part first. A Show HN post with 2 points reaches very few of them. With a small audience, one purchase is a normal result, not a bad one.
A quiz is also a crowded category. "Guess the picture" apps are everywhere. The unusual part here is the scientists category. That niche could be the hook, but a general "who or what" name hides it. The new "play with friends" tagline may be a new angle. Testing angles like that is the right instinct.
What to do instead
If you are building something similar, here is what I would copy and what I would change.
- Decide who pays before you build payments. Write one sentence: "People who love X will pay Y for Z." If you can't, ship free first.
- Lead with your niche. "A quiz of physicists and cosmologists" is easier to share than "a picture quiz." Niche communities share niche things.
- Plan distribution with the build. One launch post is one shot. Line up five places where your niche already gathers.
- Count viewers, not just buyers. If 50 people saw the paywall, one sale is data. If 5 did, it isn't yet.
- Keep the good parts. No account, local data and server-side purchase checks are worth copying as they are.
If you vibe-code this
This app type is a hybrid app (web code wrapped for mobile) that unlocks paid content with a token from a serverless backend. These checks apply to any app of this type. They are not a comment on this app.
- Verify every purchase on the server. Never trust the app when it says "I paid." Check Apple's signed transaction on your backend, as this app's privacy policy describes.
- Sign unlock tokens. A token should be something only your server can create, not a plain "unlocked=true" flag.
- Rate-limit code redemption. Web unlock codes can be guessed if you allow unlimited attempts. See API rate limiting.
- Keep secrets out of the bundle. A Capacitor app is JavaScript in a zip. Anyone can open it. See environment variables.
Here is a minimal signed unlock token in a Cloudflare Worker:
// Issue a token only AFTER the purchase has been verified server-side
async function signUnlock(deviceId: string, secret: string): Promise<string> {
const payload = `${deviceId}.${Date.now()}`;
const key = await crypto.subtle.importKey(
"raw",
new TextEncoder().encode(secret),
{ name: "HMAC", hash: "SHA-256" },
false,
["sign"]
);
const sig = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(payload));
const b64 = btoa(String.fromCharCode(...new Uint8Array(sig)));
return `${payload}.${b64}`;
}
// `secret` comes from env (wrangler secret put UNLOCK_SECRET), never from the app
For more on login and tokens, see secure authentication for vibe coders.
Shipping a paid unlock and not sure the purchase flow holds up? I review vibe-coded apps before launch. Email [email protected].
Key takeaway
AI made building this app easy, even with a serious stack. It did not bring buyers. One sale from a friend is what a paid app looks like before anyone knows it exists. Decide who pays and where they hang out before you write the paywall.
More case studies: Vibe-coded apps making money. Before you launch: Vibe coding security guide.