Environment
React: 18.x
Vite: 5.x
@vitejs/plugin-react: latest
Build tool: Vite (ESM)
Runtime: Docker (Node build stage + Nginx)
I am deploying a React 18 app built with Vite.
The app works perfectly in development, but fails at runtime in production with the following error:
Uncaught ReferenceError: React is not defined
at M0 (index-C741WXwA.js:28:113749)
The error happens immediately when the app loads in the browser.
What makes this issue confusing
I am using React 18 with the automatic JSX runtime
I do not use
React.createElementanywhere in my source codeAll JSX files use
.jsx.jsfiles contain no JSX (verified)No file uses
React.directly (verified)No JSX exists in barrel
index.jsfiles (verified)main.jsxexplicitly imports React
Vite Configuration
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
})
main.jsx
import React, { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.jsx'
import './index.css'
createRoot(document.getElementById('root')).render(
)
Question
What can cause ReferenceError: React is not defined in a React 18 + Vite production build when:
Automatic JSX runtime is used
No legacy JSX transform exists
No
React.createElementappears in the output
Dockerfile
# -------- BUILD STAGE --------
FROM node:22-alpine AS build
WORKDIR /app
# Bust cache with build arg - MANDATORY for fresh builds
ARG CACHEBUST=1
ENV CACHEBUST=$CACHEBUST
# Force no cache - print build info
RUN echo "Build ID: $CACHEBUST - $(date)"
# Copy package files
COPY package*.json ./
# FULL CACHE CLEAR - Remove everything and install fresh
RUN rm -rf node_modules && \
npm cache clean --force && \
npm ci --prefer-offline=false
# Copy source files
COPY . .
# FULL BUILD - Clear all caches and build fresh
RUN rm -rf node_modules/.vite dist .vite && \
npm run build && \
echo "Build complete - files:" && \
ls -la dist/assets/
# -------- RUN STAGE --------
FROM nginx:alpine
# Clear nginx cache
RUN rm -rf /var/cache/nginx/*
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/dist /usr/share/nginx/html
# Add cache-busting headers
RUN echo "Build completed at: $(date)" > /usr/share/nginx/html/build-info.txt
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]