DEV Community

Cover image for How React + Vite Actually Works Behind the Scenes Breakdown
Kathirvel S
Kathirvel S

Posted on

How React + Vite Actually Works Behind the Scenes Breakdown

You type npm run dev, press Enter… and your React app shows up instantly in the browser.

It feels effortless.

But here’s the thing — it shouldn’t feel like magic if you really want to get good at this.

As A2D Nandha puts it:

“If you want to crack it, you need to understand the system.”

That idea hits hard, especially in development. Because behind that one simple command, a full system wakes up — a dev server spins up, modules start flowing, transformations happen in milliseconds, and your browser begins assembling your app piece by piece.

So naturally, the question comes up:

What actually just happened after I hit that command?

If you’ve ever been curious about that moment — not just using the tool, but truly understanding it — you’re in the right place.

Let’s walk through it like you’re watching the whole system come alive in real time.


Dev Server Initialization (npm run dev & Vite CLI)

The moment you run this command, your system reads the package.json file and executes the script mapped to "dev" — usually something like:

vite
Enter fullscreen mode Exit fullscreen mode

This starts a development server on your machine.

A development server is simply a local program that:

  • Serves your files to the browser
  • Watches for changes
  • Updates your app instantly

Think of it less like “running your app” and more like “making your app available to the browser on demand.”

Quick picture in your head:
It’s like opening a live streaming room. You haven’t started the content yet — but the room is ready, the camera is on, and viewers (your browser) can now connect.

At this point, nothing is bundled. Nothing is optimized. Vite is just getting ready to serve files as they are.

And that’s where things start getting interesting.


On-Demand Module Serving (Vite Dev Server vs Bundlers)

Traditional tools like Webpack bundle your entire app before showing anything in the browser.

Vite flips that idea completely.

Instead of preparing everything upfront, Vite:

  • Starts the server instantly
  • Waits for the browser to request files
  • Sends only what’s needed

This is possible because modern browsers understand something powerful: ES Modules.

Imagine this:
You walk into a library. Instead of getting a giant stack of every book you might need, you just ask for one book at a time — exactly when you need it.

Less waiting. Less overload. More speed.


Native ES Modules (ESM) in the Browser

In older setups, browsers couldn’t handle import and export directly. Everything had to be bundled into one big file.

Now, with ES Modules:

  • Each file is treated as a module
  • The browser can request them individually
  • Dependencies are resolved step-by-step

So when your browser loads your app, it doesn’t download one giant file.

Instead, it reads your entry file and follows the import chain like a map.

Think about it like Google Maps:
You don’t load the entire world map in full detail. You zoom into your route, and more details load as needed.

That’s exactly how your app is being loaded.


Application Entry Point (main.jsx Bootstrapping)

Your app begins execution from a file like:

main.jsx
Enter fullscreen mode Exit fullscreen mode

This file usually does something like:

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
Enter fullscreen mode Exit fullscreen mode

This is the root of your application.

From here:

  • The browser loads App.jsx
  • Then any components inside it
  • Then their dependencies

It’s a chain reaction — one import leads to another.

Picture this:
It’s like turning the first domino. Once it falls, everything else follows in sequence — clean, predictable, and controlled.


JSX Transpilation (ESBuild & React Transform)

Here’s something important:

Browsers do not understand JSX.

This:

<h1>Hello</h1>
Enter fullscreen mode Exit fullscreen mode

…is not valid JavaScript.

So before the browser can execute your code, JSX must be converted into plain JavaScript.

Vite uses ESBuild to do this transformation on the fly.

For example:

<h1>Hello</h1>
Enter fullscreen mode Exit fullscreen mode

becomes something like:

React.createElement("h1", null, "Hello");
Enter fullscreen mode Exit fullscreen mode

This transformation happens:

  • Instantly
  • In memory
  • Without slowing down your app

Think of it like subtitles in a movie:
You’re watching content in one language (JSX), but your brain (browser) understands another (JavaScript). Vite quietly translates it in real time — no delay, no interruption.


Hot Module Replacement (HMR) Runtime

You change one line of code… hit save… and your app updates immediately.

No refresh needed.

This is Hot Module Replacement (HMR).

Here’s what’s actually happening:

  1. Vite detects a file change
  2. It identifies which module changed
  3. It sends an update to the browser
  4. The browser replaces only that part

So instead of reloading the entire page, only the affected component updates.

This is why:

  • Your app state is preserved
  • Updates feel instant
  • Development feels smooth

Imagine editing a Google Doc with live sync:

You change one sentence — and it updates instantly for everyone, without reloading the whole document.

That’s HMR in action.


File System Watching (Chokidar / FS Events)

Vite uses a file watcher running in the background.

This watcher:

  • Monitors your project files
  • Detects changes immediately
  • Triggers updates when needed

It’s constantly active while your dev server is running.

Think of it like auto-save on steroids:

The moment you hit save, something is already reacting — no button clicks, no manual refresh.


Browser Module Graph & Request Lifecycle

When you open http://localhost:5173, the browser:

  1. Requests the HTML file
  2. Reads the <script type="module"> tag
  3. Loads your entry file (main.jsx)
  4. Follows every import
  5. Requests each module from Vite

Each request goes back to the Vite server, which:

  • Transforms code if needed
  • Sends it back immediately

So your app is built on demand, piece by piece.

Visualize this:

It’s like assembling a Lego model — but instead of getting the full set at once, each piece arrives exactly when you need to place it.


React Virtual DOM & Reconciliation Process

Now here’s where React itself steps in.

What is Virtual DOM?

The Virtual DOM is a lightweight JavaScript representation of the real DOM (the actual UI in the browser).

Instead of directly updating the browser UI every time something changes, React:

  1. Creates a virtual copy of the UI
  2. Compares it with the previous version (diffing)
  3. Updates only the parts that changed

Why does this matter?

Direct DOM updates are slow.

React avoids unnecessary work by being smart about what actually needs to change.

Let’s make this click:

Imagine you’re editing a large Excel sheet.

You change just one cell.

Would you:

  • Recreate the entire sheet from scratch ❌
  • Or update just that one cell ✅

React chooses the second option.

Another way to see it:
Think of a food delivery app UI.

If you add one item to your cart, the whole page doesn’t reload. Only the cart section updates.

That’s Virtual DOM working behind the scenes — calculating the smallest possible change and applying it efficiently.


Production Build Pipeline (Rollup Bundling & Optimization)

When you run:

npm run build
Enter fullscreen mode Exit fullscreen mode

Everything changes.

Now Vite:

  • Bundles your code using Rollup
  • Removes unused code (tree shaking)
  • Minifies files
  • Optimizes assets

Instead of many small module requests, your app becomes a few optimized files.

Think of development vs production like this:

  • Development → flexible, fast, easy to change
  • Production → compact, efficient, optimized

It’s like working with raw ingredients vs serving a finished dish.


End-to-End Execution Flow (React + Vite Architecture Summary)

Here’s the full flow in simple terms:

  • You start the dev server
  • The browser requests your app
  • Vite serves files as ES Modules
  • JSX gets transformed instantly
  • Dependencies load one by one
  • React uses Virtual DOM to update efficiently
  • Changes update via HMR

No heavy startup time. No unnecessary work.

Just fast, on-demand execution.


One Thing to Try Right Now (Trace the Module Graph)

Open your project and follow this flow manually:

  • Start at main.jsx
  • Jump to App.jsx
  • Then open a component inside it

Now imagine the browser doing the same thing — file by file.

That’s exactly how your app runs.


Once you see this clearly, React + Vite stops feeling like a tool…

…and starts feeling like a system you actually understand.


If you want, we can go deeper next — like what exactly you’ll see in the Network tab and how Vite handles caching and requests internally.

Top comments (1)

Collapse
 
buddingdeveloper profile image
Ebenezer

Good stuff Kathir,Learned something new today
This clarified a lot more than docs did!