Inspiration
I've watched the same thing happen at every wedding and every party I've been to: everyone takes hundreds of photos, and almost none of them make it back to the people who were actually there. The WhatsApp group goes quiet after two days. The little QR code card on the table ends up in the trash with the napkins. And the friend who got the best shots of the night swears they'll send them over - they never do.
I've spent years building NFC.cool Tools at NFC.cool, so my head goes to tags by default. But Moments didn't start as an app idea. It started with the object. What if the thing sitting on the table wasn't a disposable card, but a keepsake - a small tag that holds the memories of the day? Something you can toss in a drawer after the wedding, tap years later, and be right back at that table.
The album followed from the object. Tap the tag, the shared album opens on the phone already in your hand, nothing to install, nothing to sign up for. Shipaton was the deadline that finally made me build the thing I'd been wishing existed at every party for years.
What it does
Moments turns a physical NFC tag into a shared photo album. You place the tag on the table at your wedding or party. A guest taps it with their iPhone and an App Clip opens in seconds - no App Store trip, no sign-up. They can shoot photos right there with the built-in camera, pick a look, and their shots land in the shared album. As the host you review what comes in, so the album stays yours. New memories appear in the album immediately, with a visible processing state while they upload and wait for approval, instead of vanishing into a queue. And after the event, the tag becomes the keepsake: tap it again years later and the whole day comes back.
How we built it
Two halves: a native iOS front end and a self-hosted server.
On iOS it's a SwiftUI app plus an App Clip target that shares the same capture code, with the project generated by XcodeGen. The camera is fully custom on top of AVFoundation: my own capture session, capture geometry and cropping, subject lift, and live-previewed photo looks. The filters are curated presets - I tune them with debug-only sliders, then ship a small set of named looks instead of exposing sliders to users.
The server is a TypeScript monorepo: a Fastify API with Zod-typed routes, Drizzle ORM on Postgres, and a background worker that turns uploads into image variants with sharp and runs the video pipeline. Media is delivered through Bunny CDN and transactional email goes through Postmark, all of it running in Docker behind Caddy on Scaleway, deployed as regional cells. Tests run in Vitest against a real Postgres via Testcontainers.
Challenges we ran into
App Clips are unforgiving. The whole tap-to-camera experience depends on the apple-app-site-association file being served exactly right, and a TLS flake in my deploy would silently break it - taps fell back to the browser until I chased it down.
Two Postgres drivers in the same codebase disagreed on what sslmode means. The API looked perfectly healthy while the worker had silently died, so every single upload failed - my favorite kind of bug, the one with no error anywhere near the cause.
And what looked like a production bug - a fresh upload showing as unavailable - turned out to be a missing UI state. There's a real window where a memory exists but isn't processed or approved yet, and the UI simply had no state for it. Now new memories show up instantly with progress and pending states instead.
Accomplishments that we're proud of
Tap to camera in a few seconds, on a phone that has never seen the app. An album that scrolls at the speed of Apple's own Photos app. A custom camera with hand-tuned looks that feels native instead of feeling like an upload form. And the entire media pipeline - image variants, video processing, CDN delivery - self-hosted and running on a solo-developer budget.
What we learned
Most "backend bugs" users report are actually missing UI states - design the in-between states first, not last. App Clips are the best onboarding funnel Apple ships and the least forgiving to operate. Curated presets beat sliders: a handful of looks I tuned myself makes every photo better, while a slider mostly makes photos worse. And when two libraries read the same connection string, make sure they agree on what it means.
What's next for Moments by NFC.cool
A proper line of keepsake tags - objects worth keeping on a shelf, not printed cards headed for the trash. A Live Activity in the App Clip funnel, so a guest can watch their photos land in the album while the phone is already back in their pocket. And the EU cell, so albums live close to the people in them.
Log in or sign up for Devpost to join the conversation.