Skip to content
All work

Pairfect

An app for two people: a shared memory album, a map of the places you have been, plans, and small daily rituals. Built solo alongside a full-time master's and a job.

FlutteriOS & AndroidOwn ProductUI/UX
Pairfect — 1Pairfect — 2Pairfect — 3Pairfect — 4Pairfect — 5Pairfect — 6Pairfect — 7

At a glance

Role
Solo, architecture to release pipeline
Period
10/2025 to 07/2026, nine months
Lines of Dart
approx. 78,200 across 266 files
Feature modules
11
Cloud Functions
24 files, approx. 3,450 lines
Commits
493

My role

Everything, solo

The problem

Couples already keep everything they share in five different places: photos in one app, plans in another, the dates that matter in a third, and the conversation itself somewhere else entirely. Nothing there is built for exactly two people, so nothing there behaves as if the two of them are one account.

How it works

  • Clean architecture per feature, each module split into data, domain and presentation. Dependencies point inwards, so a feature's business rules do not know that Firestore exists.
  • A serverless backend on Firebase with Auth, Firestore, Storage, Messaging, App Check and Cloud Functions in TypeScript.
  • Platform work that is not just screens: iOS home-screen widgets through WidgetKit, offline map downloads and a journey player on Mapbox, and subscriptions through RevenueCat with the entitlement shared across the pair.
  • GDPR data export and atomic account deletion as Cloud Functions, a biometric app lock, server-validated single-use pairing tokens, rate limiting and storage quotas.

Stack

Flutter, Dart, Firebase, TypeScript Cloud Functions, RevenueCat, Mapbox, WidgetKit, GitHub Actions.

What I take from it

Two decisions I would defend. Photos are stripped of metadata before upload, always, because EXIF GPS is a home address and the file header outlives the app. That component is open source now, as exif_scrubber. And the app lock is a UI gate, which the documentation says out loud: it swaps the widget tree and requires biometrics to return, but it encrypts nothing and is no defence against a rooted device or forensic access. Writing that limitation into the code comment mattered more to me than the feature sounding stronger than it is.

Outcome

Built solo in nine months, from architecture through interface and backend to an automated release pipeline, next to a full-time master's degree and a job.