DAILY NEWS

Stay Ahead, Stay Informed – Every Day

Advertisement
Building a Multi-Vendor Marketplace From Scratch: Lessons From 30,000 Lines of React


By Faiz Ullah — Full-Stack Developer & Founder of DG Technology

Most “build an e-commerce site” tutorials stop at a product list and a cart. They don’t deal with the actual hard part: three different types of humans — customers, sellers, and admins — all needing their own secure space inside the same app, talking to each other in real time, without ever stepping on each other’s data.

That’s what I set out to build with Ecommerce, a multi-vendor marketplace that grew to over 30,000 lines of React. Here’s what I learned engineering it.

The Real Challenge: Three Apps in One

A single-vendor store is one application. A multi-vendor marketplace is really three applications sharing a database:

Customers browse, buy, and chat with sellers

Sellers manage their own storefront, fulfill orders, and request payouts

Admins oversee everyone — approving sellers, resolving disputes, releasing payouts

The temptation is to bolt all three onto one App.js with a bunch of if (userType === ‘admin’) checks scattered everywhere. That gets unmanageable fast. Instead, I built three fully independent authentication systems, each with its own protected route guard:

Route element={ProtectedCustomerRoute />}>…Route>
Route element={ProtectedSellerRoute />}>…Route>
Route element={ProtectedAdminRoute />}>…Route>

Enter fullscreen mode

Exit fullscreen mode

Each guard checks its own session state independently. A seller session can never accidentally leak into the admin view, even if someone tries to manipulate the URL directly.

Real-Time Chat Without a Custom Server

I wanted buyers and sellers to message each other live — no page refresh, no polling. Rather than standing up a WebSocket server, I leaned on Firestore’s real-time listeners, which turned out to be the right call for a project this size:

onSnapshot(query(messagesRef, orderBy(‘timestamp’)), (snapshot) => {
// UI updates instantly as new messages arrive
});

Enter fullscreen mode

Exit fullscreen mode

This single pattern powers chat, unread-message counts, and live presence — all without me managing a single socket connection.

The Presence Problem

Showing whether a seller is “online” sounds trivial until you actually build it. A simple isOnline: true flag breaks the moment someone closes their laptop without logging out — they stay “online” forever.

The fix is a heartbeat pattern: the seller’s client writes a lastSeen timestamp every few seconds while the tab is active, and stops the moment the tab closes or loses visibility:

document.addEventListener(‘visibilitychange’, () => {
if (document.hidden) stopHeartbeat();
else startHeartbeat();
});

Enter fullscreen mode

Exit fullscreen mode

Anyone viewing the seller’s profile just checks: was the last heartbeat recent? No server-side cron job needed, no stale “online” ghosts.

Media at Scale: Don’t Make Your Database Hold Images

Early on I made the rookie mistake of storing image data directly. That doesn’t scale — Firestore documents have size limits, and serving large base64 blobs kills load times.

The fix was routing all uploads through Cloudinary, using unsigned upload presets so the API secret never has to live in client-side code:

formData.append(‘upload_preset’, cloudinaryConfig.uploadPreset);
const res = await fetch(`https://api.cloudinary.com/v1_1/${cloudName}/upload`, {
method: ‘POST’, body: formData
});

Enter fullscreen mode

Exit fullscreen mode

Cloudinary then handles resizing, format conversion, and CDN delivery — the database only ever stores a URL.

The Payout Problem Nobody Talks About

Letting sellers earn money is the easy half. Letting them withdraw it safely is the half that actually matters. I built a dedicated WithdrawalRequestsManager so that:

A seller requests a withdrawal
The request enters a pending queue — funds are not released automatically
An admin reviews and approves it manually before money moves

This manual checkpoint is deliberate. Automating payouts sounds efficient until the first fraud attempt — a human review step at the money boundary is the cheapest fraud prevention you can build.

What I’d Tell Someone Building Their First Marketplace

Separate your three user types from day one. Retrofitting role isolation onto a single auth system later is painful.

Use your database’s real-time features before reaching for a custom server. Firestore’s listeners replaced what would have been a whole separate real-time service.

Never store binary media where structured data lives. Offload it to dedicated media infrastructure immediately.
Put a human checkpoint wherever money actually leaves the system.

The Stack

Layer
Technology

Frontend
React, React Router

UI
Material UI (MUI)

Database
Firebase Firestore

Auth
Firebase Authentication

Realtime DB
Firebase Realtime Database (presence)

Media
Cloudinary

Faiz UllahFull-Stack Developer · Founder of DG Technology🌐 faizullah.pk · 💻 github.com/faizullahpk/multivendor-marketplace

If you’re building something with multiple user roles and real-time data, I’d love to hear about it — follow along for more on shipping real-world full-stack systems.



Source link

How I Built a Cinematic Portfolio with React and Framer Motion



Hi, I’m Akshay Bhawar, a Full Stack Developer from Maharashtra, India.

Recently, I decided to completely redesign my portfolio. Instead of going with a traditional, minimalist layout, I wanted something bold, immersive, and interactive—something that feels like a high-tech Sci-Fi Heads-Up Display (HUD).

You can see the live result here: https://akshaybhawar03.github.io/portfolio/

In this article, I’ll explain how I used framer-motion and React to bring this cinematic experience to life, the challenges I faced, and the key tech stack behind it.

🛠️ The Tech StackTo build a smooth, high-performance UI without compromising on developer experience, I used:

React.js: For building a component-driven, scalable architecture.

Framer Motion: The powerhouse behind all the futuristic animations, staggered text reveals, and UI transitions.

Tailwind CSS / CSS Modules: For styling the glowing neon effects, grids, and cyber-punk aesthetics.

🚀 Key Features & How They Were Built

The Futuristic HUD Boot-up Sequence
First impressions matter. When a user lands on the site, they are greeted with a dynamic “system loading” animation.
Using Framer Motion’s animate and variants, I staggered the entry of various UI panels to mimic a computer system powering up.

JavaScriptconst bootVariants = {hidden: { opacity: 0, scale: 0.95 },visible: { opacity: 1, scale: 1,transition: { duration: 0.8, ease: “easeOut” }}};

Glowing Neon & Cyberpunk AestheticsA true HUD needs to look alive. I heavy relied on CSS box-shadow and drop-shadow filters combined with subtle infinite floating animations. By using Framer Motion’s animate={{ y: (0, -5, 0) }} with a loop transition, elements appear to float seamlessly in space.
Interactive Data PanelsEvery section (About, Projects, Experience) behaves like an interactive module. When you switch tabs, the data doesn’t just instantly appear; it clips, slides, and reveals itself like data stream lines on a real monitor.

🧠 Challenges I FacedPerformance Optimization: Rendering multiple heavy glowing elements and continuous animations can easily drop frame rates. I optimized this by using layoutId for smooth layout transitions and ensuring hardware acceleration was active for transforms.

Responsive Design: HUDs are notoriously difficult to make mobile-friendly because they rely on fixed panels. I had to create a completely adapted layout for smaller screens that retains the “cyber” feel without cluttering the viewport.

🎯 Conclusion & Key TakeawaysBuilding this portfolio taught me a lot about the fine line between “cool animations” and “good user experience.” Framer Motion made it incredibly easy to orchestrate complex UI timelines that would have taken hundreds of lines of pure CSS.

What do you think of this high-tech approach? Would you use a HUD-style layout for your own portfolio, or do you prefer classic minimalism?

Check out the live site here: Akshay Bhawar Portfolio

Let me know your thoughts or drop your questions in the comments below! 👇



Source link

Vendor Chunking: The React Optimization I Wish I’d Known Earlier



I ignored my bundle size for months. By the time I checked, my production build was several megabytes of JavaScript in a single file — and every deploy forced my users to download all of it again. Vendor chunking is what I wish I’d known earlier.

Let’s say you are building a project using React, and for that project you need some component library, a library to handle date-related things, or a library to handle your state. So you reach for the usual suspects — Material UI, dayjs, TanStack Query, Redux and so on.

Initially, everything will work smoothly for you as well as for your end users. But as you keep shipping new features and adding dependencies, the bundle quietly grows. Locally, you don’t notice. But in production, it’s the end users who end up paying the price. What happens behind the scenes is that, when dependencies are included in the initial bundle, they can significantly increase the JavaScript downloaded by the browser. As a result, you end up with a poor Lighthouse score, slow initial load times, and a large JavaScript bundle — all of which hurt the user experience.

Your production build looks like this:

dist/assets/index-xxxx.js → 1.2 MB

Enter fullscreen mode

Exit fullscreen mode

This is exactly the kind of problem vendor chunking is designed to solve.

What is Vendor Chunking?

Vendor chunking is a technique where you can separate the third-party dependencies from your main bundle chunk. So you will have a main chunk which will contain your main application code and a vendor chunk which will contain the third-party dependency code.

How does Vendor Chunking help with large bundle size?

When you implement vendor chunking, your application is typically split into at least two separate bundles:

Main Chunk: Contains your application code
Vendor Chunk: Contains third-party dependencies and libraries

When a user visits your website for the first time, the browser downloads both chunks and stores them in the cache. This is where caching becomes very useful.

It’s worth noting that vendor chunking doesn’t come into play on the user’s first visit, because the browser still has to fetch both the chunks. The real performance gains show up when a user revisits the website and the cached vendor chunk can be reused.

Since third-party dependencies do not change frequently, the vendor chunk usually remains the same across deployments. On the other hand, whenever you ship new features, bug fixes, or other updates, your application code changes — which results in a new main chunk being generated.

When you generate a new production build, the bundler will again create:

A new main chunk containing the updated application code
The same vendor chunk, because the dependency code has not changed

Now consider this scenario where a user’s browser has already cached both the chunks because the user has already visited your website, and you deploy a new feature to the production. As a result, the user’s browser only needs to download the new main chunk, while the cached vendor chunk can be reused. This is how vendor chunks help in improving user experience.

Vendor Chunking in Action

Now let’s understand this whole thing using the code. I have a React project where I have installed multiple dependencies such as MUI, Chart.js, Lodash, dayjs and React Router.

Before Vendor Chunking, the build will look something like this:

Note: I’ve disabled tree-shaking for this demo to keep the bundle size large and make the impact of vendor chunking more visible.

The build will contain only one JS file and the browser has to download this large ~4.6 MB file.

Now I will implement vendor chunking by adding this code block in my vite.config.ts file:

Note: I’m using Vite v8, which uses Rolldown as the bundler. If you’re on an older Vite version with Rollup, the config syntax will be different

So after this, the build will look something like this:

As you can see, now we have two JS files:

Now the browser has to download both of these files so that our application loads correctly. Here comes the crazy part. Let’s update the code and try to generate the new production build. Here’s what it will generate:

If you compare the files with the previous build, you will find that only index-xx.js changed, while vendor-xx.js stays the same, because we didn’t upgrade any package versions; we only updated the application code.Now when a user revisits our website, the browser will only fetch the new index-xx.js from the server, vendor-xx.js will be served from cache.

This is how vendor chunking helps in performance improvement for web applications.

Splitting Vendors Further

So far we have bundled all the dependencies into a single chunk. This works well for small to medium applications, but as the dependency list grows, a single vendor chunk has a drawback. If you update the version of any library, a new vendor chunk will be generated and users have to re-download the whole thing – even if 95% of the code is same.

To tackle this issue, we can split vendors into multiple chunks. For example, you can keep your UI library in one chunk, your utility libraries in another, and your charting library in a third:

The final node_modules group is a catch-all so dependencies like React land in a vendor chunk too, rather than your main bundle.

After this config, your build output will look something like this:

Note: Just don’t go overboard with splitting — too many small chunks can hurt performance due to HTTP overhead and less effective compression

Wrapping Up

Vendor chunking is one of those optimizations that costs you a few lines of config and pays you back on every deploy. The core idea is simple: your application code changes often, third-party code doesn’t — so why force your users to re-download libraries they already have?

If you haven’t audited your production bundle in a while, run a build and take a look. You might be surprised how much of it is third-party code waiting to be cached properly.



Source link