ShippedMobileSince 2025
Malabji
Find a pitch, find players, book it, play.
Malabji lets you search nearby football pitches, see available slots, and reserve one. Team search, challenges, and tournaments help players fill the match.

- Role
- Founder: product, design and full engineering
- Year
- Since 2025
- Status
- Shipped
- Built with
- React Native
- Expo Router
- TypeScript
- Supabase
- Zustand
- React Query
- React Hook Form
- Zod
- Reanimated
- Skia
- Restyle
- In-App Purchases
- Deep Linking
- Calendars
- Push Notifications
- Where to find it
Football pitch bookings in Jordan run through phone calls and WhatsApp. You ask a ground about Thursday, gather players, then find the slot has gone; payment happens in cash on arrival. You also need nine other players.
Malabji handles both. The booking side is a live availability calendar per pitch with instant reservation. The social side lets you look for a team, challenge another one, and run or join a tournament, plus a directory of sports academies.
I founded it and built all of it: the Expo client for both stores, the Supabase backend, the store releases, and the support that follows a real product.
Challenges
Never sell the same hour twice
The snag
Two people opening the same 7pm slot at the same time is not a rare edge case on a Thursday evening. It is the normal load. Checking availability and then writing the booking is two steps, and anything can happen between them.
What I did
Availability is never trusted from the client. The reservation is a single server-side transaction with a uniqueness constraint on (pitch, time range); the loser of a race gets a clean 'just taken' state and the calendar refreshes under them rather than a failed payment.
In-app purchases on two stores with different rules
The snag
Apple and Google disagree on receipts, on what a restore means, and on what they will approve. A purchase that succeeds on the device but never reaches the backend is the worst possible bug in a paid product.
What I did
Entitlement is decided on the server from a verified receipt, never from the client's word. The client re-validates on launch and after every restore, so a purchase interrupted mid-flight reconciles itself the next time the app opens.
Calendar and notifications that respect the user
The snag
A booking is useless if the player forgets it. But asking for calendar and notification permission on first launch, before the app has earned anything, gets both denied.
What I did
Permissions are asked at the moment they pay off. The calendar prompt appears right after a successful booking, not before. Reminders are scheduled locally so they still fire if the device is offline.
Deep links that survive an install
The snag
Growth happens when someone shares a match invite in a group chat. If the tap opens a store page and the invite is lost after installing, the whole loop breaks.
What I did
Invite links carry their payload through the install, so a new user lands on the actual match after opening the app for the first time, not on a generic home screen.
Results
- Live on the App Store and Google Play.
- Bookings, team search, challenges and tournaments in one app.
- Built and operated solo, from schema to store listing.





