Do ES6 Modules make the case of IIFEs obsolete?

IIFEs are generally used as a design pattern for providing “privacy” to an extent through anonymous closures. Does the emergence of ES6 modules make the usage of IIFEs obsolete?

Or do you still have use cases for IIFEs? If yes, an example to drive your case would be awesome!

Kleo Petrov's photo

IIFE was one of the most used patterns in the ES5 standard, as functions were the only way to declare a scoped block of code. So the following code will result with a ReferenceError:

(function() {
    var scoped = 42;

console.log(scoped); // ReferenceError

ECMAScript introduced the block scoped let and const, so instead of using an IIFE, we can have the following code:

    let scoped = 42;

console.log(scoped); // ReferenceError

The later example is way more clear and understandable.

IIFEs were used as a building block in the revealing module pattern. Its advantage is that it clearly separates between what is public and what is private:

var myModule = (function() {
    // private variable, accessible only inside the IIFE
    var counter = 0;

    function increment() {

    // publicly exposed logic
    return {    
        increment: increment

Instead of using this pattern, with ES6 we can use modules. Modules declare their own scope and variables created inside the module will not polute the global object:

// myModule.js

let counter = 0;

export function increment() {

// logic.js

import {increment} from 'myModule.js';


The only case, where you may want to use an IIFE is with an immediately-invoked arrow functions. Sometimes you only can produce a result via a sequence of statements, not via a single expression and if you want to inline these statements, you have to immediately invoke a function:

const SENTENCE = 'Hello world, how are you?';
const REVERSE = (() => {
    const array  = [...SENTENCE];
    return arr.join('');

Keep in mind, that you need to wrap the arrow function in parentheses (they doesn't wrap the whole function).

As a rule of thumb you want to avoid using IIFEs in ES6, as there are other way to handle global variable polution.

Madhankumar's photo

Kleo ePetrov can you explain that another way of handling the global variable pollution in ES6. Usually I used to wrap all my JS files with (function() {})(); IIFE, which will avoid polluting the global space.

Peter Scheler's photo

In sense of providing a private scope: YES, you don't need them.

ESM have their own scope and don't pollute the global scope.