Social Media App · 03 / 03
Crowned ProjectRedbook
A social platform that mixes ideas from Reddit and Facebook — post, comment, and vote — without copying either; the architecture is entirely my own, built end to end on a hand-rolled PERN stack. Posts and comments carry independent up/downvotes, and messaging and notifications run live over Socket.io.
Hosted on free-tier services, so the server can take up to ~50s to wake up on the first request after a period of inactivity.
Redbook is the one project in this portfolio where I designed the whole architecture myself, rather than following a tutorial or template. It borrows feature ideas from Reddit and Facebook — voting, commenting, direct messaging — without being a clone of either. The goal wasn't just to build 'a social platform' — it was to prove I could handle something as critical as social media's core mechanics: a voting system, realtime messaging and notifications over Socket.io, image uploads through Cloudinary, and a fully Dockerized setup, all on a self-designed PERN stack, without leaning on a framework to handle the parts that are actually hard.
- Toggleable voting — Posts and comments each carry independent upvote/downvote arrays rather than a separate votes table. Casting a vote toggles it off if it's already active, and switches cleanly from up to down (or back) in a single request.
- Realtime chat and notifications — Direct messages and live notifications — new comments, upvotes, downvotes — are pushed over Socket.io to a per-user socket connection, so the UI updates instantly for the recipient without polling.
- Cloudinary-backed uploads — Profile, cover, and post images upload straight to Cloudinary through a parsed multipart form, keeping the Express server itself stateless.
- Docker Compose from day one — Postgres, the Prisma migration step, the Express API, and the React client all run through a single docker-compose.yaml — the same setup used locally and, with adjustments, in production.
Voting needed to feel instant without spamming notifications: switching a vote should notify the post's author, but withdrawing one shouldn't. I built the vote handlers as an explicit three-way branch — add, remove, switch — that mutates the right array and only fires a Socket.io notification on the branches where a vote is genuinely being cast, not removed.
It's stable and deployed now, so the near-term focus is comment threading — letting replies nest under other replies to any depth, which the schema is still flat for. Beyond that, it's ongoing polish as free time allows.