Case Study
SamePage
Collaborative reading tracker for iOS, Android, and web
Status
Live · daily use
Type
PWA · multi-user
Infra cost
$0/mo
React 19 · TypeScript · Vite · Capacitor · Firebase Auth · Firestore · Cloudflare Pages

Problem
Two people reading the same book needed a shared space to log progress, leave notes, and stay in sync — without spreadsheets or constant texting. No existing app supported the lightweight collaborative workflow they needed.
What Was Built
A single-page React app with real-time multiplayer sync. Users can join a reading group, log their progress, and leave comments. The app includes a "spoiler lock" feature that blurs comments ahead of a reader's current progress, and uses the Open Library API for book discovery.
Outcome
A fully functional multi-user PWA used daily. Demonstrates end-to-end app architecture including auth, real-time data sync, multiplayer features, and mobile UX.
Background
SamePage started as a personal project: a way for two people to track their reading together without stitching together spreadsheets and text messages. The goal was something installable on both iOS and Android, lightweight, and always in sync.
The Problem
Existing reading apps are built for solo readers. There was no lightweight, shared-first reading tracker that felt like a proper app — not a Notion page, not a spreadsheet, not a group chat thread.
What I Built
A full-stack single-page application built with React 19, TypeScript, and Vite, featuring:
- Cross-platform: Built with Capacitor to ship native iOS and Android apps from the same React codebase. Android's WebView has unreliable Firestore write channels, so the app falls back to the Firestore REST API for those writes — same data model, platform-appropriate transport.
- Real-time Multiplayer: Firestore
onSnapshotlisteners power live sync for both reading progress (debounced to avoid excessive writes) and comment threads. Fellow travelers are updated instantly. - Spoiler Lock: A custom feature that calculates a reader's current progress and automatically blurs comments left at a location more than 2 units ahead of them.
- Invite-only Auth System: Firebase Auth handles the actual authentication, but sign-ups are gated behind an invite system. Designated admins can generate expiring invite links (
?invite=<token>). - Book Discovery: Integrated the Open Library public API (
openlibrary.org/search.json) for instant book search withAbortControllerto cancel stale requests.
Key Technical Decision
Real-time sync over a complex state manager.
Instead of implementing a heavy client-side state management library like Redux, I relied entirely on Firestore's real-time listeners (onSnapshot) combined with custom hooks. This ensures the UI is a direct reflection of the database state, making multiplayer features like the "fellow travelers" progress bar trivial to implement and keeping the architecture incredibly lean.
Stack
React 19 + TypeScript + Vite · Capacitor · Firebase Auth · Firestore · Cloudflare Pages · Tailwind CSS
Download on the App Store →