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 API | Reason | Replacement |
|---|---|---|
jQuery.trim() | Native String.prototype.trim() universal | " string ".trim() |
jQuery.isArray() | Native Array.isArray() universal | Array.isArray(obj) |
jQuery.type() | Rarely needed with modern typeof | typeof or instanceof |
jQuery.isFunction() | Ambiguous with ES6 classes | typeof fn === 'function' |
jQuery.isWindow() | IE-specific check no longer needed | obj === window |
jQuery.camelCase() | Internal implementation detail | Custom utility or lodash |
.toggleClass(boolean) | Confusing signature | Explicit .addClass() / .removeClass() |
.context property | Undocumented internal property | Use selector or DOM reference |
.selector property | Unreliable with chained calls | Store original selector separately |
Positional :even, :odd | Non-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

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
| Browser | Minimum version | Notes |
|---|---|---|
| Chrome / Edge | 88+ | Chromium-based Edge only |
| Firefox | 65+ | Released January 2019 |
| Safari | 11.1+ | macOS 10.13.4+ or iOS 11.3+ |
| Opera | 74+ | Chromium-based |
| Samsung Internet | 14+ | Based on Chromium 87 |
| Node.js | 18+ | 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:
- The
dataTypeparameter explicitly specifies"script", or - 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:
| File | Format | Size target | Use case |
|---|---|---|---|
jquery.js | UMD (global) | ~90 KB unminified | Legacy <script> tag |
jquery.min.js | UMD minified | ~30 KB gzipped | Production <script> tag |
jquery.slim.js | UMD, no AJAX/effects | ~70 KB unminified | Minimal feature set |
jquery.module.js | ES module | ~90 KB unminified | Modern bundlers (Webpack, Rollup, Vite) |
jquery.slim.module.js | ES module, slim | ~70 KB unminified | Modern 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,:oddremoved). - 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
- 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/
```
- Run jQuery 3.x with deprecation warnings: If a jQuery Migrate plugin is available, enable it and fix all warnings.
- Inventory third-party plugins: Check each plugin's compatibility with jQuery 4.0.
- Set up parallel testing: Run the test suite against both jQuery 3.7 and 4.0.0 to identify behavioral differences.
Upgrade steps
- Update package.json:
```json
```
- Replace removed API calls:
```javascript
// Before
jQuery.trim(str);
// After
str.trim();
```
- Update selectors:
```javascript
// Before
$("li:even").addClass("highlight");
// After
$("li").even().addClass("highlight");
```
- Audit AJAX calls: Add explicit
dataTypewhere script execution is expected:
```javascript
$.ajax({
url: "/dynamic-content",
dataType: "script" // Add if script execution needed
});
```
- Fix CSS numeric values:
```javascript
// Before
$(elem).css("width", 100); // Became "100px"
// After
$(elem).css("width", "100px"); // Explicit unit
```
- Run full test suite: Execute unit, integration, and end-to-end tests.
- Test in all supported browsers: Focus on Safari 11.1 (oldest supported version).
Rollback plan
If critical issues emerge in production:
- Revert package.json: Change dependency back to
"jquery": "^3.7.0". - Clear build caches: Run
npm cioryarn install --forceto ensure correct version. - Rebuild and redeploy: Bundle and deploy the application with jQuery 3.x.
- 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
DOMParserimply Node 18+ support, but the README does not specify a minimum version. - Build output structure: The description of
dist/anddist-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.