Hopfly
Post what you’re drinking. Your friends see it - nobody else does.
Hopfly is a social app for beer, built for one friend group. You snap the beer you’re holding, pick the brand, and it lands in your friends’ feed, where they like it, comment on it, and tag along next time. Around that sits a map of where everyone posted from, meetups that collect their own photo album, levels with a mock brewery career, a mascot called Pinto, and a stack of party games. It runs on Android and in the browser, backed by its own FastAPI service.
What it is
Hopfly is built around the post: a photo or a 3-second clip taken with the in-app camera, the brand and beer, the pour size in millilitres, and optionally a caption, a location and the friends you were with. The beer comes from a shared catalogue, gets typed in, or is found by scanning the barcode on the bottle. No signal in the beer garden? The post waits on the phone and goes up by itself later.
Everything else grows out of that:
- A feed of your friends - your posts and your friends’ posts, newest first, and nobody else’s.
- Reactions - like or dislike a post, comment and reply, add GIFs, @mention friends.
- Meetups - plan a get-together, everyone answers in or out, and the posts made around it become an album.
- Your profile - up to three pinned posts, a grid of the rest, and three numbers: posts, unique beers, and how often you were tagged.
- Levels and Hops - activity earns XP across 100 levels and 21 ranks of a tongue-in-cheek brewery career, plus Hops, a coin you spend on dressing up Pinto.
It’s friends-only by design: there are no followers, no public profiles and no way to browse strangers’ posts.

Why it exists
The obvious app for logging beer is Untappd, and it’s built for a different job: public check-ins, venue pages, brewery marketing and badges that reward drinking more. That’s not what a group of friends wants when they share a beer photo.
Hopfly is the reaction to that:
- Authentic social over commercial. No ads, no premium tier, no analytics, nothing to buy with real money. XP for likes only comes from other people - liking your own post earns nothing.
- Private by default. Only friends see your posts, and the API doesn’t even confirm that a stranger’s post exists. Location is opt-in, view counts are the author’s alone, and nobody learns who viewed.
- No drinking pressure. No streaks, nothing that rewards frequency or volume. Posting only earns XP for the first two posts a day, and the drinking games say up front that any drink counts - water too.
It started in December 2024 as an Ionic/Angular app, moved to Expo on Supabase in 2025, and is now on its second generation: a full re-platform onto its own backend, with the old data migrated across.
Core features
| Feature | What it does |
|---|---|
| 📸 Posting | Photo or 3-second clip from the in-app camera, brand and beer from the shared catalogue or a barcode scan, pour size, caption, location and tagged friends. Works offline through an outbox. |
| 🍻 Friends feed | Your posts and your friends’, newest first. Likes, dislikes, threaded comments with GIFs and @mentions, and a list of who liked a post. |
| 🗺️ Map | Where you and your friends posted from, with clustered pins - a social map, not a venue finder. |
| 📅 Meetups | Plan a get-together, all friends invited, in/out answers, a reminder, comments, and an album that fills itself from the posts around it. |
| 🏆 Levels & achievements | XP fills 100 levels and 21 ranks. A new rank posts a mock-corporate “promotion” to your friends, who can answer it. |
| 🪙 Hops & Pinto | Coins that come with XP, spent on Pinto the mascot in a shop of 92 items. Pinto can be posted too. |
| 🎲 Games | Party games where any drink counts (Never Have I Ever, Kings Cup, Truth or Drink, Word Bomb), and Pinto’s own games without drinking - solo or online with friends. |
| 🎰 Casino | Six provably fair games and a lootbox, Hops only, never money, and 18+. |
| 📖 Beer lexicon | One shared catalogue of brands, beers and barcodes. Anyone can suggest a fix; the admin decides. |
| 🔔 Notifications | Activity inbox and pushes for likes, comments, mentions, tags, friend requests, promotions and meetups, with per-type and per-friend switches. |
| 🛡️ Safety | Report posts, comments or people, block someone, hide their comments, an age check against the local drinking age, and full account or data deletion. |
| 🎨 Hopfly Pop | A chunky, warm design with selectable colour palettes (including a dark one), English and German, an app tour and home-screen widgets. |

Vision
Hopfly is feature-complete for the friend group, so what’s next is less about adding and more about polish: running the newest work (games, casino, video posts, meetups) through real use on real phones, keeping the Play Store release healthy, and smoothing out the web app for friends on iPhones.
The guardrails stay the same for anything new: it has to stay friends-only, it can’t push anyone to drink more, and it can’t turn the group into a market.
Technical details
Hopfly is a handful of repositories that fit together: the app, the backend, an admin dashboard, a one-off migrator for the old data, a landing page and a documentation site.
Stack
| Layer | Choice |
|---|---|
| App | Expo SDK 56, React Native 0.85, React 19, Android plus the same code as a PWA via react-native-web |
| Routing | Expo Router (file-based) |
| Styling | NativeWind 5 + Tailwind v4, run-time CSS variables for the palettes |
| Client state | TanStack Query 5 for server state, Zustand 5 + MMKV on the device |
| API client | Hey API - typed SDK and query keys generated from the backend’s OpenAPI spec |
| Native | Vision Camera, Mapbox, Reanimated 4, three custom Kotlin modules (video clips, widgets, in-app updates) |
| Backend | FastAPI on Python 3.13 |
| Database | PostgreSQL via Piccolo ORM and asyncpg, with auto-generated migrations |
| Storage | Cloudflare R2 (S3 API via boto3), photos processed with Pillow |
| Auth | JWT access and refresh tokens, Google sign-in, email codes via Resend |
| Push | Expo push for the app, Web Push (VAPID) for the browser |
| Admin | Next.js 16 dashboard for moderation, the catalogue, app updates and the Hops economy |
| Website & docs | Astro landing page, Docusaurus docs with a generated API reference |
Engineering decisions
- The backend enforces everything. The first version kept its rules in Supabase and its queries in the screens. V2 moved every rule into its own API, and one predicate -
can_view_user_content- is the single definition of who may see whose content. The feed, the map, profiles, comments and stats all go through it. - Hidden means hidden. Reads of anything outside your circle answer 404, not 403 - a 403 would confirm the thing exists. Ownership checks on writes keep 403, because there the caller already knows.
- A generated client. The app never builds a URL. Its SDK, types and query keys are generated from the backend’s OpenAPI spec, so an API change surfaces as a type error instead of a runtime bug.
- Ledgers, not counters. XP and Hops are append-only ledgers; a balance is the sum of its rows. Levels never go back - a deleted post keeps its XP - and an admin correction is a new grant row, not an edited number. XP rules, levels, ranks and shop prices are data, not code, so tuning needs no release.
- Taps feel instant. Reactions render from local component state, with the shared cache updated alongside rather than driving the UI. When something feels slow, the fix is the latency, never the animation.
- Offline posting. A post is written to an on-device outbox with a client-generated id, and creating a post is safe to repeat - a retried upload can’t produce a duplicate.
- A provably fair casino. Every round is drawn from a committed server seed, a client seed and a nonce, and booked against the Hops ledger.
- Built for real data. The development database holds the group’s migrated history and nothing fake; tests run against their own throwaway databases. The V1 migration rebuilt every account, post, like, comment and friendship from a Supabase export.
- Updates without a store. Every API response carries version headers, so the app can show an update screen - blocking for a breaking change - wherever it was installed from.
Get & use Hopfly
Install (Google Play)
Hopfly is on the Play Store: Get it on Google Play.
Use it in the browser
On an iPhone or a laptop, open web.hopfly.app - it’s the same app as an installable PWA. Add it to your home screen and it behaves like a native app.
First run
- Sign in with Google or an email address, and confirm your age.
- Add your friends - Hopfly is pretty empty without them.
- Tap the beer button, take a photo, pick the brand, and post. Cheers!
More about the project lives on the landing page, hopfly.app.
Hopfly - beer with your friends, not for an audience.