
!function(){}(): what it is and why an IIFE is written that way
What an IIFE is, why it sometimes starts with !, + or void before function, and where it still shows up in JavaScript code today.
What is an IIFE?
You’ll sometimes find a line like this in a minified library or an old script
!(function () {
console.log("Hi!");
})();
It looks like a typo — an exclamation mark in front of function — but it’s entirely intentional. This is an IIFE, short for Immediately Invoked Function Expression: a function that gets defined and invoked in the same instant.
The most common form, the one usually taught, is this:
(function () {
console.log("Hi!");
})();
Parentheses around the function, followed by another pair that invokes it. But why does !function(){}() work the same way? And more importantly, why doesn’t simply writing function(){}() work?
The problem: declaration vs. expression
Try writing this in a JavaScript file:
function () {
console.log("Hi!");
}();
You get a syntax error. The reason is that the JavaScript engine, when it finds the function keyword at the start of a statement, expects a function declaration (function name() {}), not an expression. A function declaration can’t be invoked inline right after its definition: that trailing () doesn’t make sense to the parser in that context.
To make JavaScript treat function(){} as a function expression (something that produces a value, and is therefore callable), you need to signal to the parser that you’re not at the start of a statement. The best-known way is to wrap the whole thing in parentheses:
(function () {})();
But it’s not the only one.
The unary-operator trick
Any unary operator placed before function achieves the same effect, because a statement can’t start with an operator like !, +, -, or void. The parser therefore understands it’s reading an expression, and the function that follows is treated as a callable function expression.
!(function () {
console.log("Run with !");
})();
+(function () {
console.log("Run with +");
})();
void (function () {
console.log("Run with void");
})();
All three forms execute the function immediately, exactly like (function(){})(). The only difference is the value returned by the whole expression, which in practice almost nobody uses:
!function(){}()returnstrue(the negation ofundefined, which is falsy).+function(){}()tries to convert the return value to a number (usuallyNaN, sinceundefinedisn’t convertible).void function(){}()always returnsundefinedby construction — if that sounds familiar, it’s the same principle behind thevoidoperator explained in javascript:void(0), what is it?.
ℹ️ Watch the return value
If your IIFE needs to return something you’ll actually use (not just run code for its side effects), skip !/+ and use the classic parentheses form (function(){ return x; })().
Where it still shows up today
This pattern mostly appears in:
- Minified libraries or UMD wrappers, where every saved character counts and
!functionis one byte shorter than(function. - Concatenated scripts without a bundler, where the leading character also acts as a safety net: if the previous script doesn’t end with a semicolon, an expression starting with
(risks being parsed as a function call on the previous script. Starting with!,+, orvoidavoids the ambiguity. - Old jQuery/plugin code, where the goal was to create an isolated scope without polluting the global namespace.
Modern alternatives are better
With ES modules (import/export), every file already has its own isolated scope: you no longer need to wrap code in an IIFE just to avoid global variables. If you’re writing new code with a modern bundler, prefer modules. The IIFE is still worth recognizing when you run into it in legacy code or third-party bundles, though.

Co-Founder & CTO at PAPION. Senior full-stack engineer specializing in React, TypeScript, Node.js, and application security.