Inspiration
Every friend group has one. The pool table at the flat, the FIFA rivalry, the Friday table tennis at the office. And every one of those groups has the same argument: who's actually better?
Usually the answer lives in one person's head, or a notes app, or a WhatsApp message from three months ago that everyone remembers differently. The person keeping score always seems to be winning.
I wanted an app that just settles it. Log the game in a couple of taps, and let the table say who's best. But a scoreboard only works if everyone trusts it, so the most important feature turned out to be a rule, not a screen: nothing counts until both players agree.
What it does
Krovo keeps score for you and your friends, for any game: pool, darts, FIFA, chess, padel, cards, or the argument you have every week.
- Log a match in seconds. Pick the group, the game and who played. A score is optional.
- Both sides confirm. Your result sits as "waiting on Ahmed" until Ahmed agrees. If he says the score was different, it goes back to you. Only agreed results reach the table.
- Standings that settle it. Win rate, form, streaks and a table per game, per group, per season or all time.
- Head to head. Your full record against any one person.
- Groups for the flat, the five a side, the office. Invite with a link or a code.
- Play people who aren't on Krovo. Log them anyway. If they join later, they get a claim link and their whole record comes with them.
- It works on your own, from the very first match, with no account needed.
- No ads and no tracking. No advertising ID, no contacts, no location.
How it makes money
Krovo Pro, through RevenueCat: £5.99 a month or £39.99 a year, on one pro entitlement.
Pro gives you seasons with a champion at the end, your own awards, every stat and a recap card at the end of each season. The interesting part is League Mode: you point your Pro at one of your groups, and the season, table and awards switch on for everyone in that group.
That was a deliberate choice. My first plan was a group subscription, but then everyone in the group gets everything and nobody ever sees a reason to buy. With personal Pro, one person pays and the other five play in their league every week and see what it adds.
It also made the RevenueCat setup more interesting than "check an entitlement":
- The app calls
logInwith the user's id, so a purchase is tied to a person and not an anonymous device. Without that, the purchase succeeds, the buyer's own app turns Pro on, and the other five people in the group never get League Mode. It's a nasty bug because the person who paid can't see it. - A RevenueCat webhook (a Supabase Edge Function) writes entitlements into Postgres. The group's league checks "does a current member have Pro pointed here?" on the server, so no phone ever reads anyone else's billing.
- A small redeem code function hands out Pro through RevenueCat, for testers and judges.
How I built it
- Expo and React Native with Expo Router and NativeWind, in TypeScript.
- Local first. Every match is written to SQLite on the phone first and synced through an outbox, so logging works with no signal at the side of a pitch.
- Supabase for accounts and sync: Postgres with row level security on every table, 46 migrations, and Edge Functions for the RevenueCat webhook, redeem codes and a sweep job that closes lapsed votes.
- Sign in with Apple, Google, or a guest account, so nobody has to make a password to keep score of a pool game.
I also wrote the whole system design before writing any code, then reviewed it like someone else had written it. That review found sixteen problems, six of which would have broken the very first database migration. Fixing them on paper cost an afternoon. Fixing them after launch would have cost people their match history.
Challenges I ran into
- Making "confirmed" mean something. Once results could be edited, a lot of simple assumptions broke. What happens to a confirmed result someone edits? Who has to agree again? I ended up treating a score like a contract: any change goes back through the same agreement.
- Claim links in in-app browsers. WhatsApp and Instagram often open links in their own browser, which never hands the link to the app. So a claim link now lands on a web page that works either way.
- Everything around the store. Android needs 12 testers for 14 straight days before it can go to production. We hit that on September 17, and the build is in review now.
Accomplishments I'm proud of
- A real two sided agreement flow that feels quick instead of like paperwork.
- A pricing model where one purchase makes the app better for a whole group, built on RevenueCat and server side entitlements.
- The design: amber always means you, blue always means your opponent, and colour is never the only signal, so it works in greyscale too.
What I learned
The hardest part of a social app isn't the screens, it's trust. Every feature in Krovo ended up being about whether people believe the table, and "nothing counts until you both agree" does more for that than any chart.
What's next for Krovo
- Finish Google Play review and ship to the App Store
- Launch with real friend groups first and let them tell me what to build next
- Scan to log: take a photo of a scoreboard and let Krovo read the result
Why open source
I'm a student at NUST in Pakistan, and I'm submitting Krovo to the Next Gen track as an open source project. The full client, database migrations and Edge Functions are on GitHub under MIT, with setup instructions in the README. It runs on the device with no backend at all, so anyone can clone it and try it in a browser in a couple of minutes.
Built With
- deno
- expo.io
- nativewind
- postgresql
- react-native
- revenuecat
- sqlite
- supabase
- typescript
Log in or sign up for Devpost to join the conversation.