Bppatkar/social_media: The Node.js Social App That Treats Production Like the Product
A full-stack social platform with a service layer, token rotation, Redis caching, cursor pagination, and observability built in from the start.

A passionate Full Stack Developer with deep expertise in building scalable, high-performance web applications. Post-Graduate in Computer Science with a strong foundation in Data Structures & Algorithms.
- This repo treats production discipline as the product, with security, caching, and observability built into the core architecture.
- Refresh-token rotation, login lockouts, and layered middleware show a system designed for failure modes, not just happy paths.
- Redis cache-aside reads and cursor pagination make the feed feel built for real traffic instead of tutorial-scale data.
- The service layer keeps controllers thin, which turns the codebase into a reference for testable Node.js architecture.
Most social app repos are demos with a feed attached. This one feels different: it behaves like a blueprint for a Node.js service that expects real users, real abuse, and real traffic. The surprise is not that it can post, follow, and paginate. The surprise is how many production concerns are treated as first-class product decisions.
Why This Repo Feels Like a Production Blueprint
The codebase is organized like a team expects to own it. Controllers, services, models, middleware, routes, and client features are separated cleanly, so the repository reads less like a hobby project and more like a reference implementation. That matters because the architecture is not just neat. It creates room for security, caching, and testability to exist without fighting each other.
The frontend follows the same discipline. A Next.js app with feature-oriented structure and a design system keeps the product side from drifting into random component sprawl. The backend and frontend are split, but they share the same bias toward explicit boundaries.
Security Is Not an Add-On Here
The auth flow does not stop at JWTs. Access and refresh tokens are separated, refresh tokens are rotated, and revoked tokens are tracked so a stolen token does not remain useful forever. That is a serious signal. The repository assumes credential theft, failed logins, and hostile input are normal operating conditions.
The security layer is broader than auth alone. Helmet, HPP, Mongo sanitization, environment validation, and login lockouts all point in the same direction. The system wants to fail early, reject bad input aggressively, and reduce the blast radius when something goes wrong.
The Feed Is Built for Real Traffic, Not Toy Data
This is where the repository becomes especially convincing. Feed reads use Redis first, then MongoDB on cache miss, then repopulate Redis with a TTL. Writes can invalidate the relevant cache keys so freshness is not left to chance. It is the kind of logic you only add once you have learned that a feed is not a static list, it is a moving contract between speed and staleness.
| Concern | Typical tutorial app | Bppatkar/social_media |
|---|---|---|
| Feed reads | Hit MongoDB every time | Cache-first with Redis and TTL |
| Pagination | Offset-based skip and limit | Cursor pagination with _id markers |
| Write consistency | Hope the list stays current | Invalidate feed cache after content changes |
| Scale mindset | Works on small datasets | Keeps read cost predictable as data grows |
Cursor pagination is the quieter win here. Offset pagination is easy to write and expensive to trust, because the deeper the page, the more work the database has to do. By advancing from the last seen record, the repo chooses a shape that degrades more gracefully.
What the feed pipeline is really optimizing
Read path:
User -> Redis cache lookup -> MongoDB on miss -> Redis repopulation with TTL
Write path:
New post -> invalidate feed:* keys -> next read rebuilds cache
Pagination path:
client sends cursor -> query with _id < cursor -> fetch next slice without skip cost
That is the deeper pattern here. The app does not treat speed as a separate optimization track. It treats speed as part of correctness, because stale reads and slow reads both hurt the product.
The Service Layer Is the Quiet Superpower
The most useful architectural choice in the repo is also the least flashy one. Controllers stay thin, while business logic lives in services. That split makes the code easier to test, easier to reason about, and easier to extend without turning route handlers into tangled decision trees.
This matters because the repository is not just trying to work. It is trying to stay understandable after the first release. Once auth, feed logic, audit events, and profile actions grow, a service layer becomes the difference between a system you can patch and one you can still shape.
Observability Makes the App Inspectable
Winston, Morgan, audit logs, and health routes are not decorative extras. They make the app legible under pressure. When a login fails, a profile changes, or the service starts behaving oddly, there is a paper trail and a place to look first.
That is a product decision as much as an engineering one. Observability shortens the distance between user pain and diagnosis. In a repo like this, that distance is part of the user experience.
What This Repo Does Better Than the Average Tutorial Stack
| Concern | Typical Express tutorial | Bppatkar/social_media |
|---|---|---|
| Layering | Logic lives in controllers | Controllers and services are separated |
| Auth | Single token path | Access and refresh token rotation |
| Feed | Plain database queries | Redis cache-aside plus invalidation |
| Operations | Minimal logging | Winston, Morgan, audit logs, health checks |
| Input safety | Basic validation | Zod, sanitization, and defensive middleware |
The difference is not that this repo has more features. It is that the features are arranged like they expect scrutiny. Refresh tokens are rotated, not reused. Controllers stay thin. Feed reads are cache-first, not database-first. That is what gives the project its unusual weight.
Read this as a template-plus repo. It is a working social platform, but it is also a lesson in how to structure a Node.js application so the hard parts remain visible, isolated, and testable.