The jQuery.holdReady() method pauses or releases jQuery’s document ready event — letting dynamic script loaders finish before $(function(){}) handlers run. This tutorial covers the official $.getScript pattern, multiple hold counters, deprecation in 3.2, and the modern $.when($.ready, promise) replacement.
01
hold
Boolean arg
02
true
Pause ready
03
false
Release
04
Since 1.6
Added
05
Deprecated
Since 3.2
06
$.when
Modern fix
Fundamentals
Introduction
Most jQuery pages wait for the DOM with $(function(){ ... }). That works when all scripts are loaded synchronously in order. But what if a bootstrap script must fetch a plugin with $.getScript() before the rest of your app initializes?
jQuery 1.6 added jQuery.holdReady(hold) as a global pause switch. Call $.holdReady(true) early to block the ready event, load extra JavaScript, then call $.holdReady(false) when plugins are available. Only then do queued ready handlers run.
This is an advanced API. jQuery deprecated it in 3.2 because explicit promise composition is clearer. You should understand holdReady when maintaining legacy loaders — and use $.when($.ready, customPromise) in new projects.
Concept
Understanding the jQuery.holdReady() Method
jQuery.holdReady(hold) accepts a Boolean. Passing true requests a hold — jQuery will not fire the ready event even if the DOM is parsed. Passing false releases one hold. Ready fires only when the hold counter returns to zero and the document satisfies normal ready conditions.
The method returns undefined. It does not chain. It must be invoked from an inline script in the <head> (or very early in the body) before ready would otherwise occur — calling it after ready already fired has no effect.
⚠️
Deprecation notice
Since jQuery 3.2, prefer $.when($.ready, customPromise).then(fn) over global ready holds. See the official migration guidance on the jQuery API page.
Foundation
📝 Syntax
Pause or release the ready event with a Boolean flag:
jQuery
jQuery.holdReady( hold )
// or
$.holdReady( hold )
Parameters
hold (Boolean) — true adds a hold; false releases one hold.
Releasing hold at ... (+800ms)
Ready handler at ... (same moment as release)
How It Works
Ready handlers queue normally but jQuery withholds execution until all holds clear. The handler timestamp matches the release, not DOM parse time.
Example 3 — Multiple Holds Need Matching Releases
Two true calls require two false calls before ready fires.
jQuery
$.holdReady( true );
$.holdReady( true );
$(function () {
console.log("Ready finally runs");
});
$.holdReady( false ); // still held — one hold remains
console.log("After first release — ready not yet");
setTimeout(function () {
$.holdReady( false ); // second release — ready can fire
}, 200);
After first release — ready not yet
Ready finally runs (after second false)
How It Works
jQuery tracks a hold counter internally. Forgetting a matching false leaves ready blocked forever — a common bug when multiple loaders each call holdReady(true).
Example 4 — Modern $.when Replacement (Recommended)
Official migration pattern — wait for DOM ready and a custom promise without global holds.
No global side effects — other code can still use $(fn) independently. Your init block explicitly waits for both conditions, with .catch for load failures.
Example 5 — Calling holdReady After Ready Has No Effect
Attempting to hold after the ready event already fired does nothing.
jQuery
$(function () {
console.log("Ready already ran");
// Too late — ready event passed
$.holdReady( true );
console.log("holdReady(true) after ready — no effect");
$(function () {
console.log("This inner handler still runs immediately");
});
});
Modern apps: ES modules and type="module" defer naturally — rarely need holdReady.
Prefer $.when($.ready, promise) for new code — clearer error handling with .catch.
Compatibility
Browser Support
jQuery.holdReady() works wherever jQuery runs. Added in jQuery 1.6, deprecated in jQuery 3.2. Behavior is identical across browsers because it is jQuery-internal ready scheduling.
✓ Deprecated 3.2
jQuery jQuery.holdReady()
Supported in jQuery 1.x, 2.x, and 3.x. Use $.when($.ready, promise) in new projects instead of global holds.
100%With jQuery loaded
Google ChromeAll versions · Desktop & Mobile
Full support
Mozilla FirefoxAll versions · Desktop & Mobile
Full support
Apple SafariAll versions · macOS & iOS
Full support
Microsoft EdgeAll versions · Chromium & Legacy
Full support
Internet ExplorerIE 6+ · Legacy environments
Full support
OperaAll modern versions
Full support
jQuery.holdReady()Legacy API
Bottom line: Understand holdReady for maintaining legacy loaders. Default to explicit promise composition for new initialization code.
Wrap Up
Conclusion
jQuery.holdReady(hold) is a global pause switch for jQuery’s ready event — born for dynamic script loaders that had to fetch plugins before page initialization. Call true early, release with false, and match every hold with a release.
jQuery deprecated the API in 3.2 because $.when($.ready, customPromise) is clearer and safer. Learn holdReady to read legacy code; write new bootstraps with explicit promises instead.
Use $.when($.ready, promise) in new jQuery 3.2+ code
Call holdReady(true) immediately after jQuery in head (legacy only)
Release with holdReady(false) in getScript callbacks
Match every true with a false
Add .catch when plugin load can fail
❌ Don’t
Use holdReady in greenfield apps without a legacy reason
Call holdReady(true) after ready already fired
Forget a release — ready handlers never run
Block all page init globally when one module needs a delay
Assume holdReady works with native ES module graphs
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about jQuery.holdReady()
Pause and release the global ready event.
5
Core concepts
⏸01
true/false
Hold/release
API
📄02
Early
In head
Timing
2×03
Counter
Match pairs
Pitfall
3.204
Deprecated
Since 3.2
Migrate
🔄05
$.when
Replace
Modern
❓ Frequently Asked Questions
jQuery.holdReady(hold) pauses or releases jQuery's document ready event. Pass true to delay ready handlers from running; pass false to release one hold. Added in jQuery 1.6 for dynamic script loaders that need plugins loaded before page init.
Yes. jQuery.holdReady() was deprecated in jQuery 3.2. The official docs recommend explicit waiting with $.when($.ready, customPromise).then(...) instead of a global ready switch. It still works in jQuery 3.7.x but should not appear in new code.
Early in the document — typically in the head immediately after the jQuery script tag, before DOM ready fires. If you call holdReady(true) after the ready event already ran, it has no effect.
Yes. Each holdReady(true) increments an internal counter. Ready does not fire until every hold is released with a matching holdReady(false) and normal DOM ready conditions are met.
Use $.when($.ready, yourPromise).then(function(){ /* main code */ }).catch(function(err){ /* errors */ }). Build a Deferred or Promise for your custom async work — getScript, dynamic imports, or module loading — and compose it with $.ready.
jQuery.ready is the thenable that resolves when ready fires. holdReady blocks that resolution until holds are released. While held, $(function(){}) callbacks and $.when($.ready) handlers wait even if the HTML DOM is already parsed.
Did you know?
Before holdReady, developers sometimes placed jQuery plugins synchronously in the head to guarantee they existed before body scripts ran. holdReady let loaders switch to async $.getScript without race conditions against $(fn). jQuery 3.2’s deprecation pushed the ecosystem toward composing $.ready with local Deferreds — the same promise mindset jQuery uses elsewhere for Ajax — instead of one global flag that could accidentally freeze every ready handler on the page.