# showcase.social
A "linktree for collectors." A personal gallery for the stuff you collect (TCGs, vinyl, blind boxes, whatever), without a feed or algorithm.
- role
- solo
- stack
- Next.js 16React 19ExpoReact NativeSupabasePostgresTypeScriptTailwindNativeWind
- demo
- showcase.social
## Why
Most social apps aren't great for showing off a collection. Instagram is too temporary, Reddit posts disappear into the feed, and TCG apps only handle one type of thing. I wanted a page that was just my stuff, organized how I want it, without an algorithm pushing me to post every day.
The pitch is "linktree for collectors." Your profile is the whole product.
## What it is
Every user gets a profile page that's their gallery. You make collections and put items in them. Each collection has a display template (grid, binder, more on the way) and a cover image. There's also a pinned "Showcase" section at the top of your profile for your favorite items.
It's both a website and a mobile app. The web is better for browsing the gallery and admin stuff, the mobile app is better for adding items because you can take a photo and add it right there.
## Stack
- Web: Next.js 16 (App Router), React 19, TypeScript, Tailwind v4
- Mobile: Expo, React Native, NativeWind
- Backend: Supabase (Postgres, Auth, Storage, RLS on everything)
- Validation: Zod schemas shared between web and mobile
- Monorepo with pnpm workspaces, shared packages for types, schemas, categories, and Supabase types
## Status
Working but invite-only. I'm not shipping new features right now since I'm working on other stuff, but it's deployed and live. I'll come back to it.
## devlog(6 entries)
iOS deploy + the camera saga
Spent a week on the camera. iOS and Android both behave differently for in-app cameras, and Expo's APIs only smoothed over some of it. Eventually got photo capture working on both with a basic edit/crop step before uploading to Supabase Storage.
Then a cleanup pass before iOS deployment: safe-area warnings, build errors, profile loading bugs, auth fixes, env variables hooked into EAS for the build. The mobile app is now buildable for both iOS and Android, the web app is in production, and showcase.social is live (invite-only for now).
Stepping away from this for a bit. Other stuff I want to work on. Classic me, but I'll come back to it.
shops and inventory
Added shops and inventory management to user profiles. If you collect stuff and sometimes want to sell or trade duplicates, you can mark items as for-sale and they'll show up in your shop section. There's also an inventory view for managing what's listed, prices, and notes on each item.
A lot of collectors trade or sell on the side so it made sense to have shops on the profile instead of making people go somewhere else for it. The gallery is still the main thing.
added a mobile app
Started a mobile app with Expo and React Native. The web app is fine for browsing collections but adding items felt better suited to mobile. You're taking photos of the items anyway, might as well do everything from your phone.
Restructured into a monorepo with pnpm workspaces so the web and mobile sides could share Zod schemas, display types, theme configs, and Supabase database types. NativeWind on the mobile side so the same Tailwind classes mostly work on both.
First week was mostly monorepo plumbing, making sure the shared packages didn't pull React DOM into the mobile bundle. Once that was sorted things moved faster.
migrated to Supabase. rip atproto
Ripped out the AT Protocol entirely. I was spending way more time fighting with PDS proxying, lexicon shapes, and OAuth quirks than I was building the actual gallery features that were the point of the app. Decentralization is cool but for an invite-only app where I control who joins, plain Supabase auth gets the job done with way less complexity.
Now it's Postgres with RLS on everything, Supabase Auth, Supabase Storage for images. Server components and server actions for mutations. Once that was in place I could actually focus on building the product (collections, themes, display templates) instead of fighting with plumbing.
feed, firehose, and other PDSs
Two weeks in and the basics are working. Login through any AT Proto PDS (not just bluesky.social), custom lexicon records for items and collections, a profile page that reads records from your PDS, and a feed view powered by the firehose.
The firehose part was fun. Subscribing to the AT Proto event stream, filtering for Showcase records, and rendering them on the page was satisfying.
Took a few weeks off after this. Got a little burned out on the protocol stuff and wanted to think about whether all this was the right approach for what is basically a gallery app.
started showcase on the AT Protocol
Started Showcase as a Next.js app built on top of the AT Protocol (the protocol Bluesky uses). The plan was that every user's collection would live in their own PDS as custom lexicon records, and Showcase would just be a viewer for that decentralized data.
The idea was cool. Your data is in your PDS, you can take it anywhere, no central database.
Getting OAuth working with the .well-known endpoint and proxying back to the user's PDS turned out to be a pain. My commit messages from that week are kind of funny in hindsight: "dang it i lied", "one more try then dinner", "ok for real last time".