JavaScriptEnvironments

Environment detection in JavaScript

Conditional code for different runtimes & environments

Introduction

Environment detection in JavaScript depends on what features of the target environment you plan on using. There's no point in detecting the Node.js environment if you only plan on cross-platform features like the console or Error objects. There's also no point in searching for the window and document objects if you don't plan on using them. That's why the first step to environment detection is determining why you need it in the first place.

As mentioned before, JavaScript has many cross-platform objects. You can't accurately identify the current environment unless there is some known unique feature of the target environment only used by that environment. The second step is to identify specific objects to check for, or you'll end up misidentifying the environment.

The wrong way

Using libraries

A general rule is to not search for the existence of libraries:

if (jQuery !== undefined) {
  console.log("This is the browser");
}

Developers can always include dependencies after the fact.

Using variables

This is one of the more ridiculous ones I've seen:

/* SCRIPT 1: */
const node =  true;
// or:
node = true;
// or:
global.node = true;

/* SCRIPT 2: */
if (typeof node === true) {
  console.log("Hello, Node.js!");
}

Variables - global or otherwise - aren't environment-dependent! A variable defined in any environment will always have the same value unless you provide conditions to alter its value or make future updates.

The right way

Searching for the process object

The browser doesn't have a process object built in, we can search for it to determine if we're in a Node.js environment or not.

if (typeof process === "object") {
  console.log("You are using Node.js");
} else {
  console.log("You are not using Node.js");
}
Searching for the window.document or module.exports

Node.js doesn't have a window or window.document object, and browsers don't have a module or module.exports object by default:

// Browser:
if (typeof window !== "undefined" && typeof window.document !== "undefined") {
  console.log("You are using a browser");
}

// Node.js:
if (typeof module === "object" && typeof module.exports === "object") {
  console.log("You are using Node.js");
}

Closing thoughts

While I understand that there sometimes is a need for environment detection, you should consider if it is the best option for you. Remember, you can always separate the source code for each environment into separate scripts instead.

Separation of concerns is a principle used in programming to separate an application into units, with minimal overlapping between the functions of the individual units. The separation of concerns is achieved using modularization, encapsulation and arrangement in software layers.

Thank you for reading.