Match

Swipe less, play more.


Inspiration

If you've ever wanted to play a casual game of badminton, you know the pain. You scroll through dozens of Facebook groups - most are inactive, poorly organised, or filled with players way above or below your level. Even when you find a group that looks right, you're hit with logistics: coordinating schedules, finding a court, splitting payments, and arranging transport. For many people the search alone eats up the free time they wanted to spend playing.

For beginners, the problem is even worse. Jumping into an unknown pick-up group can feel intimidating, and the fear of being judged pushes newcomers away from the sport entirely-robbing them of experiences that could genuinely improve their game and their wellbeing.

We live in an era where it's easier to queue up for a League of Legends match than to organise a real-world game with real people. That felt wrong to us. We believe technology should make it effortless to get off the couch, meet your neighbours, and experience the magic of community through sport. That conviction became Match.


What it does

Match is a mobile-first web app that instantly connects badminton players to each other and to nearby courts. Think of it as Uber meets pick-up sport: tap a button, get matched, and start playing.

Quick Match lets players jump into a game right now. You hit the hero card, choose Singles or Doubles, and enter a live queue. The system scores candidates on availability, proximity, sportsmanship rating, and skill level, then proposes a mutual match. Once all slots are filled, the top three nearby venues are surfaced and everyone confirms a court within minutes.

Schedule Match is for planners. Create a session for a future date, set your preferences, and publish it as an open lobby. Other players browse and request to join, or the system auto-fills empty slots an hour before game time so no one is left hanging.

Beyond matching, Match handles the entire session lifecycle: real-time group chat so players can coordinate, integrated Stripe payments with automatic cost splitting, venue discovery on an interactive Mapbox map, merchant upsells like racquet rentals and post-game refreshments, and a post-session rating system that feeds back into future match quality.

On the merchant side, venue owners list their courts, manage availability and pricing, offer upsell items, and track revenue-all from a dedicated dashboard. Match earns a commission on every booking, aligning our incentives with theirs: the more players we send their way, the more everyone wins.


How we built it

Match is built on a modern, full-stack TypeScript architecture designed for real-time responsiveness and rapid iteration.

Concern Technology
Framework Next.js 16 (TypeScript)
API Layer tRPC 11 + TanStack React Query
Database Supabase (Postgres) + Prisma ORM
Auth Supabase Auth (Google & Apple)
Real-time Supabase Realtime (WebSocket)
UI Tailwind CSS 4 + shadcn/ui
Maps Mapbox GL JS
Payments Stripe (Checkout + Connect)
Push Notifications Web Push API + Service Workers

The core matching algorithm computes a composite score across four weighted factors: availability overlap (40%), geographic distance (30%), sportsmanship rating (20%), and skill proximity (10%). Skill is deliberately weighted lowest because on a growing platform, getting a game happening matters more than perfect competitive balance.

We designed the Explore screen around an always-visible hero card that transitions through six colour-coded states-from Idle to Searching to Confirmed to Venue Selection-giving players a clear sense of progress without ever locking them out of browsing. The pull-up bottom sheet surfaces a mixed feed of venues, open sessions, and player suggestion cards, so Quick Match runs in the background while users stay in control.


Challenges we ran into

Real-time matching at its core is a concurrency problem. Two players can't both accept the same candidate simultaneously, and a system auto-match arriving while a manual request is pending has to cleanly take priority without leaving orphaned state. We spent significant time modelling the session lifecycle as a finite state machine with eight distinct states and mapping every edge case-player drops pre-booking, player drops post-booking, app backgrounding, venue disagreements-before writing a line of matching logic.

Dual-path matching (system auto-match versus manual feed pick) introduced its own complexity. Both paths feed into the same confirmation flow, but they have different timeout semantics and priority rules. Getting mutual confirmation, one-directional requests, and the two-minute response windows to coexist without race conditions required careful orchestration through Supabase Realtime channels.

Payment splitting was another challenge. Stripe handles individual charges well, but evenly splitting a court booking plus variable per-player upsells-while deducting platform commission and routing payouts to merchants via Stripe Connect-required us to carefully structure the checkout flow so every cent is accounted for and refund logic works cleanly when sessions are cancelled.


Accomplishments that we're proud of

We shipped a complete, end-to-end session lifecycle: from tapping Quick Match, through real-time candidate scoring and mutual confirmation, to venue selection, payment processing, in-game chat, and post-session ratings. Every state transition is accounted for, including cancellations, backfills, and timeouts.

The Explore screen genuinely feels like a native app. The hero card's six-state colour transitions, the persistent bottom sheet feed, and the Mapbox integration with live venue pins and player dots create an experience that's fluid and intuitive despite being a web application running in a mobile browser.

We also built a fully functional two-sided marketplace in hackathon time. Merchants can onboard through Stripe Connect, manage courts and upsells, and view revenue analytics-while players enjoy a seamless booking and payment experience. The commission model means Match's revenue scales directly with user value, which we think is the right alignment.


What we learned

State machines are worth their weight in gold. Modelling the unified session lifecycle upfront-with explicit states like Searching, Confirming, Matched, Booked, In Progress, and Completed-saved us from countless bugs and made edge-case handling systematic rather than ad hoc.

We learned that skill-based matchmaking is overrated for a new platform. Our weighting algorithm intentionally deprioritises skill (10%) in favour of availability and proximity. Early on, the most important thing is that people actually get a game; competitive balance can be refined later with ELO systems and richer data.

Building for real-time is a fundamentally different discipline. Everything from queue state to chat to live map markers needs to feel instant, and Supabase Realtime carried a lot of that weight. But we also learned that graceful degradation matters: what happens when the WebSocket drops, when the app is backgrounded, when a push notification fires but the user doesn't respond for five minutes. Designing for the unhappy path is where robustness lives.


What's next for Match

Our MVP is scoped to badminton, but the architecture is sport-agnostic. The immediate roadmap includes expanding to tennis, basketball, and futsal-each with their own session formats, player counts, and venue requirements-while keeping the same core matching engine.

We plan to introduce an ELO-style algorithmic skill rating that passively improves match quality over time, replacing self-reported skill levels with data-driven assessments. Alongside that, we want to add social features like friend lists and activity feeds to strengthen the community layer.

On the merchant side, we're exploring tournament and league management tools that let venues host recurring competitive events, driving repeat bookings and deeper player engagement. We're also looking at transportation coordination-helping players who don't have cars get to courts-because the last mile to the venue shouldn't be the reason someone skips a game.

Ultimately, we want Match to be the default way people play sport in their city: open the app, find your people, and go play.

Built With

+ 2 more
Share this project:

Updates