Skip to the solution
EasyFrontend7 min read

What is the role of a bundler like Webpack in a React project?

135 views

The problem

Question presented to candidate: "Why does a React project need a bundler at all? What is Webpack β€” or Vite β€” actually doing between your source files and the browser?"

What a strong answer should cover:

  • Two non-negotiable jobs: browsers cannot run JSX, and bare module specifiers like import React from "react" are not resolvable by the browser.
  • Module resolution and dependency graphing β€” following imports from an entry point.
  • Transformation β€” JSX and modern syntax through a compiler (Babel, SWC, esbuild, oxc).
  • Bundling and code splitting β€” combining modules, then splitting them again at route or import() boundaries.
  • Optimisation β€” minification, tree shaking (helped by the /* @__PURE__ */ annotations the JSX transform emits), and content hashing for cache busting.
  • Asset handling β€” CSS, images, fonts as importable modules.
  • Dev server with HMR, which is what preserves component state across edits.
  • The modern landscape: Webpack is the incumbent; Vite (Rollup/Rolldown + native ESM in dev) is the current default; Turbopack and Rspack are the Rust-based successors.
  • The architectural point: Webpack bundles before serving; Vite serves native ES modules on demand β€” that is why dev startup differs so much.

Clarifying questions expected:

  • "Are we talking about the development experience or the production build?" β€” the tools behave very differently in each.

Code / implementation expected: No. Being able to describe the pipeline and name what each stage produces is what is being tested.

  • webpack
  • bundler
  • build process
  • javascript

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

7 min read Β· 9 sections

Try it in the playground

Open any example in the playground to run and change it.

ReactCode splitting: what the bundler does with React.lazy
import { lazy, Suspense, useState } from "react";

// A dynamic import() is the SPLIT POINT the bundler looks for. Everything
// reachable only from here is emitted as a separate chunk and fetched the
// first time this component actually renders β€” not on initial page load.
//
// In a real project this would be:
//   const Settings = lazy(() => import("./Settings"));
//
// The playground has no second file, so we simulate the same shape with a
// promise that resolves to a module object with a default export.
const Settings = lazy(
  () =>
    new Promise((resolve) =>
      setTimeout(
        () =>
          resolve({
            default: function Settings() {
              return (
                <div style={{ background: "#eef", padding: 12, borderRadius: 8 }}>
                  <strong>Settings panel</strong>
                  <p style={{ margin: "6px 0 0", fontSize: 13 }}>
                    In a real build this arrived as its own chunk, requested
                    only when you clicked.
                  </p>
                </div>
              );
            },
          }),
        900, // stand-in for network latency fetching the chunk
      ),
    ),
);

export default function App() {
  const [show, setShow] = useState(false);

  return (
    <div style={{ padding: 24, fontFamily: "system-ui", lineHeight: 1.6, maxWidth: 460 }}>
      <h3>Code splitting with React.lazy</h3>
      <p style={{ fontSize: 14 }}>
        This chunk is not downloaded until it is needed. Suspense supplies the
        fallback while the request is in flight.
      </p>

      <button onClick={() => setShow((s) => !s)}>
        {show ? "Hide" : "Load"} settings
      </button>

      <div style={{ marginTop: 14 }}>
        {show && (
          <Suspense fallback={<em style={{ color: "#666" }}>Fetching chunk…</em>}>
            <Settings />
          </Suspense>
        )}
      </div>

      <p style={{ color: "#666", fontSize: 13 }}>
        Click Load and watch the fallback appear first. In a production build
        the Network panel would show a separate hashed .js file being fetched
        at exactly that moment.
      </p>
    </div>
  );
}

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 24 of 119 in React.js

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All React.js questions
Up nextEasy

What is `create-react-app` and when would you use it?

Continue