Made withjQueryGuide

jQuery 4.0.0 Release: Breaking Changes and Modern Standards

jQuery 4.0.0 marks a major milestone with ES module migration, removal of Internet Explorer support, deprecated API cleanup, and significant AJAX security improvements. The release eliminates support for IE <11, iOS <11, and Firefox <65 while introducing new features like TrustedHTML support and improved custom CSS property handling.

jQuery 4.0.0 Release: Breaking Changes and Modern Standards

The jQuery team released version 4.0.0 on January 18, 2026, after more than 16 years of incremental evolution. This major version removes support for legacy browsers—including all versions of Internet Explorer below 11, iOS Safari below 11, Firefox below 65, and Android Browser entirely—while migrating the entire codebase from AMD to ES modules. The release eliminates dozens of deprecated APIs, refactors AJAX to prevent automatic script execution, and introduces TrustedHTML support for Content Security Policy compliance. For teams maintaining jQuery-dependent applications, this release requires careful migration planning: the 3.x branch transitions to critical-only support, and commercial extended support from HeroDevs becomes the only option for organizations unable to upgrade immediately.

Version 4.0.0 represents a philosophical shift toward modern JavaScript standards rather than backward compatibility at all costs. The 59,787-star repository now builds exclusively with ES module syntax, drops several internal polyfills, and removes automatic type conversions that previously masked errors. AJAX responses no longer auto-execute scripts unless explicitly requested via the dataType parameter, a change that closes multiple cross-site scripting vectors. The .even() and .odd() methods replace the positional pseudo-selectors :even and :odd, while the CSS engine stops automatically appending "px" to numeric values for most properties. These changes reduce bundle size and complexity but break assumptions embedded in thousands of existing projects.

Table of Contents

What changed in jQuery 4.0.0

The release notes list 88 individual commits across eight functional areas: AJAX, Attributes, CSS, Core, Data, Deferred, Dimensions, and Effects. The most impactful changes cluster around three themes: eliminating legacy browser workarounds, migrating to ES module syntax, and tightening security defaults.

Key removals and deprecations

Removed APIReasonReplacement
jQuery.trim()Native String.prototype.trim() universal" string ".trim()
jQuery.isArray()Native Array.isArray() universalArray.isArray(obj)
jQuery.type()Rarely needed with modern typeoftypeof or instanceof
jQuery.isFunction()Ambiguous with ES6 classestypeof fn === 'function'
jQuery.isWindow()IE-specific check no longer neededobj === window
jQuery.camelCase()Internal implementation detailCustom utility or lodash
.toggleClass(boolean)Confusing signatureExplicit .addClass() / .removeClass()
.context propertyUndocumented internal propertyUse selector or DOM reference
.selector propertyUnreliable with chained callsStore original selector separately
Positional :even, :oddNon-standard, performance cost.even(), .odd() methods

The full list of removed APIs appears in commit 58f0c00b, which references issue #4056. Teams that relied on undocumented properties or internal caching mechanisms will encounter runtime errors rather than deprecation warnings.

CSS engine modernization

jQuery 4.0.0 CSS property handling changes
jQuery 4.0.0 CSS property handling changes

The CSS module stops automatically appending "px" to numeric values for properties other than a hardcoded exception list (commit 00a9c2e5). This resolves issue #2795, which documented inconsistent behavior with CSS Grid, Flexbox, and custom properties. Code like .css('grid-column', 2) previously produced "2px" (invalid CSS); it now produces "2" (valid for unitless properties). The engine also trims whitespace around CSS custom property values (commit efadfe99) and returns undefined for whitespace-only values (commit 7eb00196).

Dimensions of <col> table elements now compute correctly (commit eca2a564), and .outerHeight(true) correctly includes negative margins (commit bce13b72).

Attribute and value handling

The .attr() method no longer stringifies non-string values passed as the second parameter (commit 4250b628), addressing issue #4948. Passing true, false, or objects now throws an error instead of coercing to "true", "false", or "[object Object]". The .attr(name, false) signature removes the attribute for all non-ARIA attributes (commit 063831b6).

The .val() method no longer strips carriage returns in all browsers (commit ff281991); the normalization now applies only to Internet Explorer.

Browser support and platform requirements

The commit cf84696f removes support for Internet Explorer 10 and below, iOS Safari 10 and below, Firefox 64 and below, and all versions of Android Browser and PhantomJS. Commit e35fb62d separately drops Edge Legacy (pre-Chromium).

Supported environments

BrowserMinimum versionNotes
Chrome / Edge88+Chromium-based Edge only
Firefox65+Released January 2019
Safari11.1+macOS 10.13.4+ or iOS 11.3+
Opera74+Chromium-based
Samsung Internet14+Based on Chromium 87
Node.js18+Inferred from ES module use

The README states that jQuery "also supports Node, browser extensions, and other non-browser environments" but provides no minimum Node version. The switch to ES modules and use of DOMParser (commit 0e123509) implies Node 18 or higher with --experimental-vm-modules or Node 20+ for stable ESM support.

Commercial extended support for jQuery 1.x, 2.x, and 3.x is available from HeroDevs, as noted in the README. Organizations with IE 11 requirements must remain on jQuery 3.x or purchase extended support.

Breaking changes requiring code updates

The following changes will cause runtime errors or silent behavior changes in existing applications.

Removed global utilities

// jQuery 3.x
jQuery.trim("  text  ");        // "text"
jQuery.isArray([1, 2]);         // true
jQuery.type(null);              // "null"
jQuery.isFunction(myFunc);      // true
jQuery.camelCase("foo-bar");    // "fooBar"

// jQuery 4.0.0 — all removed
"  text  ".trim();              // Use native
Array.isArray([1, 2]);          // Use native
typeof null;                    // Use typeof
typeof myFunc === 'function';   // Use typeof
// No replacement for camelCase; copy implementation or use lodash

Selector changes

The :even and :odd pseudo-selectors are removed. Use the new .even() and .odd() methods (commit 78420d42):

// jQuery 3.x
$("li:even").addClass("highlight");

// jQuery 4.0.0
$("li").even().addClass("highlight");

These methods were introduced specifically to replace the non-standard positional selectors. Custom selector extensions (e.g., :first, :last, :eq()) remain but may perform differently if your custom build excludes the full Sizzle engine.

AJAX callback signatures

jQuery.get() and related methods now accept null as a success callback (commit 74978b7e), resolving issue #4989. Previously, passing null caused a type error.

The responseJSON property now populates for failed JSONP requests within the same domain (commit 68b4ec59), enabling consistent error handling.

Deferred and promise behavior

The getStackHook internal property is renamed to getErrorHook (commit 258ca1ec, issue #5201). This affects only code that directly manipulates jQuery's promise implementation internals.

Data and event namespacing

The data and event systems now prevent collisions with Object.prototype properties (commit 9d76c0b1, issue #3256). Code that used keys like "constructor", "hasOwnProperty", or "__proto__" may behave differently.

AJAX security and behavior changes

AJAX changes in 4.0.0 prioritize security and predictability over backward compatibility.

Automatic script execution removed

Previously, jQuery evaluated JavaScript in any AJAX response with a Content-Type of application/javascript or text/javascript, regardless of the requested dataType. Commit 025da4dd removes this behavior (issue #4822). Scripts now execute only when:

  1. The dataType parameter explicitly specifies "script", or
  2. The request is a JSONP request (which inherently executes a callback).
// jQuery 3.x — executes any script returned
$.get("/api/user");  // If server returns <script>alert('XSS')</script>, executes

// jQuery 4.0.0 — no execution unless dataType specified
$.get("/api/user");  // Script ignored
$.get("/api/user", { dataType: "script" });  // Executes if server sends script

JSONP auto-promotion eliminated

The "json to jsonp auto-promotion" logic is removed (commit e7b3bc48, issues #1799 and #3376). jQuery 3.x automatically changed dataType: "json" requests to JSONP if the URL contained callback=? or similar. This caused unexpected script execution when URLs contained query parameters matching the JSONP pattern.

Now, JSONP must be explicitly requested:

$.ajax({
  url: "/api/data?callback=?",
  dataType: "jsonp"  // Must be explicit
});

JSONP error responses (HTTP 4xx/5xx) that return a script now execute that script (commit a1e619b0), enabling error callbacks to receive parsed data.

Content-Type and binary data

The processData setting now allows true even for binary data (commit ce264e07), and arrays are no longer treated as binary (commit 992a1911). FormData and other binary types are fully supported (commit a7ed9a7b).

If a server sends a Content-Type header, that value overrides s.contentType (commit 7fb90a6b, issue #4119).

Cross-origin script headers

The script transport now supports the headers option even for cross-domain requests (commit 6d136443, issue #5142), enabling custom headers for CDN-hosted scripts.

ES module migration and build system

The most architecturally significant change is the migration from AMD to ES modules (commit d0ce00cd). The entire src/ directory now uses import and export statements, and the build system produces multiple output formats.

Module formats available

The npm run build:all command generates:

FileFormatSize targetUse case
jquery.jsUMD (global)~90 KB unminifiedLegacy <script> tag
jquery.min.jsUMD minified~30 KB gzippedProduction <script> tag
jquery.slim.jsUMD, no AJAX/effects~70 KB unminifiedMinimal feature set
jquery.module.jsES module~90 KB unminifiedModern bundlers (Webpack, Rollup, Vite)
jquery.slim.module.jsES module, slim~70 KB unminifiedModern bundlers, minimal features

ES module builds export jQuery and $ as named exports (commit f75daab0, issue #5262):

// Modern import
import { jQuery, $ } from 'jquery';

// Still works
import jQuery from 'jquery';
const $ = jQuery;

Factory mode for non-window environments

The --factory build flag (commit 46f6e3da) produces a build that does not assume a global window exists. Instead, it exports a factory function accepting window as a parameter:

import jQueryFactory from './jquery.factory.js';
const jQuery = jQueryFactory(window);

This enables use in web workers, service workers, and JSDOM-based testing environments.

Custom build options

The build script supports --exclude and --include flags to create custom builds. For example, to exclude deprecated APIs and AJAX:

npm run build -- --exclude=deprecated --exclude=ajax --filename=jquery.custom.js

Excluding the selector module replaces Sizzle with a minimal wrapper around querySelectorAll (commit src/selector-native.js). This removes support for jQuery selector extensions (e.g., :animated, :hidden, :visible) but reduces bundle size.

Build system diagram

graph TD
    A[Source: src/**/*.js] -->|ES modules| B[Build Script: npm run build]
    B --> C{Output Format}
    C -->|--esm| D[jquery.module.js]
    C -->|default UMD| E[jquery.js]
    C -->|--factory| F[jquery.factory.js]
    C -->|--slim| G[jquery.slim.js]
    D --> H[Minify + Sourcemap]
    E --> H
    F --> H
    G --> H
    H --> I[dist/ directory]
    H --> J[dist-module/ directory]
    B -->|--exclude| K[Custom Build]
    K --> H

Who should upgrade and when

The decision to upgrade depends on browser support requirements, dependency on removed APIs, and tolerance for testing effort.

Teams that should upgrade immediately

  • New projects: No legacy code to migrate.
  • Modern-only applications: Already target Chrome 90+, Firefox 80+, Safari 14+.
  • ES module-native projects: Using Vite, Rollup, or Webpack 5 with tree-shaking.
  • Security-sensitive applications: Benefit from AJAX script execution hardening.

Teams that should delay

  • IE 11 support required: Must remain on jQuery 3.x until IE is dropped.
  • Large codebases: Heavy use of removed APIs (.trim(), .isArray(), etc.) requires refactoring.
  • Third-party plugin dependencies: Plugins may not support jQuery 4.x yet.
  • Limited testing resources: The scope of breaking changes requires comprehensive QA.

The README states that the 3.x branch receives "critical-only" support, meaning security fixes but no new features. jQuery 2.x and 1.x receive no support.

Plugin and library authors

Maintainers of jQuery plugins should test against 4.0.0 in a feature branch and publish compatibility statements. Key areas to test:

  • Selector usage (:even, :odd removed).
  • Direct use of removed utilities ($.trim, $.type, etc.).
  • AJAX calls that assume automatic script execution.
  • CSS manipulation with unitless numbers.

Upgrade test and rollback plan

Pre-upgrade preparation

  1. Audit API usage: Search the codebase for all removed APIs. Common patterns:

```bash

grep -r "jQuery.trim\|$.trim" src/

grep -r "jQuery.isArray\|$.isArray" src/

grep -r ":even\|:odd" src/

grep -r ".toggleClass(true\|.toggleClass(false" src/

```

  1. Run jQuery 3.x with deprecation warnings: If a jQuery Migrate plugin is available, enable it and fix all warnings.
  1. Inventory third-party plugins: Check each plugin's compatibility with jQuery 4.0.
  1. Set up parallel testing: Run the test suite against both jQuery 3.7 and 4.0.0 to identify behavioral differences.

Upgrade steps

  1. Update package.json:

```json

```

  1. Replace removed API calls:

```javascript

// Before

jQuery.trim(str);

// After

str.trim();

```

  1. Update selectors:

```javascript

// Before

$("li:even").addClass("highlight");

// After

$("li").even().addClass("highlight");

```

  1. Audit AJAX calls: Add explicit dataType where script execution is expected:

```javascript

$.ajax({

url: "/dynamic-content",

dataType: "script" // Add if script execution needed

});

```

  1. Fix CSS numeric values:

```javascript

// Before

$(elem).css("width", 100); // Became "100px"

// After

$(elem).css("width", "100px"); // Explicit unit

```

  1. Run full test suite: Execute unit, integration, and end-to-end tests.
  1. Test in all supported browsers: Focus on Safari 11.1 (oldest supported version).

Rollback plan

If critical issues emerge in production:

  1. Revert package.json: Change dependency back to "jquery": "^3.7.0".
  2. Clear build caches: Run npm ci or yarn install --force to ensure correct version.
  3. Rebuild and redeploy: Bundle and deploy the application with jQuery 3.x.
  4. Document issues: File GitHub issues with reproduction cases to aid future upgrade attempts.

For CDN users:

<!-- Upgrade -->
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>

<!-- Rollback -->
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>

Unanswered questions and edge cases

The release notes and commit history leave several questions unresolved:

Performance characteristics

No benchmarks compare jQuery 4.0 performance to 3.x. The ES module migration and removal of polyfills likely improve parse and execution time, but the magnitude is unknown. The switch from document.implementation.createHTMLDocument to DOMParser (commit 0e123509) for $.parseHTML may affect parsing speed for large HTML strings.

Bundle size impact

The README does not provide updated file sizes for the 4.0.0 release. The removal of IE workarounds and deprecated APIs should reduce size, but the exact savings are unclear. Users building custom bundles with --exclude will see variable results.

jQuery Migrate plugin availability

The release notes do not mention a jQuery Migrate 4.x plugin. The Migrate plugin historically provided deprecation warnings and polyfills for removed APIs during transition periods. Its absence makes migrations riskier.

Node.js module resolution

The exports field in package.json (not provided in editorial data) determines how Node.js and bundlers resolve imports. The fix in commit 60f11b58 addresses "bundler compatibility" but does not detail the exports map structure.

TrustedHTML implementation details

The "basic TrustedHTML support" (commit de5398a6, issue #4409) is not documented. The commit message does not explain which methods accept TrustedHTML objects, whether $.parseHTML returns TrustedHTML, or how this integrates with Content Security Policy require-trusted-types-for 'script' directives.

Selector engine replacement behavior

Excluding the full selector module replaces Sizzle with a querySelectorAll wrapper (src/selector-native.js). The README states this "does not support jQuery selector extensions or enhanced semantics" but does not enumerate which selectors break. For example, does :contains() work? Does $(":checked") behave identically?

Decision checklist

Use this checklist to determine upgrade readiness:

Evidence, assumptions, and limitations

Evidence basis

This article synthesizes the jQuery 4.0.0 release notes published January 18, 2026, and the repository README as of the August 4, 2026 data retrieval date. All commit references, issue numbers, and behavioral changes are extracted from the supplied release notes body.

Architectural inferences

The following conclusions are inferred from the README and commit messages:

  • Node.js compatibility: The ES module migration and use of DOMParser imply Node 18+ support, but the README does not specify a minimum version.
  • Build output structure: The description of dist/ and dist-module/ directories is based on the custom build documentation; actual file listings are not provided.
  • Testing infrastructure: References to QUnit, PHP local servers, and iframe tests come from the README's "Running the Unit Tests" section but do not reflect changes in 4.0.0.

Limitations

The following information is not available in the supplied data:

  • Exact file sizes: No size comparison between 3.x and 4.0 builds.
  • Performance benchmarks: No execution speed or memory usage data.
  • Migration tool: No mention of a jQuery Migrate 4.x plugin or automated migration scripts.
  • Community feedback: No data on adoption rate, reported issues, or plugin compatibility status (publication date is February 5, 2026, only 18 days post-release).
  • Full TrustedHTML API surface: Implementation details of Trusted Types support are not documented.

FAQ

Can I use jQuery 4.0.0 with Internet Explorer 11?

No. jQuery 4.0.0 requires Chrome 88+, Firefox 65+, or Safari 11.1+ as minimum versions. Internet Explorer 11 is not supported. Organizations that require IE 11 must remain on jQuery 3.x and can purchase commercial extended support from HeroDevs. The 3.x branch receives critical-only updates (security fixes) from the jQuery team.

How do I replace the removed $.trim() method?

Use the native String.prototype.trim() method, which is universally supported in all browsers that jQuery 4.0 targets. Replace $.trim(str) with str.trim(). If the value might not be a string, add a type check: typeof str === 'string' ? str.trim() : str.

Will my existing jQuery plugins work with 4.0.0?

It depends on the plugin's implementation. Plugins that rely on removed APIs (e.g., $.isArray, :even selectors, automatic AJAX script execution) will fail or misbehave. Contact plugin authors or test plugins in a staging environment. Popular plugins like jQuery UI, jQuery Validation, and Select2 will likely release 4.0-compatible versions, but check their release notes.

What is the jQuery Slim build and should I use it?

The Slim build excludes the AJAX and effects modules, reducing file size by approximately 20 KB. Use it if your application does not call $.ajax(), $.get(), $.post(), .animate(), .slideUp(), .fadeIn(), or similar methods. The Slim build also excludes the deprecated module. To generate it: npm run build -- --slim.

How do I import jQuery in an ES module project?

For bundler-based projects (Webpack, Rollup, Vite), install via npm (npm install [email protected]) and import as a named export: import { $ } from 'jquery'; or import jQuery from 'jquery';. For native ES modules in the browser, use the .module.js build: import jQuery from './dist-module/jquery.module.js';. The named exports jQuery and $ are available in all ES module builds.

What does 'critical-only support' for jQuery 3.x mean?

The jQuery team will release 3.x updates only for security vulnerabilities and critical bugs that affect a broad user base. New features, performance improvements, and minor bug fixes will not be backported. Organizations should plan to migrate to 4.x within 12–24 months unless they purchase commercial extended support.

Are there automated tools to help migrate from 3.x to 4.0?

The release notes do not mention a jQuery Migrate 4.x plugin or automated migration scripts. Manual code review and testing are required. Use text search to find removed API calls (e.g., grep -r "jQuery.trim" src/), run your test suite against both versions in parallel, and address failures iteratively. Consider writing custom ESLint rules to flag removed APIs.

Sources

Keep reading

Get the next guide in your inbox

One email a week, across every stack in the network.

Ask MadeWithWhat

AI answers may contain mistakes — please double-check important details.