INSTAGRAM
ARCHITECTURE

Timeline

4 Weeks

Role

Full Stack Dev

Database

MongoDB NoSQL

Stack

MERN + Socket.io

01. Architecture

Building a scalable social media clone requires a solid foundation. I opted for a decoupled architecture using Node.js and Express for the backend, serving RESTful APIs to the React frontend.

This separation of concerns ensures that the client remains lightweight while the server handles the heavy lifting of authentication (JWT) and data processing.

System DesignREST APIJWT Auth
ClientReact + Redux
API ServerNode.js + Express
DatabaseMongoDB Cloud

02. Database Schema

Designing the NoSQL schema was tricky due to the highly relational nature of a social network (Users following Users, Posts belonging to Users, Comments belonging to Posts).

I utilized Mongoose references to link collections, allowing for efficient .populate() queries when fetching complex feed data without duplicating records.

MongoDBMongoose
PostModel.js
const postSchema = new mongoose.Schema({
  caption: { type: String, required: true },
  image: { type: String, required: true },
  creator: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User'
  },
  likes: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }],
  comments: [commentSchema]
}, { timestamps: true});

03. Real-Time WebSockets

A modern social app needs instant feedback to feel alive. Instead of relying on constant HTTP polling, I implemented Socket.io.

This creates a persistent, two-way connection between the browser and the server, enabling instant notifications, direct messaging, and real-time "like" updates across all connected clients.

Socket.ioReal-time Data
socketEvents.js
io.on('connection', (socket) => {
  socket.on('like_post', async ({ postId, userId }) => {
    // 1. Update Database
    await Post.findByIdAndUpdate(postId, {
      $push: { likes: userId }
    });

    // 2. Broadcast to all clients viewing this post
    io.emit('post_updated', { postId, newLike: userId });
  });
});

04. Global State

With deeply nested components like feed posts, comment sections, and user profiles, "prop drilling" quickly became an anti-pattern.

I integrated Redux Toolkit for global state management. This allowed the app to smoothly share the user's authentication state, cached feed data, and active socket connection globally.

Redux ToolkitReact Context
REDUX STORE
Auth Slice
JWT / UserData
Feed Slice
Posts / Cache
UI Slice
Modals / Theme
← Back to Overview