JavaScript Strict Mode ('use strict') Explained

Learn what JavaScript strict mode does, how to enable it with 'use strict', and why it catches silent errors that normal JavaScript ignores. Includes practical examples and real-world usage patterns.

JavaScriptbeginner
10 min read

JavaScript was designed to be forgiving. Misspell a variable name? JavaScript silently creates a global. Assign to a read-only property? JavaScript shrugs and moves on. This tolerance was useful in the early days of the web, but it became a source of hard-to-find bugs as applications grew.

Strict mode, introduced in ECMAScript 5, changes this behavior. When you opt into strict mode with 'use strict', JavaScript throws errors for actions it would normally ignore silently. Think of it like switching your code editor from "ignore all warnings" to "treat warnings as errors." The same code runs, but now the language actively tells you when something looks wrong.

This tutorial covers what strict mode does, how to enable it, the specific errors it catches, and when you should (and should not) use it in your projects.

What Is JavaScript Strict Mode?

Strict mode is a restricted variant of JavaScript that eliminates some silent errors, fixes mistakes that make it difficult for engines to perform optimizations, and prohibits syntax that may conflict with future ECMAScript versions. It does not add new features; it changes how existing features behave.

When strict mode is active, JavaScript:

  • Throws errors instead of silently failing
  • Prevents accidental creation of global variables
  • Disallows duplicate parameter names
  • Makes eval and arguments behave more predictably
  • Blocks the use of deprecated or reserved syntax

Why Was Strict Mode Created?

JavaScript's original design allowed many operations that seemed convenient but caused real problems at scale:

ProblemNormal Mode BehaviorStrict Mode Behavior
Assigning to an undeclared variableCreates a global variable silentlyThrows ReferenceError
Assigning to a read-only propertyFails silentlyThrows TypeError
Deleting an undeletable propertyFails silently, returns falseThrows TypeError
Duplicate parameter namesLast value winsThrows SyntaxError
Using with statementAllowedThrows SyntaxError
Octal numeric literals like 0644Interpreted as octalThrows SyntaxError

The ECMAScript committee could not simply change the default behavior because millions of existing websites depended on the lenient rules. Instead, they made strict mode opt-in so developers could adopt it file by file or function by function.

How to Enable Strict Mode

Strict mode is enabled by placing the string 'use strict'; (or "use strict";) at the very top of a script or function body. The position matters: it must be the first statement, before any other code.

Enabling Strict Mode for an Entire Script

Place 'use strict'; at the top of your JavaScript file, before any other statements:

javascriptjavascript
'use strict';
 
let userName = 'Alice';
console.log(userName);
 
// This would throw a ReferenceError in strict mode:
// mistypedVariable = 'oops'; // ReferenceError: mistypedVariable is not defined

Every line of code in this file runs under strict mode rules. If any code violates those rules, the engine throws an error immediately instead of failing silently.

Enabling Strict Mode for a Single Function

If you only want strict mode inside a specific function, place the directive as the first statement inside the function body:

javascriptjavascript
function processPayment(amount) {
  'use strict';
  
  // All code inside this function runs in strict mode
  let total = amount * 1.08; // tax calculation
  
  // Accidentally omitting 'let' would throw an error here:
  // result = total; // ReferenceError: result is not defined
  
  return total;
}
 
// Code outside the function runs in normal (sloppy) mode
globalVar = 'this still works out here'; // no error in normal mode

This approach is useful when you need strict mode in new code but are working within a codebase that relies on normal mode behavior elsewhere.

ES6 Modules Are Always in Strict Mode

If you write modern JavaScript using import and export syntax, your code is automatically in strict mode. You do not need the 'use strict' directive:

javascriptjavascript
// This file uses ES6 module syntax, so strict mode is automatic
import { formatCurrency } from './utils.js';
 
export function calculateTotal(items) {
  // Strict mode is already active here
  let total = items.reduce((sum, item) => sum + item.price, 0);
  return formatCurrency(total);
}
ES6 Modules and Strict Mode

When using ES6 modules (files with import/export), strict mode is enabled automatically. Adding 'use strict' is harmless but redundant. This also applies to code inside class bodies, which always run in strict mode.

How Strict Mode Changes JavaScript Behavior

Strict mode modifies several key behaviors. Here are the most important changes, each with a concrete example.

Prevents Accidental Global Variables

In normal mode, assigning a value to a variable that was never declared creates a property on the global object. This is one of the most common sources of bugs in JavaScript:

javascriptjavascript
'use strict';
 
function calculateShippingCost(weight, distance) {
  // Typo: 'baseCost' instead of 'base_cost'
  baseCost = weight * 0.5; // ReferenceError: baseCost is not defined
  
  let base_cost = weight * 0.5;
  let distanceFee = distance * 0.02;
  return base_cost + distanceFee;
}
 
calculateShippingCost(10, 50);

Without strict mode, baseCost would silently become a global variable, and the function would return NaN because base_cost is undefined. With strict mode, you get an immediate ReferenceError pointing directly at the typo.

Makes Assignment Failures Throw Errors

In normal mode, assigning to read-only properties, non-writable properties, or getters without setters fails silently:

javascriptjavascript
'use strict';
 
const config = {};
Object.defineProperty(config, 'apiUrl', {
  value: 'https://api.example.com',
  writable: false,
});
 
// In normal mode, this silently fails. In strict mode:
config.apiUrl = 'https://hacked.com'; // TypeError: Cannot assign to read only property 'apiUrl'

This also applies to built-in read-only properties:

javascriptjavascript
'use strict';
 
undefined = 42;      // TypeError: Cannot assign to read only property 'undefined'
NaN = 'not a number'; // TypeError: Cannot assign to read only property 'NaN'
Infinity = 0;        // TypeError: Cannot assign to read only property 'Infinity'

Prevents Deletion of Undeletable Properties

javascriptjavascript
'use strict';
 
// Attempting to delete a non-configurable property
delete Object.prototype; // TypeError: Cannot delete property 'prototype' of function Object()

Changes this Behavior in Functions

In normal mode, this inside a regular function call defaults to the global object (window in browsers, global in Node.js). In strict mode, this is undefined:

javascriptjavascript
'use strict';
 
function showContext() {
  console.log(this); // undefined (not the global object)
}
 
showContext();

This change prevents a common class of bugs where methods accidentally modify the global object. It forces you to be explicit about what this refers to.

Disallows Duplicate Parameters

javascriptjavascript
'use strict';
 
// SyntaxError: Duplicate parameter name not allowed in this context
function merge(obj, obj) {
  // In normal mode, the second 'obj' silently shadows the first
  return obj;
}

Restricts eval Scope

In strict mode, variables declared inside eval do not leak into the surrounding scope:

javascriptjavascript
'use strict';
 
eval('var leakyVariable = 42;');
console.log(typeof leakyVariable); // "undefined" (strict mode prevents leaking)
 
// In normal mode, leakyVariable would be 42

Strict Mode vs Normal (Sloppy) Mode Comparison

FeatureNormal ModeStrict Mode
Undeclared variable assignmentCreates global variableReferenceError
Read-only property assignmentFails silentlyTypeError
Non-extensible object propertyFails silentlyTypeError
Deleting undeletable propertyReturns false silentlyTypeError
Duplicate function parametersLast parameter value winsSyntaxError
Octal literals (0644)Interpreted as octal (420)SyntaxError
this in plain function callsGlobal objectundefined
eval variable scopeLeaks into surrounding scopeContained within eval
with statementAllowedSyntaxError
arguments.calleeReturns the current functionTypeError
Setting arguments propertiesAllowedNo effect (disconnected from params)
Reserved words as variable namesSome allowedSyntaxError for implements, interface, let, package, private, protected, public, static, yield

Best Practices

Strict Mode Adoption Strategy

These practices help you adopt strict mode safely without breaking existing code.

Use ES6 modules whenever possible. Modules are strict by default, which eliminates the need to manually add 'use strict' to every file. If your project uses a bundler like Webpack or Vite, you are likely already writing modules.

Add 'use strict' to all non-module scripts. If you write scripts that load via <script> tags without type="module", place 'use strict' at the top of every file. This catches bugs early and prepares your code for eventual migration to modules.

Never place 'use strict' after code. The directive only works when it is the very first statement. If any expression or statement precedes it, the engine treats it as a regular string expression and ignores it.

Be cautious when concatenating strict and non-strict files. If you combine a strict-mode file and a non-strict-mode file into one bundle, the result depends on which file comes first. Bundlers handle this correctly for modules, but legacy concatenation scripts may not.

Test after enabling strict mode. When adding strict mode to an existing codebase, run your full test suite. Code that worked in normal mode may throw errors under strict mode, especially if it relies on implicit globals or sloppy this behavior.

Common Mistakes and How to Avoid Them

Watch Out for These Pitfalls

These mistakes trip up developers when they first start using strict mode.

Placing 'use strict' after a regular statement. The directive must be the first statement in a script or function. Even a simple variable declaration before it will silently disable it:

javascriptjavascript
let x = 10;
'use strict'; // This is now just a string expression, NOT a directive
y = 20;       // No error — strict mode is not active

Assuming this is always the global object. In strict mode, this is undefined in plain function calls. If your code accesses this.someProperty inside a utility function, it will throw a TypeError instead of reading from the global object.

Forgetting that eval behaves differently. Code using eval to create variables in the calling scope will break under strict mode because eval variables stay contained within the eval call.

Using octal literals for file permissions. If you work with file systems and use octal numbers like 0644, strict mode will throw a SyntaxError. Use the explicit 0o644 syntax instead, which is valid in both modes.

Not checking third-party libraries. Some older libraries rely on normal-mode behaviors like implicit globals. Wrapping them in a strict-mode context can cause unexpected ReferenceError exceptions.

When to Use (and Not Use) Strict Mode

ScenarioRecommendationReason
New project with ES6 modulesNo action neededModules are strict by default
New non-module scriptAdd 'use strict'Catches bugs from day one
Legacy codebase migrationAdd per-function firstAvoids breaking existing code
Third-party library wrapperDo not force strict modeMay depend on normal-mode behavior
Node.js applicationUse ES modules (.mjs)Built-in strict mode
Browser <script> tagsAdd 'use strict'Essential for bug prevention

Next Steps

Practice identifying strict mode errors

Take an existing JavaScript file and add 'use strict' at the top. Run it and fix every error that appears. This hands-on exercise will teach you the most common patterns that strict mode catches.

Migrate a project to ES6 modules

Convert your <script> tags to <script type="module"> and refactor files to use import/export. This gives you strict mode automatically plus better dependency management.

Learn about common strict mode errors

Explore the specific error types that JavaScript strict mode catches to understand each enforcement rule in depth.

Set up a linter for automatic enforcement

Configure ESLint with the strict rule to automatically flag files missing the 'use strict' directive. This ensures consistency across your entire team.

Rune AI

Rune AI

Key Insights

  • Opt-in enforcement: strict mode catches accidental globals, silent assignment failures, and deprecated syntax by throwing errors instead of ignoring them
  • ES6 modules are strict by default: modern projects using import/export get strict mode automatically without the directive
  • Migration is incremental: you can enable strict mode per function, then per file, without rewriting an entire codebase at once
  • Performance benefit: strict mode allows JavaScript engines to optimize more aggressively because the code has fewer ambiguous behaviors
  • Always use it: there is no practical reason to write new JavaScript code in normal mode in 2026
RunePowered by Rune AI

Frequently Asked Questions

Does strict mode make JavaScript slower?

No. Strict mode actually enables [JavaScript engine](/tutorials/programming-languages/javascript/what-is-a-javascript-engine-a-complete-guide)s to perform more optimizations because the code has fewer ambiguities. Some operations are slightly faster in strict mode because the engine does not need to check for legacy edge cases like implicit global creation or `with` scope resolution.

Can I use strict mode in just part of a file?

Yes. You can enable strict mode per function by placing `'use strict';` as the first statement inside the function body. The rest of the file continues to run in normal mode. This is especially useful when migrating large codebases incrementally.

Do modern frameworks already use strict mode?

Yes. React, Angular, Vue, and most modern frameworks use ES6 modules, which are automatically in strict mode. If you write code inside a framework project that uses a bundler (Webpack, Vite, Rollup), your code almost certainly runs in strict mode already.

Is 'use strict' still needed in 2026?

For ES6 modules and class bodies, it is redundant because they are strict by default. For standalone scripts loaded via `<script>` tags without `type="module"`, it is still necessary and recommended. Many Node.js projects using CommonJS (`require`) also benefit from adding it.

What happens if I mix strict and non-strict code?

Each script or function maintains its own mode. A strict-mode function called from non-strict code still runs in strict mode. Conversely, a non-strict function does not inherit strict mode from its caller. The mode is determined by where the `'use strict'` directive (or module boundary) appears in the source code.

Conclusion

JavaScript strict mode transforms silent failures into explicit errors, making it one of the simplest and most effective tools for writing reliable code. By adding 'use strict' to your scripts or using ES6 modules (which are strict by default), you get immediate feedback on typos, unsafe assignments, and deprecated syntax that would otherwise cause subtle bugs in production.