Two people on a sofa, forty minutes of scrolling, and still no film. ReelMatch turns that into a swipe: each person likes what they like, and the app finds what they both want to watch.
What it is
ReelMatch is my own app for deciding what to watch together. You swipe through recommendations in a Tinder-style stack, watch trailers, and match with friends on shared interests.
My role
I designed, built and run ReelMatch end to end, live on the App Store and Google Play.
What I built
- Designed, built and run end to end: product, UX, architecture, backend, builds and release on the App Store and Google Play.
- A Tinder-style swipe stack of recommendations with trailers, a friends list, shared likes and a match view that shows what two people both want to see.
- A free tier and a premium tier with in-app purchases, invitations with referral rewards, and push notifications.
Architecture and approach
- Layered architecture: screens and widgets, then providers (ChangeNotifier), then repositories, then services and APIs (Firebase, TMDB, RevenueCat).
- Provider for state management and GetIt for dependency injection, with everything registered in one locator.
- GoRouter for declarative navigation, with an analytics observer on every route.
- Firebase Auth and Firestore for users, likes, friends and recommendations; Remote Config for feature flags; Cloud Messaging for notifications.
- Crashlytics and Performance Monitoring in production, plus a custom analytics event schema.
- A subscription layer on RevenueCat, with plan limits enforced by a SubscriptionGuard widget and swipe-limit service.
- Unit and widget tests mirrored against the lib/ structure with Mockito.
Hard problems
Recommending to users with no history
Cold-start: before a user has ten likes the engine blends popular and genre-based titles. After that it mixes TMDB recommendations seeded from their likes, filtered by genre, language and streaming platform, retries on API failure and de-duplicates across sources.
A production crash in a dependency
Crashlytics showed a fatal AnimationController double-dispose when a swipe was cancelled. I traced it to the swiper package, forked it into the repo with an _isDisposed guard and registered the fix as a dependency override.
Image memory on older phones
A swipe stack is image-heavy. The image cache is capped (200 images, 50 MB), image errors are suppressed and logged separately, and loading goes through a single cached network image widget.
Free vs premium without leaks
Limits are enforced centrally rather than per screen, so a new feature cannot accidentally bypass the paywall.
Outcome
- 14,000+ downloads across the App Store and Google Play.
- Live on both stores with subscriptions, invitations and review-prompt logic.
- Continuous delivery through GitHub Actions and Xcode Cloud.
Tech and keywords
- Flutter
- Dart
- Provider
- GetIt
- Dependency injection
- GoRouter
- Firebase Auth
- Firestore
- Remote Config
- Crashlytics
- Cloud Messaging
- TMDB API
- RevenueCat
- In-app purchases
- Recommendation engine
- Cold start
- Mockito
- GitHub Actions
- Xcode Cloud
Quick facts
- App: ReelMatch
- Category: Entertainment
- Built by: David Miller, Digital Space Agency, Hamburg
- Type: My own product
Discuss a similar project All work
No mail app? Open in Gmail or write to info@dsa.team
FAQ
What did David Miller do on ReelMatch?
I designed, built and run ReelMatch end to end, live on the App Store and Google Play. Details of scope and stack are shared on request.
Who made ReelMatch?
ReelMatch work was done by David Miller of Digital Space Agency, a Flutter and mobile developer based in Hamburg. I designed, built and run ReelMatch end to end, live on the App Store and Google Play.
Can David Miller build a similar app?
Yes. I take contract engagements and am open to full-time roles, working in Hamburg or remotely on CET. Email info@dsa.team with a short description of the project.