A jQuery upgrade appears successful until a customer opens a rarely used form. Its validation plugin depends on behaviour that the new release changed, and the form stops responding. The homepage looked fine because it never exercised that code path.
jQuery Migrate helps make this kind of dependency visible during an upgrade. It can restore some removed behaviour and report relevant API usage through its development diagnostics. It does not inspect every possible interaction in advance, repair arbitrary plugin code, or certify that a quiet page is compatible.
The useful outcome is a tested application running on the intended jQuery version with its dependencies understood. Migrate can support that transition, but finding and resolving the underlying dependencies remains application work.
Establish What the Page Actually Loads
Begin by recording the jQuery version, Migrate version if present, relevant plugins, and script-loading order on each affected page. A content-management system, theme, tag manager, and application bundle can each introduce scripts. Updating one dependency declaration may leave another copy running in a different part of the site.
Use the browser’s network and debugging tools to establish what executes, rather than relying only on a package manifest. If a second jQuery copy replaces the global reference after a plugin registers, the resulting failure can resemble an API incompatibility even though the immediate problem is loading order or duplicate instances.
Create a repeatable baseline before changing versions. Check form submission, asynchronous content, modal controls, validation failures, keyboard interaction, and any important plugin lifecycle. Record existing defects separately so the upgrade can be evaluated against known behaviour.
This is a practical form of modernising without rewriting business logic. The runtime dependency changes while the team explicitly checks which user-visible behaviour should remain. A browser-support requirement may also constrain the target version and needs resolving before the migration begins.
Match Migrate to the Upgrade Stage
The jQuery Migrate repository publishes the compatibility mapping between jQuery and Migrate generations. The documented branches are:
| jQuery generation being run | Matching Migrate generation |
|---|---|
| jQuery 1.x | Migrate 1.x |
| jQuery 2.x | Migrate 1.x |
| jQuery 3.x | Migrate 3.x |
| jQuery 4.x | Migrate 4.x |
This is a branch mapping, not a guarantee that every historical combination or plugin works. Select released versions appropriate to the supported upgrade path and record them in the deployment configuration. A work-in-progress build is a different proposition from a pinned release.
The jQuery 4.0 upgrade guide describes staged upgrades for older applications. In particular, Migrate 4 does not restore all behaviours removed during earlier major transitions. Code coming from a much older version needs those earlier compatibility issues resolved before the jQuery 4 stage.
Follow the documented stage for the application’s starting point, fix the issues discovered there, and verify that stage without its Migrate dependency before moving on. Loading several Migrate generations simultaneously is not a supported shortcut. It makes the source of restored behaviour harder to understand while bypassing the intended migration process.
Use Diagnostics to Locate Dependencies
Load the development build after jQuery and before application or plugin code that needs its patches. Exercise the relevant workflows with the browser console available. The development build emits messages prefixed with JQMIGRATE; the production build suppresses normal migration warnings, so silence there is not evidence that the dependencies disappeared.
Inspect the stack trace and identify the application call site or plugin responsible. A warning produced inside a minified bundle may require source maps or a development asset to investigate. Associate each finding with the affected user journey and an owner rather than treating the console as an unstructured list of chores.
The plugin also exposes diagnostics such as jQuery.migrateMessages. Those messages describe observed execution, not a complete inventory of dormant code. A warning may be reported only once even when the underlying pattern executes repeatedly. Do not interpret the number of console lines as the number of affected uses or users.
Use the warning documentation for the Migrate branch actually running. A message’s wording and compatibility patch relate to that stage. Advice intended for Migrate 4 can be misleading when applied to an older migration without checking the relevant versioned documentation.
The diagnostic record should include which page and action produced the warning. If the last incompatible path only runs after a failed network request or a repeated modal opening, ordinary happy-path testing will not find it. Reproduction steps make the eventual fix testable.
Repeat checks under the roles that expose different scripts. An administrator may load a reporting plugin that ordinary customers never receive, while an authenticated customer may reach checkout code absent from anonymous pages. Record that coverage explicitly instead of allowing one successful browser session to stand for the whole application.
Distinguish Removed APIs From Deprecated Ones
A warning is a reason to investigate, but it does not always mean that the target jQuery version removed the API. The Migrate 4 warning catalogue distinguishes compatibility patches from deprecated behaviour that can still work. For example, it describes .bind() as deprecated while still present in jQuery 4.x.
For a straightforward direct event subscription, a migration can replace an older binding form with .on():
// Before: direct binding through a deprecated API.
$(".save-button").bind("click", saveRecord);
// After: the same direct subscription through .on().
$(".save-button").on("click", saveRecord);
This example assumes saveRecord already exists and that the selected buttons are present when binding runs. Execute one form, not both, or the handler will be registered twice. The change does not automatically add support for buttons inserted later.
If the intended behaviour is delegation from a stable container, that is a separate decision:
$("#editor").on("click", ".save-button", saveRecord);
Now the handler is attached to the editor and receives matching descendant events. Verify propagation, handler context, and the lifetime of the container. Moving from direct binding to delegation can be useful, but it changes the subscription model and should not be presented as a mechanical rename.
Other replacements need input semantics rather than a new function name. Replacing a numeric-checking utility requires deciding whether the application accepts decimal strings, exponents, whitespace, or values outside an exact integer range. A permissive conversion can silently change validation. Test representative accepted and rejected inputs instead of copying a generic replacement.
Resolve Plugin Ownership and Test the Behaviour
A third-party plugin can be the final dependency keeping Migrate in place. Check whether a maintained release supports the target jQuery generation and whether upgrading it changes its own public API. Updating jQuery and a plugin together may be necessary, but their effects still need to be distinguishable during testing.
If the plugin is abandoned, the choices include a reviewed local patch, replacement, or removal of the feature. Document the resulting maintenance responsibility. Editing a minified vendor file without retaining the source and patch process creates a dependency that will be difficult to reproduce later.
Test more than whether a click handler runs. A form may submit twice, validation may reject a value it previously accepted, or an asynchronous error may leave a control disabled. Keyboard use and focus handling deserve attention when a UI plugin changes because mouse-only testing can miss a substantial regression.
Include repeated setup and teardown. Code that opens a component several times can accidentally accumulate handlers or retain removed elements. A migration that replaces one event API can still preserve, or introduce, that lifecycle problem. The relevant check is the observable operation, such as one save request per user action.
Keep security fixes separate from assumptions about compatibility. Migrate is not a general security patch for unsupported plugins or unsafe application code. A successful compatibility test does not establish that dependency versions and HTML handling are suitable for the site’s security requirements.
Remove the Layer Under the Same Verification Scope
Once the known findings are resolved, remove Migrate in the test environment and repeat the important workflows. Clearing the console with Migrate still active is a useful milestone, but testing without its patches is the stronger check that those exercised paths no longer depend on it.
Inspect the final network requests and generated bundles to ensure a theme or plugin has not reintroduced the script. Verify the deployment’s asset versions and cache behaviour so users receive the tested combination. Keeping an old bundled copy while updating a separate script can leave different users on different effective configurations.
A staged production release can help identify paths that were not represented in testing. Monitor actual errors and failed business operations, and retain a rollback route for the affected deployment. Avoid declaring the whole application compatible from a finite set of successful checks; state which journeys and environments were verified.
The migration is complete when the supported target version and its plugins satisfy the application’s behaviour requirements without the compatibility layer. The lasting value is the dependency inventory, repeatable checks, and clearer ownership that make the next upgrade easier to assess.





