Share photos in the moment, find yourself in everyone else's.
The weekend trip ends. The house party winds down. The dinner wraps up. And then comes the part nobody enjoys: "send me the pics." Someone makes a WhatsApp group. Half the photos arrive compressed into mush. Three people forget. The good shot of you is stuck on a friend's phone forever. A week later you're still asking, and you've given up scrolling through 400 photos to find the four you're actually in.
The photos exist. Getting them to the people in them is the hard part.
QuickLoop is a shared gallery that lives for exactly as long as the moment does.
You spin up a "loop" — a time-limited room — and everyone scans a code to join. Photos go into one place, full quality, as they're taken. When the timer runs out, the room closes, so it stays about this trip and not your camera roll forever.
Then the good part: snap a selfie and QuickLoop pulls up every photo you're in. No scrolling, no "can you send the one of me by the window." Just yours.
Built with Kotlin Multiplatform and Compose Multiplatform, so Android and iOS run the same shared codebase.
- Loops — create or join a room with a code or QR, set how long it lasts.
- Shared gallery — upload photos, see everyone else's appear in real time.
- Find my face — take a selfie, get back every photo you're in.
- Live updates — new photos, joins, and the countdown all sync over WebSocket.
- Google Sign-In, profiles, and avatars.
- UI — Compose Multiplatform (shared across Android & iOS)
- Networking — Ktor (HTTP + WebSocket)
- DI — Koin
- Images — Coil 3
- Serialization — kotlinx-serialization
Face detection and matching happen on the backend (a separate Go service with ONNX-based SCRFD + ArcFace, R2 storage, and Postgres + pgvector). The app talks to it over a REST + WebSocket API.
composeApp/src/
commonMain/ shared UI, navigation, view models, data layer
androidMain/ Android-specific implementations
iosMain/ iOS-specific implementations
iosApp/ iOS entry point (Xcode project)
Features live in their own packages under commonMain — home, gallery,
createloop, facefinder, onboarding, profile, splash — each with a
screen and a view model.
Android
./gradlew :composeApp:assembleDebugiOS — open iosApp/ in Xcode and run.
Tests
./gradlew :composeApp:allTestsSecrets aren't committed. Add them to local.properties in the project root:
API_BASE_URL=https://your-server
GOOGLE_WEB_CLIENT_ID=...
GOOGLE_IOS_CLIENT_ID=...
GOOGLE_IOS_URL_SCHEME=...The build reads these and generates AppConfig.kt at compile time. Without them,
the app falls back to http://10.0.2.2:8080 (the Android emulator's localhost).