A social platform for Nepal, built and shipped solo.
Reepro fuses LinkedIn — jobs, professional profiles, networking — with Instagram's reels and stories. It runs in production today, serving roughly 4,000–5,000 live users.
Nepal had professional networking in one place and short-form social in another. Neither was built for the market.
Reepro answers that by putting both behaviours on a single social graph: one user model that carries a professional identity and a creator identity at once. Job seekers, professionals, and employers share the same posts, reels, stories, messaging, and calls — employers get job posting and recruiting layered on top rather than a separate product.
The interface had to work in Nepali script as well as English, which shaped the typography choices from the first component onward.
Sole engineer,
every layer
Architecture, backend, frontend, DevOps and deployment, and production incident response. 1,156 commits across a four-app NX monorepo since July 2024.
Next.js 15 · React 18 · Chakra UI · Zustand · TanStack Query & Table · React Hook Form + Zod
Next.js API routes · Express · NextAuth v5
PostgreSQL · Prisma · Redis · BullMQ
FFmpeg · HLS.js adaptive streaming · AWS S3 · CloudFront
Socket.io messaging · Agora RTC with token auth
Self-managed VPS · custom deploy scripts · Nginx
One boundary,
enforced everywhere
All web and mobile APIs live in a single Next.js app; Express serves the dashboard only. Holding that line kept the mobile app on one contract and left web iteration fast.
Progress is tracked in Redis and surfaced back to the uploader. The transcoding worker runs as a dedicated standalone process, split out from the web app so a heavy encode can't touch request latency.
All web and mobile APIs live in the Next.js app; Express is dashboard-only. That boundary keeps the mobile contract stable for whoever builds the client, while web iterates freely.
One user carries both identities. Posts, reels, stories, messaging and calls are shared; employer-only job posting and recruiting sit on top rather than forking the product.
A proprietary completeness index that scores a profile from resume, experience, education, skills, portfolio and certifications.
Reels: moving the work off the upload
Uploads used to block on processing. Now a chunked upload lands in S3, a BullMQ job picks it up, and the user is free immediately — the reel appears when the worker finishes.
- Explore and feed with infinite scroll and windowed rendering.
- Admin moderation dashboard for reported and flagged reels.
- "Stuck reel" bulk recovery tooling for jobs that die mid-pipeline.
- Dedicated worker process, isolated from the web app.
Six things that broke,
and why
Diagnosed and fixed in production, on a live user base, with no second engineer to hand the pager to.
The production database and app server were sitting in different datacenter regions, adding latency to every single request.
Fix — Planned and executed a syd1 → blr1 migration with the old box held as rollback, then decommissioned it once the new region proved stable.
Prod, staging, and system processes shared an unbounded per-service connection budget against a 25-connection database.
Fix — Explicit connection_limit tuning per service, sized against the real budget rather than left to defaults.
Next.js bundled a separate instance of the in-memory event bus per API route, so events published on one instance had no listeners on another. Every notification dropped silently in production.
Fix — Promoted the bus to a globalThis singleton so all routes publish and listen on the same instance.
The Agora credential was exposed to the client through a NEXT_PUBLIC_ env var — the real root cause behind every call failing token generation with a 500.
Fix — Rotated the credential and moved token generation server-side.
Output file tracing missed zod, used only by a pages/api socket route, so the deployed bundle was incomplete.
Fix — Patched the break and added a deploy-time dependency top-up guard so future file-tracing gaps fail loudly instead of in production.
A committed .env.production file and multiple copies of a Firebase Admin service-account key were tracked in the repository.
Fix — Untracked both and began credential rotation.
Built from scratch, in two scripts
A custom Chakra UI theme with its own component variants — Button, Input, Modal, Tabs and the rest — plus a typography stack chosen for Devanagari support: Mukta and Tiro Devanagari Hindi alongside IBM Plex Mono.