How the Create React App Error Overlay Displays Runtime Errors
Create React App injects a development-only iframe-based UI called react-error-overlay that captures runtime exceptions via global error handlers, stores them as ErrorRecord objects, and renders a full-screen React component tree inside an isolated iframe.
When you run npm start in a Create React App (CRA) project, the development environment includes a sophisticated error handling system designed to catch and display runtime JavaScript errors before they crash your application. According to the facebook/create-react-app source code, this system operates through a four-stage pipeline that bridges the webpack hot module replacement client and a dedicated React-based overlay UI.
How the Error Overlay Captures Runtime Errors
The error detection mechanism begins long before any UI appears. It starts in the webpack development client and propagates through global browser error hooks.
Registering the Runtime Error Listener in webpackHotDevClient
The entry point for error reporting is packages/react-dev-utils/webpackHotDevClient.js. During initialization, this file calls ErrorOverlay.startReportingRuntimeErrors() with a callback that sets a critical state flag:
const ErrorOverlay = require('react-error-overlay');
ErrorOverlay.startReportingRuntimeErrors({
onError: () => {
hadRuntimeError = true;
},
});
This hadRuntimeError flag serves a vital purpose in the hot reloading lifecycle. When set to true, it signals that the application state may be corrupted. If a subsequent hot update is deemed unsafe, CRA forces a full page reload rather than attempting to patch the module.
Hooking Into Global Error Handlers
Inside packages/react-error-overlay/src/index.js, the startReportingRuntimeErrors function imports listenToRuntimeErrors from listenToRuntimeErrors.js. This utility attaches listeners to three critical error sources:
window.onerrorfor synchronous exceptionswindow.onunhandledrejectionfor unhandled Promise rejections- The
ErrorUtilsglobal (used internally by React)
When any of these listeners fire, they create an ErrorRecord object containing the error instance, parsed stack frames, and context. This record passes to handleRuntimeError, which manages the UI state.
Rendering Runtime Errors in the Error Overlay
Once captured, errors must be displayed in isolation from your application code to prevent the error UI itself from crashing. CRA achieves this by mounting the overlay inside a sandboxed iframe.
Storing Errors and Updating the Iframe
The handleRuntimeError function (defined in packages/react-error-overlay/src/index.js lines 83-100) executes the onError callback, deduplicates identical errors by checking currentRuntimeErrorRecords, and pushes the new record into that array. It then calls update():
function handleRuntimeError(options) {
return function (errorRecord) {
if (typeof options.onError === 'function') {
options.onError();
}
if (currentRuntimeErrorRecords.some(r => r.error === errorRecord.error)) {
return;
}
currentRuntimeErrorRecords.push(errorRecord);
update();
};
}
The update() function creates a hidden iframe on first run, loading iframeScript (a pre-bundled script containing the React UI). When the iframe signals readiness via window.__REACT_ERROR_OVERLAY_GLOBAL_HOOK__.iframeReady, updateIframeContent() serializes the error records and passes them to iframe.contentWindow.updateContent.
The React Component Hierarchy Inside the Iframe
Inside the iframe, the UI renders as a standard React component tree defined in packages/react-error-overlay/src/components/ErrorOverlay.js and related containers:
<ErrorOverlay>- The root component that handles keyboard shortcuts (Esc to close, arrow keys to navigate)<RuntimeErrorContainer>- Manages state for multiple runtime errors, rendering navigation controls<RuntimeError>- Displays individual error details using:<Header>- Shows the error name and message<StackTrace>- Renders clickable stack frames with theeditorHandlercallback
The editorHandler function, configured by CRA, allows users to click any stack frame to open their code editor directly to the offending line.
Code Examples: Working with the Error Overlay
The following examples demonstrate how CRA initializes the overlay and how it processes runtime errors internally.
Initializing the overlay in the development client:
// CRA’s dev client – registers the overlay (run automatically in `npm start`)
const ErrorOverlay = require('react-error-overlay');
ErrorOverlay.startReportingRuntimeErrors({
onError: () => {
// CRA sets a flag so the next successful compile forces a full reload
hadRuntimeError = true;
},
});
Handling a runtime error internally:
// Inside react‑error‑overlay – how a runtime error is recorded
function handleRuntimeError(options) {
return function (errorRecord) {
if (typeof options.onError === 'function') {
options.onError(); // CRA’s callback above
}
// Avoid duplicate entries
if (currentRuntimeErrorRecords.some(r => r.error === errorRecord.error)) {
return;
}
currentRuntimeErrorRecords.push(errorRecord);
update(); // triggers iframe re‑render
};
}
Rendering the error UI:
// The UI component that finally displays the error
function RuntimeError({ errorRecord, editorHandler }) {
const { error, stackFrames } = errorRecord;
const header = `${error.name}: ${error.message}`;
return (
<div style={wrapperStyle}>
<Header headerText={header} />
<StackTrace
stackFrames={stackFrames}
errorName={error.name}
editorHandler={editorHandler}
/>
</div>
);
}
Key Source Files for the Error Overlay
Understanding the error overlay architecture requires familiarity with these specific modules in the facebook/create-react-app repository:
packages/react-dev-utils/webpackHotDevClient.js- Starts the overlay in development and coordinates HMR / reload logicpackages/react-error-overlay/src/index.js- Core API (startReportingRuntimeErrors,reportRuntimeError, iframe handling)packages/react-error-overlay/src/components/ErrorOverlay.js- Wrapper that renders the overlay and handles shortcut keyspackages/react-error-overlay/src/containers/RuntimeErrorContainer.js- Manages navigation between multiple runtime errorspackages/react-error-overlay/src/containers/RuntimeError.js- Displays the error header and stack tracepackages/react-error-overlay/src/utils/parseCompileError.js- Parses stack frames for clickable "open in editor" links
Summary
- react-error-overlay is a development-only UI injected by Create React App to catch and display runtime JavaScript errors.
- The overlay registers global listeners via
startReportingRuntimeErrorsinwebpackHotDevClient.js, capturing exceptions fromwindow.onerror,window.onunhandledrejection, and React'sErrorUtils. - Errors are stored as
ErrorRecordobjects incurrentRuntimeErrorRecordsand rendered inside an isolated iframe to prevent conflicts with application code. - The UI consists of a React component hierarchy:
ErrorOverlay→RuntimeErrorContainer→RuntimeError→HeaderandStackTrace. - When a runtime error occurs, CRA sets
hadRuntimeError = true, forcing a full page reload on the next successful compilation if the hot update is unsafe.
Frequently Asked Questions
How does Create React App catch runtime errors without modifying my source code?
CRA injects the react-error-overlay package through the webpack development client (webpackHotDevClient.js). This client automatically calls ErrorOverlay.startReportingRuntimeErrors() when the development server starts, attaching listeners to global browser error events like window.onerror and window.onunhandledrejection. Because this happens in the dev client's entry point, your application source code remains unchanged.
Why does the error overlay use an iframe instead of rendering directly in the DOM?
The overlay renders inside a sandboxed iframe to achieve complete style and script isolation from your React application. This prevents CSS conflicts where your app's styles might accidentally hide or distort the error UI, and it ensures that if your application is in a broken state, the overlay can still function independently. The iframe loads a pre-bundled script that contains the React component tree for the error display.
What happens after I fix a runtime error and save the file?
When you save a fix, CRA's webpack dev server detects the change and attempts a Hot Module Replacement (HMR). However, because a runtime error previously set hadRuntimeError = true in webpackHotDevClient.js, CRA treats the application state as potentially corrupted. If the hot update is deemed unsafe or if the update fails, CRA automatically performs a full page reload to ensure your application starts from a clean state without any lingering error side effects.
Can I customize the error overlay or disable it in development?
While CRA does not expose official configuration options to customize the overlay's appearance, you can disable it by ejecting from CRA or by using environment variables that prevent the dev client from starting the overlay. However, disabling it is generally not recommended because the overlay provides critical debugging information including clickable stack traces that open directly in your code editor. If you need custom error handling, you would typically eject and modify webpackHotDevClient.js or fork react-error-overlay.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →