Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/wppconnect-team/wa-js/llms.txt

Use this file to discover all available pages before exploring further.

The WPP.loader module sits at the heart of the WA-JS injection lifecycle. It detects which module system WhatsApp Web is using, captures a reference to it, and progressively unlocks the rest of the WPP API as WhatsApp’s own bundles finish loading. You interact with WPP.loader primarily to know when it is safe to call other WA-JS functions — and to register code that should run at a specific point in that sequence.

Readiness flags

Three boolean properties on WPP.loader reflect the current state of the injection sequence. They start as false and are set to true exactly once, in order. You can read them at any point, but for reacting to state transitions use the lifecycle hooks below.
All three flags are also re-exported on the top-level WPP object. WPP.isInjected, WPP.isReady, and WPP.isFullReady are identical to their WPP.loader counterparts.

WPP.loader.isInjected

Set to true the moment the loader has captured WhatsApp’s internal module system. At this point the module registry exists, but core modules may not yet be resolvable.
console.log(WPP.loader.isInjected); // true or false
isInjected
boolean
required
true once the loader has hooked into the WhatsApp module system.

WPP.loader.isReady

Set to true once the core WhatsApp modules are resolvable. This is the point at which most WPP.* API calls become safe to make. The onReady() callback fires at this stage.
console.log(WPP.loader.isReady); // true or false
isReady
boolean
required
true once core WhatsApp modules have loaded and the WPP API is usable.

WPP.loader.isFullReady

Set to true after all runtime chunks (including non-main bundles) have finished loading, and after conn.main_ready has fired. This indicates that every module WhatsApp ships is available.
console.log(WPP.loader.isFullReady); // true or false
isFullReady
boolean
required
true once all runtime modules have loaded and the main interface is ready.

Lifecycle hooks

Use these functions to register callbacks that fire at specific points in the readiness sequence. All three accept an optional delay parameter (in milliseconds) that defers the callback via setTimeout.

WPP.loader.onReady(callback, delay?)

The primary lifecycle hook. Registers a function to call once isReady becomes true — that is, once the core WhatsApp modules are resolvable and WPP.* calls are safe. This is the recommended hook for the vast majority of use cases.
WPP.loader.onReady(async () => {
  const isAuth = WPP.conn.isAuthenticated();
  console.log('Authenticated:', isAuth);

  if (isAuth) {
    await WPP.chat.sendTextMessage('5511999999999@c.us', 'Hello from WA-JS!');
  }
});
With a delay:
// Defer by 1 second after ready
WPP.loader.onReady(() => {
  console.log('Ready (delayed 1s)');
}, 1000);
body.callback
() => void
required
Function to invoke when the loader reaches isReady. May be synchronous or async.
body.delay
number
default:"0"
Milliseconds to wait after the ready event before invoking callback. Uses setTimeout internally.

WPP.loader.onInjected(callback, delay?)

Fires as soon as the loader has captured the module system (isInjected = true). At this stage the core modules are not yet loaded, so most WPP.* functions are not yet usable. Use this for very early setup that does not require module access.
WPP.loader.onInjected(() => {
  console.log('Loader injected — module system captured');
});
body.callback
() => void
required
Function to invoke at injection time.
body.delay
number
default:"0"
Milliseconds to delay after injection.

WPP.loader.onFullReady(callback, delay?)

Fires once all runtime chunks have loaded and the main WhatsApp interface is fully ready (isFullReady = true). Use this when you need access to modules that are only available in the non-main bundles.
WPP.loader.onFullReady(() => {
  console.log('All modules loaded — full ready');
});
body.callback
() => void
required
Function to invoke at full-ready time.
body.delay
number
default:"0"
Milliseconds to delay after full ready.

Injection lifecycle

The sequence below shows how the loader progresses from injection to full readiness.
1

Bundle injected

The dist/wppconnect-wa.js UMD bundle is injected into the WhatsApp Web page — via TamperMonkey, Playwright, or another mechanism. WPP becomes available on window.
2

Loader initialises

WPP.loader detects which module system WhatsApp is using:
  • Meta loader (WhatsApp >= 2.3000.0): Installs setter traps on global.__d and global.require, then calls global.importNamespace() wrapped with ErrorGuard.skipGuardGlobal().
  • Webpack loader (legacy): Pushes into webpackChunkwhatsapp_web_client to intercept __webpack_require__.
3

isInjected = true

The module system is captured. WPP.loader.isInjected becomes true and onInjected callbacks fire.
4

Core modules resolve

The loader waits until a well-known core module (e.g. WAWebUserPrefsMeUser) is resolvable — with exponential backoff up to 5 seconds — confirming that the module registry is populated.
5

isReady = true

WPP.loader.isReady becomes true and onReady callbacks fire. The WPP.* API is now fully usable.
6

Main interface ready

The loader waits for the conn.main_ready event, signalling that the WhatsApp Web main interface is authenticated, loaded, and ready to send messages.
7

isFullReady = true

All remaining runtime chunks finish loading. WPP.loader.isFullReady becomes true and onFullReady callbacks fire.

Loader type

The loaderType property indicates which module system was detected.
console.log(WPP.loader.loaderType);
// 'meta'    — WhatsApp >= 2.3000.0 (Meta loader)
// 'webpack' — Legacy webpack loader
// 'unknown' — Detection not yet complete
loaderType
string
required
One of 'meta', 'webpack', or 'unknown'. Settles to 'meta' or 'webpack' once injection is complete.

The module blacklist

The Meta loader filters WhatsApp’s internal module registry before exposing it to WA-JS. Module IDs are included only if they match /^(?:use)?WA/ and are not present in META_MODULE_ID_BLACKLIST. The blacklist excludes modules that are known to be unstable, React components, or otherwise unsuitable for inspection.
The blacklist is an internal implementation detail of the loader. You do not need to interact with it directly. If a module you expect to find is missing, it may be excluded by the blacklist or not yet loaded — check WPP.loader.isFullReady.

Choosing the right hook

Use WPP.loader.onReady(). This is the correct hook for nearly all application code. At this point, WPP.conn, WPP.chat, WPP.contact, and all other feature modules are available.
WPP.loader.onReady(async () => {
  // Safe to call any WPP.* function here
  const me = WPP.conn.getMyUserId();
  console.log('My ID:', me?.toString());
});
Read the WPP.loader.isReady flag directly. This is a plain boolean and is always current.
if (WPP.loader.isReady) {
  const me = WPP.conn.getMyUserId();
} else {
  console.log('Not ready yet');
}
Use WPP.loader.onFullReady(). This fires after isFullReady becomes true, which happens after both all runtime chunks have loaded and the main interface is ready. Prefer onReady() unless you specifically need full-bundle modules.
WPP.loader.onFullReady(() => {
  console.log('All WhatsApp modules are available');
});
Use WPP.loader.onInjected(). Only use this for very early setup — the WhatsApp module registry exists, but individual modules have not loaded yet.
WPP.loader.onInjected(() => {
  console.log('Module system captured');
});

Loader events

The loader emits three internal events through WPP.on():
EventWhen it fires
loader.injectedisInjected becomes true
loader.readyisReady becomes true
loader.full_readyisFullReady becomes true
These are low-level internal events. Prefer the onInjected(), onReady(), and onFullReady() helper functions over subscribing to these events directly — the helpers handle timing edge cases and the optional delay parameter for you.
WPP.on('loader.ready', () => {
  console.log('Loader ready event received');
});

Build docs developers (and LLMs) love