Skip to content
Marko Ivanovski

Twitter clone

A full-stack social feed with real-time notifications and private accounts, built with Next.js, NestJS and Postgres.

category
personal
year
2026
status
completed
role
Sole developer
  • Docker
  • NestJS
  • Next.js
  • PostgreSQL
  • Prisma ORM
  • React
  • Tailwind CSS
  • TypeScript
Screenshot of the home feed with a reposted image post, from Twitter clone.
Screenshot of the notification menu with two follow requests to accept or decline, from Twitter clone.
Screenshot of a private profile as a non-follower sees it, from Twitter clone.
Screenshot of a single post page with its likes, repost and comments, from Twitter clone.
Screenshot of the feed in dark mode, from Twitter clone.

What it is

A Twitter-style social feed. Next.js and React on the front end, a NestJS API with Prisma over Postgres on the back end, all running locally with one Docker Compose command. People post text and images, follow each other, like, retweet and reply, and can make their account private so only approved followers see their posts.

Notifications arrive live over Server-Sent Events, and follow requests are accepted straight from the inbox. Who can see a post is decided by a single database filter that every feed, profile and count uses, so a privacy rule can't be missed in one corner of the app.

  • Real-time notifications over Server-Sent Events, with reconnection through the refresh-token flow and nothing lost while disconnected.
  • Private accounts and follow requests, enforced by one visibility rule shared by every query.
  • Security hardening: uploads checked by file signature, rate-limited credential endpoints, session revocation on password change.
  • 97 API unit tests written test first, with every feature independently reviewed before merging.

What I learnt

  1. A privacy rule written once and reused everywhere is easier to trust than checks scattered across endpoints. The one gap review found was a retweet path the rule had not covered yet.
  2. Writing the failing test first caught regressions the green build alone would have missed.
  3. A live stream has to respect logout too. Ending it at token expiry made the stream follow the same session rules as every other request.

What I would do next

Live like and retweet counts in the feed.

Frontend tests with Playwright.