"Required is not defined" and Runtime Environments
Always keep in mind your runtime environment and which Modules Standard is implemented there.

If you work in web development, you have probably seen this at some point. It happens when you try to require(...)
a module in the browser.
You searched the solution and discovered that the problem is that you cannot use require(...);
in the browser. The browser does not understand that, and it complains.
To get to the bottom of why this is, we need to dive into two different topics which are tightly coupled: runtime environment and Javascript modules. One depends on the other because to know when to use a module standard, we need to know in which runtime environment our code is executed.
Runtime Environment
Every programming language has at least one runtime environment, which can also be called a runtime system. It’s a set of programs that manage the execution of the language.
The runtime environment can have different responsibilities depending on the programming language; such as memory management, interfacing with the operating system, garbage collection, or threading.
For example, in C, the runtime system is a particular set of instructions inserted into the executable file by the compiler. These instructions manage the stack, create space for local variables, and set up the stack with parameters when a new function is called.
Javascript Runtime Environment
In the Javascript world, there are two popular types of Runtime environments. On one side, we have the browser environments with Chrome, Firefox, Safari, etc. On the other side, node.js.
In both cases, the environment gives the developer a set of tools to help with the execution of code:
A standard library with built-in functions such as “map” in Array.
APIs that extend the functionality of the language itself, e.g. “document.getElementById” in the browser.
A JS engine that executes the code, such as V8 in Chrome.
Javascript Modules
In a nutshell, a module is a piece of code that can be reused. Actually, any JS file can become a module. Yet, there are different ways to reuse this code, as well as different standards of how to specify we are using a module.
These are the main standards at the moment: CommonJS, AMD, and ES6 Modules.
CommonJS
CommonJS was started in 2009 by Mozilla engineer Kevin Dangoor. I find his quote revealing of what JS Modules standards are:
"What I’m describing here is not a technical problem. It’s a matter of people getting together and making a decision to step forward and start building up something bigger and cooler together."
- Kevin Dangoor, 2009
In this standard, the way to specify what is exported in a file is done using module.exports
, and the import is done through the require
function:
const lodash = require(‘lodash’);
Asynchronous Module Definition or (AMD)
AMD was developed as a way to load modules asynchronously because the CommonJS standard was not well suited for the browser environment. Therefore, some people got together to come up with a new standard.
The API proposed in this standard is a function called defined
that takes the dependencies and a callback that is executed when the module has been loaded—enabling the asynchronicity of the modules.
define("alpha", ["require", "exports", "beta"], function (require, exports, beta) {
exports.verb = function() {
return beta.verb();
//Or:
return require("beta").verb();
}
});
ES6 Modules
ES6 Modules is the newest way proposed to use modules. It uses import
and export
keywords to specify what a module exposes and how to use the module in another file.
import { useState } from ‘react’;
Implementations of Javascript Modules Standards
The previous items in the list are just standards or conventions. These conventions need to be implemented somewhere so that developers can use them.
There are different ways to implement the standards. For example, NodeJS implements the CommonJS standard, whereas the library RequireJS implements AMD for browsers.
The new ES6 modules standard is already implemented by the most modern browsers and the latest versions of NodeJS.
As we can see, there are different ways to implement a standard; either the runtime environment offers the functionality, or a library can do so.
When we start a project and want to use modules, our first step is to ask, which is my runtime system? Which standard does it implement?
Multiple Runtime Environments
Current frontend development is a little bit tricky. Sometimes, it’s hard to understand in which runtime environment the code is being executed. For example, if we use create-react-app, we import modules with ES6 Modules; yet, the code can be run in a browser that does not support ES6 Modules.
With create-react-app, we use multiple runtime systems at the same time—each for different purposes. For example, NodeJS is used to create the file (or files) executed in the browser. This creation of files is also known as the build step.
The file (or files) created in the build step already has all its dependencies. Therefore, when this file is executed on the website, it does not need to use any modules.
You can use ES6 Modules even if you are using a Node version that does not support them. Create-react-app uses a library called Babel that implements the ES6 Modules standard. In this case, even though we are using NodeJS, we don’t rely on the implementation of JS modules offered by NodeJS. Instead, we rely on a library to implement the standard we want to use.
Know your Runtime Environment and Module Standard
Now that we understand modules and runtime environments we can understand the errors better.
This error happens because we are trying to use the CommonJS format in the browser. The browser runtime environment does not support CommonJS.
Browser + CommonJS → NOT SUPPORTED
This other error is when we are trying to use ES6 Modules in Node version 12, which does not support ES6 Modules.
Node v12 + ES6 Modules → NOT SUPPORTED
In summary, always keep in mind your runtime environment and which Modules Standard is implemented there.