← Back to gaearon/react-hot-loader

How to Deploy & Use gaearon/react-hot-loader

# React Hot Loader: Deployment & Usage Guide

> **⚠️ Deprecation Notice:** React Hot Loader is deprecated. Use [React Fast Refresh](https://github.com/facebook/react/issues/16604) instead. Fast Refresh is supported in React Native (≥0.61), Parcel 2 (≥alpha 3), Create React App (≥4 with `FAST_REFRESH=true`), Next.js (≥9.4), and via the `react-refresh-webpack-plugin` for webpack. Only use React Hot Loader if your bundler/environment does not yet support Fast Refresh.

---

## 1. Prerequisites

* **Node.js** (v10+ recommended) and **npm** or **yarn** package manager.
* A JavaScript bundler that supports Hot Module Replacement (HMR). The most common setup is **webpack** with `webpack-dev-server`.
* A React application (v16.8+ recommended for full hooks support).

---

## 2. Installation

Install the package as a regular dependency. It is safe for production as it self-disables in non-development environments.

```bash
npm install react-hot-loader
# or
yarn add react-hot-loader

3. Configuration

3.1 Babel Plugin (Required)

Add react-hot-loader/babel to your Babel configuration (.babelrc, babel.config.js).

{
  "plugins": ["react-hot-loader/babel"]
}

Important: The Babel plugin is required for:

  • Correctly handling React component updates.
  • Enabling hook order change detection (which triggers a remount).
  • Supporting the "old API" for incompatible bundlers like Parcel.

3.2 Mark Root Component as Hot

In your application's root component file (e.g., src/index.js or src/App.js), wrap your root component with the hot function from react-hot-loader/root.

// App.js
import { hot } from 'react-hot-loader/root';

const App = () => <div>Hello World!</div>;

export default hot(App);

For Parcel or other incompatible bundlers, use the legacy API:

import { hot } from 'react-hot-loader';

const App = () => <div>Hello World!</div>;

// Note the double invocation: hot(module)(App)
export default hot(module)(App);

3.3 Ensure Patch Load Order

The react-hot-loader patch must be applied before react and react-dom are loaded. Choose one method:

Method A: Import in your main entry file (before any React imports)

// src/index.js
import 'react-hot-loader'; // Must be first
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
// ... render logic

Method B: Prepend to webpack entry point

// webpack.config.js
module.exports = {
  entry: ['react-hot-loader/patch', './src/index.js'],
  // ...
};

3.4 (Optional) @hot-loader/react-dom for Advanced HMR

For the most resilient HMR experience, especially with hooks and complex components, replace react-dom with the patched version @hot-loader/react-dom.

Using Yarn (preferred):

yarn add react-dom@npm:@hot-loader/react-dom

Using npm or Webpack alias:

npm install @hot-loader/react-dom

Then, in webpack.config.js:

module.exports = {
  // ...
  resolve: {
    alias: {
      'react-dom': '@hot-loader/react-dom',
    },
  },
};

3.5 (Optional) Configuration API

You can adjust behavior via setConfig before any React code runs.

import { setConfig } from 'react-hot-loader';

setConfig({
  // Disable ALL hook reloading (use with caution)
  reloadHooks: false,
  // Reload hooks (useEffect, useCallback, useMemo) when their body changes, even with empty deps
  reloadHooksOnBodyChange: true, // default: true
  // Reload lifecycle methods (componentDidMount, etc.) on every change
  reloadLifeCycleHooks: false, // default: false
});

4. Build & Run

Development (with HMR)

Start your development server with HMR enabled.

For webpack-dev-server:

webpack serve --hot --open
# or older versions
webpack-dev-server --hot --open

For other bundlers: Enable their respective HMR flags. React Hot Loader will automatically hook into the process.

Production Build

No special configuration is needed. The Babel plugin and runtime are safe for production and have minimal footprint. Ensure your bundler's production mode is set correctly.

# Example with webpack
NODE_ENV=production webpack --mode production

Note: Hot reloading is inactive in production builds. The code only handles updates during development.


5. Deployment

React Hot Loader is a development-time tool only. It does not affect your production deployment. Deploy your production build (from step 4) to any standard static hosting platform:

  • Vercel / Netlify: Push your production build folder (e.g., build/, dist/) or connect your Git repository.
  • AWS S3 + CloudFront: Upload build artifacts and configure static hosting.
  • Docker: Create an image with a web server (like Nginx) serving the static files.
  • Traditional VPS: Use a web server (Apache, Nginx) to serve the build directory.

Remember: Remove React Hot Loader if your target environment supports Fast Refresh. It is not needed in production and should not be included in your final deployment bundle if you want to minimize size (though its footprint is very small).


6. Troubleshooting

HMR Not Working / Components Not Updating

  1. Check patch order: Ensure react-hot-loader/patch or import 'react-hot-loader' is executed before react and react-dom.
  2. Verify Babel plugin: Confirm react-hot-loader/babel is in your Babel config and that your bundler is using that Babel configuration.
  3. Root component: Ensure your root component is wrapped with hot() from react-hot-loader/root (or the legacy hot(module) for Parcel).
  4. Webpack config: For webpack, ensure devServer.hot is set to true (or use --hot flag).

Hooks Not Updating on Change

  • By design, useState and useEffect with an empty dependency array ([]) preserve state and do not re-run on hot updates.
  • To force a hook to re-run on every update, add a dummy dependency like ['hot']:
    useEffect(() => {
      // effect code
    }, ['hot']);
    
  • If you changed a hook's dependency array, a full remount of the component (and its children) will occur. This is expected behavior.

"You are erroneously trying to use a Babel plugin as a Webpack loader"

  • Cause: You added react-hot-loader/babel to the loaders array in webpack config instead of the plugins section of your Babel config.
  • Fix: Remove it from webpack's module.rules. Add it only to your .babelrc or babel.config.js under plugins.

Using with Parcel

  • Parcel (v1) is not compatible with the new /root API.
  • You must use the legacy API: export default hot(module)(App);
  • The Babel plugin is required for Parcel to work correctly.

"Module has been replaced but did not re-export the default export"

  • This can happen if your component file uses multiple export statements (named and default) and the Babel plugin cannot track them correctly.
  • Fix: Ensure your component file has a single export default statement for the main component. Move named exports to a separate file or use export { NamedComponent } after the default export.

React Version Compatibility

  • React Hot Loader patches React's internals. It includes specific patches for different React versions (see src/webpack/patch.js).
  • If you upgrade React major versions (e.g., 16.x -> 17.x), ensure you are using a compatible version of react-hot-loader. Check the project's release notes.

State Not Preserving on Some Changes

  • Certain changes (like changing a component from a function to a class, or altering hook order) will cause a full remount, resetting state. This is a safety measure.
  • The Babel plugin helps minimize unnecessary remounts. Ensure it is active.

"ReferenceError: Can't find variable: reactHotLoader"

  • Cause: The react-hot-loader runtime was not loaded before your application code.
  • Fix: Double-check step 3.3. The import/patch must be the very first thing in your entry bundle.
// Correct order in entry file:
import 'react-hot-loader'; // 1. Load RHL runtime
import React from 'react'; // 2. Then load React
import ReactDOM from 'react-dom';
// ...
// Correct webpack entry:
entry: ['react-hot-loader/patch', './src/index.js']