All projects
Shipped · Active · since 2025 ·
react nativefastapipostgress3social network

Hopfly

A friends-only social app for beer - post what you're drinking, and your friends like it, comment on it and drink along.


Hopfly

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.

A comment thread with a GIF, and a profile with its stats and post grid


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

FeatureWhat it does
📸 PostingPhoto 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 feedYour posts and your friends’, newest first. Likes, dislikes, threaded comments with GIFs and @mentions, and a list of who liked a post.
🗺️ MapWhere you and your friends posted from, with clustered pins - a social map, not a venue finder.
📅 MeetupsPlan a get-together, all friends invited, in/out answers, a reminder, comments, and an album that fills itself from the posts around it.
🏆 Levels & achievementsXP fills 100 levels and 21 ranks. A new rank posts a mock-corporate “promotion” to your friends, who can answer it.
🪙 Hops & PintoCoins that come with XP, spent on Pinto the mascot in a shop of 92 items. Pinto can be posted too.
🎲 GamesParty 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.
🎰 CasinoSix provably fair games and a lootbox, Hops only, never money, and 18+.
📖 Beer lexiconOne shared catalogue of brands, beers and barcodes. Anyone can suggest a fix; the admin decides.
🔔 NotificationsActivity inbox and pushes for likes, comments, mentions, tags, friend requests, promotions and meetups, with per-type and per-friend switches.
🛡️ SafetyReport posts, comments or people, block someone, hide their comments, an age check against the local drinking age, and full account or data deletion.
🎨 Hopfly PopA chunky, warm design with selectable colour palettes (including a dark one), English and German, an app tour and home-screen widgets.

The drinking games lobby, and the level-up screen for a new rank


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

LayerChoice
AppExpo SDK 56, React Native 0.85, React 19, Android plus the same code as a PWA via react-native-web
RoutingExpo Router (file-based)
StylingNativeWind 5 + Tailwind v4, run-time CSS variables for the palettes
Client stateTanStack Query 5 for server state, Zustand 5 + MMKV on the device
API clientHey API - typed SDK and query keys generated from the backend’s OpenAPI spec
NativeVision Camera, Mapbox, Reanimated 4, three custom Kotlin modules (video clips, widgets, in-app updates)
BackendFastAPI on Python 3.13
DatabasePostgreSQL via Piccolo ORM and asyncpg, with auto-generated migrations
StorageCloudflare R2 (S3 API via boto3), photos processed with Pillow
AuthJWT access and refresh tokens, Google sign-in, email codes via Resend
PushExpo push for the app, Web Push (VAPID) for the browser
AdminNext.js 16 dashboard for moderation, the catalogue, app updates and the Hops economy
Website & docsAstro 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

  1. Sign in with Google or an email address, and confirm your age.
  2. Add your friends - Hopfly is pretty empty without them.
  3. 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.