196

Is it possible to detect whether the current version of React is development or production at runtime? I'd like to do something like this:

if (React.isDevelopment) {
  // Development thing
} else {
  // Real thing
}
Wingjam
  • 742
  • 8
  • 17
pfhayes
  • 3,667
  • 3
  • 19
  • 17

6 Answers6

310

This is best done emulating the Node way of doing things with your build tool - webpack, browserify - by exposing process.env.NODE_ENV. Typically, you'll have it set to "production" in prod and "development" (or undefined) in dev.

So your code becomes:

if (!process.env.NODE_ENV || process.env.NODE_ENV === 'development') {
    // dev code
} else {
    // production code
}

For how to set it up, see envify or Passing environment-dependent variables in webpack

Community
  • 1
  • 1
David L. Walsh
  • 24,097
  • 10
  • 61
  • 46
  • This worked for me, once I had installed `browserify` and `envify`. – pfhayes Mar 07 '16 at 18:50
  • 15
    `process is not defined` on the client. – trusktr Feb 26 '18 at 23:54
  • 6
    You need to use a build tool like webpack. – David L. Walsh Feb 28 '18 at 00:21
  • 29
    If you are using create-react-app, `process.env.NODE_ENV` will be "development" in development mode. – Joseph238 Feb 27 '19 at 16:14
  • 6
    Adding to @Joseph238's comment - when using create-react-app, `process.env.NODE_ENV` will be defined for you and you have access to it anywhere in your app. [See React documentation for detail](https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables). – Shawn Apr 06 '19 at 19:05
  • how do you import this process.env ? – Choco Apr 20 '19 at 21:51
  • 1
    @Joseph238 @ShaungCheng I've just created a fresh app using newest scripts using `create-react-app` but `process.env` doesn't have a variable `NODE_ENV`. – Can Poyrazoğlu Mar 16 '20 at 11:29
  • @ShaungCheng `process.env.NODE_ENV` is set in . Are you launching the app using "yarn start" and logging `process.env` inside the ES6 script? Webpack is probably inlining the process.env.NODE_ENV variable – Joseph238 Mar 17 '20 at 16:54
27

I use a helper file (in Typescript):

import process from "process";

const development: boolean = !process.env.NODE_ENV || process.env.NODE_ENV === 'development';

export default function isDev(): boolean
{
    return development;
}

Then elsewhere I use it like this:

import isDev from "./helpers/DevDetect";

if (isDev())
{
    ...
}
James
  • 30,496
  • 19
  • 86
  • 113
5

I wanted access to this from the index.html and desired a solution which didn't involve ejecting webpack or configuring it with additional modules and I came up with this.

Sources are David's answer above and the create-react-app documentation for using environment variables in the html file

if ( ! '%NODE_ENV%' || '%NODE_ENV%' === 'development') {
  // dev code
} else {
  // production code    
}
Max Carroll
  • 4,441
  • 2
  • 31
  • 31
5

import.meta.env should be all you need!

The import.meta object exposes context-specific metadata to a JavaScript module more here

As I see it, this is aligned with the newer esmodules import/export syntax, and is therefore the latest standard for reading environment variables in JS (and Typescript).

However, if import.meta is not available, then the env variables should be available to you in process.env (the good old commonJS way)

console.log(import.meta.env) // ...or process.env

/* dev */
{
  "MODE": "development",
  "DEV": true,
  "PROD": false,

}
/* prod */
{
  "MODE": "production",
  "DEV": false,
  "PROD": true,
}

this means you should be able to do stuff like

 import.meta.env.MODE;
 // or process.env.MODE;

OBS: the values inside the env object are different depending on what build tool your're using to run your app.

// create-react-app
{
  "NODE_ENV": "development",
  "PUBLIC_URL": "",
  "FAST_REFRESH": true
}

// vite-app
{
  "BASE_URL": "/",
  "MODE": "development",
  "DEV": true,
  "PROD": false,
  "SSR": false
}

// I haven't tested but I'm sure nextJS has it's own env setup
Felipe Chernicharo
  • 3,619
  • 2
  • 24
  • 32
1

If you have multiple environments in production as well. like testing (test branch), staging(staging branch) and production(master branch). Which you are handling with CICD

In this case, process.env.NODE_ENV will return 'production' in all 3 environments.

Hence If this is your case, I would recommend adding a variable in your .env files.

.env.production

REACT_APP_ENV = "prod"

.env.staging

REACT_APP_ENV = "staging"

.env.development

REACT_APP_ENV = "development"

So that you can create a function in your utils file.

export const isProdMode = (): boolean => {
  if (process.env.REACT_APP_ENV === 'prod') {
    return true;
  }
  return false;
}
vishal patel
  • 125
  • 1
  • 7
1

You don't need to change your webpack configuration - simply check if minifying has been enabled for your js code, which would only be the case in production. E.g. I have disabled logging with this simple trick. The element.type.name will be renamed by minifying.

    const MyElement = ({isProduction}) => (<div>Environment: {isProduction?'Production':'Development'}</div>);

    const MyElementEl = React.createElement(MyElement);
    const isProduction = (MyElementEl.type.name !== 'MyElement');

    if(isProduction) //will be true when your js sources are minified 
        console = { ...console, logX: console.log, log: () =>{ } };
        
    ReactDOM.render(<MyElement isProduction={isProduction}/>, document.getElementById("app"));
   

 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    <body>
    <div id="app" />
    </body>
Florian
  • 33
  • 7