Back to Blog
jQuery 4.0 Features: A Practical Hands-on Guide (After 10 Years of Waiting)
A no-nonsense hands-on guide to jQuery 4.0.0 features. Learn how to test ES Modules, handle breaking changes, and why you might (or might not) upgrade.
Back
Frontend

Table of contents
jQuery 4.0 Features: A Practical Hands-on Guide (After 10 Years of Waiting)
Ten years. That's how long it took to get a major jQuery update. Most of us have moved on to React, Vue, or just plain Vanilla JS, but let's be honest—jQuery is still everywhere. I just spent the last four hours digging through the 4.0.0 release candidate to see if it's actually better or just another layer of technical debt.
Spoiler: It's a massive cleanup. If you're still supporting IE10, don't even bother reading. For the rest of us, here's how to actually test these features without breaking your sanity.
Browser Compatibility: jQuery 4.0 drops support for Internet Explorer entirely. You'll need modern browsers that support ES6+ features. Think Chrome 90+, Firefox 88+, Safari 14+, or Edge 90+.
1. Testing the Move to ES Modules
Finally, jQuery isn't just a global object hanging off the window. It's now authored in ES modules. This means you can import it directly in modern browsers without needing a bundler that feels like it's about to overheat your laptop.
Modern ES Module Usage
html
<script type="module">
import $ from 'https://code.jquery.com/jquery-4.0.0.module.js';
$(() => {
console.log('jQuery version:', $.fn.jquery); // Should be 4.0.0
$('body').css('background', '#f4f4f4');
});
</script>Handling Legacy Plugins
The 2 AM Reality: It feels weirdly modern. Not having to worry about the order of <script> tags is a relief, but remember: if you're using old plugins that expect window.jQuery to exist globally, they will crash. You'll have to manually expose it or refactor those ancient scripts.
Here's how to bridge the gap:
javascript
// Option 1: Expose jQuery globally for legacy plugins
import $ from 'https://code.jquery.com/jquery-4.0.0.module.js';
window.jQuery = window.$ = $;
// Now your old plugins will work
import 'legacy-plugin.js'; // Expects window.jQueryjavascript
// Option 2: Refactor to ES modules (recommended)
import $ from 'https://code.jquery.com/jquery-4.0.0.module.js';
import { legacyPlugin } from './legacy-plugin-modernized.js';
$(() => {
legacyPlugin.init();
});2. Breaking Changes: The Utility Cleanup
The team finally grew a backbone and deleted functions that have been deprecated since the dawn of time. If your code uses these, it's going to scream at you.
Complete List of Removed Functions
These utility functions have been removed in jQuery 4.0. You'll need to replace them with native JavaScript equivalents:
$.isArray()→Array.isArray()$.isFunction()→typeof x === 'function'$.isNumeric()→!isNaN(parseFloat(x)) && isFinite(x)$.trim()→String.prototype.trim()$.type()→typeoforObject.prototype.toString.call()$.isWindow()→x != null && x === x.window$.isPlainObject()→ Use a library like Lodash or write your own check
Migration Examples
The "What Just Happened?" Test: Try running any of these in the console with jQuery 4.0.
javascript
// ❌ This will throw a TypeError in 4.0
try {
const isArr = $.isArray([1, 2, 3]);
const trimmed = $.trim(' hello ');
const isNum = $.isNumeric('123');
} catch (e) {
console.warn('These functions no longer exist!');
}
// ✅ Use native alternatives instead
const isArr = Array.isArray([1, 2, 3]);
const trimmed = ' hello '.trim();
const isNum = !isNaN(parseFloat('123')) && isFinite('123');Before/After Migration Patterns
javascript
// Before (jQuery 3.x)
function validateForm(data) {
if ($.isArray(data.items)) {
const clean = $.trim(data.name);
if ($.isNumeric(data.age)) {
return true;
}
}
return false;
}
// After (jQuery 4.0)
function validateForm(data) {
if (Array.isArray(data.items)) {
const clean = data.name.trim();
if (!isNaN(parseFloat(data.age)) && isFinite(data.age)) {
return true;
}
}
return false;
}Real-world take: Look, if you're still using $.trim() in 2026, we need to have a talk. Native String.prototype.trim() has been supported since forever. This cleanup is long overdue, but it means you can't just "drop-in" 4.0 and expect it to work without a search-and-replace session.
Pro Tip: Use your IDE's "Find and Replace" with regex to quickly migrate:
- Find:\$.isArray(→ Replace:Array.isArray(
- Find:\$.trim(→ Replace:.trim(
- Find:\$.isNumeric(→ Replace with your numeric check function
Quick Migration Checklist
Before upgrading to jQuery 4.0, run through this checklist:
- [ ] Search your codebase for all removed utility functions (
$.isArray,$.trim,$.isNumeric, etc.) - [ ] Test in a separate branch - never upgrade production directly
- [ ] Check plugin compatibility - verify all jQuery plugins work with 4.0
- [ ] Update build tools - ensure your bundler supports ES modules if needed
- [ ] Verify browser support - confirm your target browsers are modern enough
- [ ] Run your test suite - if you have one (you should)
- [ ] Test form validations - especially if you rely on focus event order
- [ ] Check CSP policies - if you use strict Content Security Policy
3. Trusted Types and CSP
This is the "boring but important" part. If you've ever fought with a strict Content Security Policy (CSP), you know the pain of XSS errors. jQuery 4.0 now supports Trusted Types, which helps you work with strict CSP without violating security policies.
Understanding the Problem
When you have a strict CSP, operations like $('#container').html(userContent) can trigger violations because the browser can't verify the content is safe. Trusted Types API allows you to create a policy that sanitizes content before it's used.
The Security Check
javascript
// If your policy requires Trusted Types, jQuery 4.0 plays nice
const policy = window.trustedTypes.createPolicy('myPolicy', {
createHTML: (string) => {
// Sanitize the HTML - remove script tags, etc.
return string.replace(
/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
''
);
},
});
const safe = policy.createHTML('<b>Verified Content</b>');
$('#container').html(safe); // No CSP violation here.Common CSP Violations (Before jQuery 4.0)
javascript
// ❌ This would trigger CSP violation in strict mode
$('#container').html(userGeneratedContent);
// ✅ With jQuery 4.0 and Trusted Types
const safeContent = trustedTypesPolicy.createHTML(userGeneratedContent);
$('#container').html(safeContent);When Do You Need This?
You'll need Trusted Types support if:
- Your security team requires strict CSP headers
- You're building enterprise applications with security audits
- You're handling user-generated content that needs sanitization
- You're working in regulated industries (finance, healthcare, etc.)
The 2 AM Reality: You probably won't care about this until your security auditor starts breathing down your neck. But when they do, you'll be glad you're on 4.0.
4. The New Focus Event Order
This one is subtle and potentially annoying. jQuery now follows the W3C spec for focus event order: blur → focusout → focus → focusin. Previously, jQuery had its own order that didn't match the spec, which could break form validation logic.
Understanding the Impact
If your form validation relies on the specific order of focus events, this change will break your logic. The old jQuery order was different from the W3C standard, and now jQuery 4.0 aligns with the spec.
How to Test It
javascript
$('#myInput').on('blur focusout focus focusin', (e) => {
console.log(`Fired: ${e.type} at ${new Date().getTime()}`);
});
// Click away from input, then click back in
// You'll see the new order in consoleReal-World Example: Form Validation
javascript
// ❌ Old code that might break
let validationState = 'idle';
$('#email').on('focus', () => {
validationState = 'checking';
// This might fire in wrong order now
});
$('#email').on('blur', () => {
if (validationState === 'checking') {
// This logic might not work as expected
validateEmail();
}
});
// ✅ Better approach - use specific events
$('#email').on('focusin', () => {
// User is focusing in
showValidationHint();
});
$('#email').on('focusout', () => {
// User is leaving the field
validateEmail();
});Migration Strategy
- Identify all focus event handlers in your codebase
- Test form interactions - especially multi-step forms
- Check validation timing - ensure validations fire at the right time
- Update event listeners - use
focusin/focusoutfor better cross-browser support
Check your logs. If your form validation relied on the old "jQuery-only" order, your logic is now officially broken. Fix it.
Common Pitfalls
Here are the most common issues you'll encounter when upgrading:
Pitfall 1: Plugin Compatibility
Problem: Old plugins expect window.jQuery to exist.
Solution: Either expose jQuery globally or update plugins to use ES modules.
javascript
// Quick fix
import $ from 'jquery';
window.jQuery = window.$ = $;Pitfall 2: Third-Party Libraries
Problem: Libraries that bundle their own jQuery might conflict.
Solution: Check if libraries have been updated for jQuery 4.0, or use a single jQuery instance.
Pitfall 3: Build Tools
Problem: Older bundlers might not handle ES modules correctly.
Solution: Update to modern bundlers (Webpack 5+, Vite, Rollup) that support ES modules natively.
Pitfall 4: Form Validation Logic
Problem: Focus event order changes break validation timing.
Solution: Refactor to use focusin/focusout explicitly instead of relying on event order.
Pitfall 5: Utility Function Dependencies
Problem: You forgot to replace all $.trim() calls.
Solution: Use a linter or automated tool to find and replace all instances before upgrading.
Final Verdict: Should you care?
- Ship it if: You're building something new and want to keep it lightweight with ESM, or you need to pass a strict security audit.
- Skip it if: You're maintaining a legacy monster with 50+ jQuery plugins from 2014. The refactoring nightmare isn't worth the 3KB you'll save on gzipped size.
- Wait if: You're comfortable on 3.7.x and don't want to spend your weekend fixing
$.isArraycalls. jQuery 3.7.x is still maintained and secure.
Related Article: For a comprehensive overview of what changed and why it matters, read jQuery 4.0: What Actually Changed (And Why It Matters).
Resources & Links
Share Your Experience
Migrated to jQuery 4.0? Hit a wall? Found a workaround? Share your migration story in the comments below. Your pain (and solutions) might save someone else's weekend.
Comments
No comments yet
Loading comments...