Contents

09/26/2026

jQuery 4: "$.trim is not a function" and other removed APIs

jQuery 4.0 removed $.trim, $.isArray, $.isFunction, $.parseJSON and other utility functions, so a plugin that still calls one throws TypeError: $.trim is not a function after the upgrade. Replace each call with its native equivalent, such as s.trim(), Array.isArray(v) or JSON.parse(s), and load jQuery Migrate in development to find every one.

jQuery 4.0.0 shipped on January 17, 2026, the first major release in almost ten years according to the official jQuery 4.0.0 announcement. Your own code probably survives the upgrade. The plugins you have not opened since 2016 are what break, because they lean on utility functions 4.0 deleted. The quickest way to find them is to load jQuery Migrate in development and read the console.

<!doctype html>
<script src="/js/jquery-4.0.0.js"></script>
<!-- Development only: the uncompressed build logs every deprecated call -->
<script src="/js/jquery-migrate-4.0.2.js"></script>
<script src="/js/old-carousel-plugin.js"></script>

What an old plugin hits

Loaded into a page with jQuery 4.0.0 alone, every one of these is simply gone:

jQuery 4.0.0
  $.trim: undefined
  $.isArray: undefined
  $.isFunction: undefined
  $.type: undefined
  $.parseJSON: undefined
  $.now: undefined
  $.isNumeric: undefined
  $.unique: undefined
  $.fn.push: undefined
  $.trim("  hi  ") threw TypeError: $.trim is not a function

With Migrate 4.0.2 loaded after it, the functions come back and each call logs where it came from:

JQMIGRATE: Migrate is installed with logging active, version 4.0.2
JQMIGRATE: jQuery.trim() is removed; use String.prototype.trim

That TypeError usually surfaces inside a plugin's init, so the visible symptom is a slider that never initializes, not an error pointing at the real line. Migrate turns it into a named warning with a stack trace.

The replacement table

Every removal has a native equivalent. This list follows the jQuery Core 4.0 upgrade guide:

Removed Use instead
$.trim(s) s.trim()
$.isArray(v) Array.isArray(v)
$.isFunction(v) typeof v === "function"
$.parseJSON(s) JSON.parse(s)
$.now() Date.now()
$.isNumeric(v) Number.isFinite(v), or your own check for numeric strings
$.isWindow(v) v != null && v === v.window
$.type(v) typeof, Array.isArray, instanceof
$.nodeName(el, n) el.nodeName.toLowerCase() === n
$.unique(arr) $.uniqueSort(arr)
$.cssProps Nothing; not needed in supported browsers
$.camelCase A small helper: s.replace(/-([a-z])/g, (_, c) => c.toUpperCase())
$.fx.interval Nothing; animations use requestAnimationFrame
.push() on a jQuery object .add()
.sort() on a jQuery object .toArray(), then the array's sort()
.splice() on a jQuery object .slice(), or .not() with .eq()

One trap in that table: $.isNumeric("42") returns true (checked against the version Migrate restores), and Number.isFinite("42") returns false, because it does not coerce strings. If a plugin validates form input with it, the like-for-like replacement is Number.isFinite(parseFloat(v)) or an explicit pattern, not Number.isFinite alone. The same goes for form checks in general: requiring at least one checked checkbox needs no library at all.

Patching a plugin you cannot upgrade

If the plugin is abandoned and the calls are few, fix them in place and keep a note of the file. Where that is not possible, a small shim restores only what you actually saw in the Migrate log:

// jquery4-shims.js: load after jQuery, before the old plugins.
// Remove each line when the plugin that needed it is gone.
(function ($) {
  if (!$.trim) $.trim = (s) => (s == null ? "" : String(s).trim());
  if (!$.isArray) $.isArray = Array.isArray;
  if (!$.isFunction) $.isFunction = (v) => typeof v === "function";
  if (!$.parseJSON) $.parseJSON = JSON.parse;
})(jQuery);

This is deliberately narrower than Migrate. Migrate also restores behavior and logs every call; a shim is for production after you know which calls remain. And some old plugins solve problems CSS now handles on its own, such as matching element heights across a row; those are better deleted than patched. The upgrade guide's intended path is Migrate in development, fix the warnings, then remove it.

Changes that are not missing functions

Some breaks do not throw. They behave differently, which is harder to spot.

Events

jQuery no longer shims focusin and focusout, and the announcement says focus events now follow the W3C order: blur, focusout, focus, focusin. Handlers that assumed the old relative order, such as a validation plugin listening to both, now run in a different sequence.

Ajax

A request for JSON is no longer auto-promoted to JSONP. Code that fetched cross-domain JSON by adding callback=? needs dataType: "jsonp" stated explicitly. Scripts are also not executed from a response unless you ask for dataType: "script" or use $.getScript().

CSS and classes

.css() no longer appends px to most unitless numbers; only a limited set of known properties still get it, so pass units explicitly. The toggleClass(boolean) signature, which stripped or restored all of an element's classes at once, is gone: name the classes you mean.

Data

The object returned by .data() no longer inherits from Object.prototype, so .data().hasOwnProperty("key") throws TypeError: ... hasOwnProperty is not a function. Use "key" in el.data() or Object.hasOwn(el.data(), "key").

Two traps outside the browser

Deep imports are blocked. jQuery 4 ships an exports map in package.json. In Node 24, require.resolve('jquery/dist/jquery.js') failed with ERR_PACKAGE_PATH_NOT_EXPORTED. Import jquery, jquery/slim, jquery/factory or jquery/factory-slim instead; those are the entry points the map declares.

Server-side use needs the factory. Under Node without a DOM, the guide replaces require("jquery")(window) with require("jquery/factory")(window).

Browsers and dependencies

jQuery 4 drops Internet Explorer 10 and older and Edge Legacy, and keeps IE 11 for now. The upgrade guide also states that jQuery 4.0.0 needs jQuery UI 1.13.3 or newer, so check that before anything else if the site uses jQuery UI widgets.

A working order

  1. Upgrade jQuery UIjQuery 4.0.0 needs jQuery UI 1.13.3 or newer
  2. Load jQuery 4 and Migrate 4The uncompressed Migrate build, in development only
  3. Collect the JQMIGRATE linesClick through every page that loads a plugin
  4. Fix, patch, then shimYour own code first, then plugins; shim only what is left
  5. Remove Migrate from productionDelete each shim line once its plugin is gone

Test on a page with <!doctype html>. Without one, Migrate also warns that jQuery is not compatible with Quirks Mode.

Questions this raises

Why do I get "$.trim is not a function" after upgrading to jQuery 4?

jQuery 4.0 removed jQuery.trim. Call the native String method instead, s.trim(). To find every other removed call at once, load jQuery Migrate 4 in development: it restores the function and logs where each call came from.

What replaces $.isArray, $.isFunction and $.parseJSON in jQuery 4?

Array.isArray(v), typeof v === "function" and JSON.parse(s). The jQuery Core 4.0 upgrade guide lists a native equivalent for each removed utility.

Does jQuery 4 still support Internet Explorer?

IE 11 is still supported in 4.0. Internet Explorer 10 and older, and Edge Legacy, are no longer supported.

Should jQuery Migrate stay on in production?

No. The upgrade guide intends it for development: load it, fix the warnings, then remove it. If an abandoned plugin still needs a function or two, a small shim that restores only those is lighter than shipping Migrate.

Filed under