The virtual DOM is a lightweight JavaScript object tree that mirrors the structure of the real DOM. React builds this tree from JSX via createElement, diffs it on re-renders, and applies only the minimal set of changes to the actual browser DOM.
JSX is not HTML. It is syntactic sugar that a build tool like Babel transforms into React.createElement calls before the code reaches the browser. Each JSX tag becomes a function call that returns a plain JavaScript object describing an element's type, props, and children.
These plain objects form a tree called the virtual DOM. It has the same shape as the UI you described in JSX, but it exists entirely in memory as regular JavaScript data, not as browser DOM nodes.
When state changes, React calls your component again to produce a new virtual DOM tree, compares it with the previous one (reconciliation), and updates only the real DOM nodes that actually changed. This avoids expensive full-page re-renders.
Interview framing: define Virtual DOM in one sentence, then explain one concrete runtime behavior and one common pitfall with a short code example.