npm / @hocuspocus/provider
@hocuspocus/provider
What changed in @hocuspocus/provider 3 to 4, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-18.
6 breaking1 security10 new APIs and options1 performance4 behavior and defaults20 fixes and other
See which of these apply to your code, ranked, in your agent:
npx @unstale/cli init@hocuspocus/provider 430 changes
Breaking changes 4
When beforeHandleMessage throws, other messages that were already queued are no longer processed.
The CloseEvent passed to onClose callbacks now contains only code and reason; target and type are no longer available.
attach() now throws an error when attaching two authenticated providers with the same effective name instead of silently overwriting the existing provider.
The provider no longer imports or re-exports Event, MessageEvent, or CloseEvent from ws; TypeScript users relying on those types should import from @hocuspocus/common or use web-standard types.
Security 1
Enforces resource limits before authentication to safeguard server stability.
New APIs and options 8
Adds an option for batching updates to reduce websocket traffic during heavy editing.
Adds consistent state synchronization across Redis instances.
Adds a hook that runs after message handling completes.
Adds the unloadImmediately option to configure document persistence behavior when disconnect() is called.
Exposes sessionAwareness in provider-react HocuspocusRoom.
Adds the beforeHandleAwareness hook for handling awareness updates.
Adds application-level Ping (9) and Pong (10) message types; the provider responds to server Ping messages with Pong, replacing WebSocket-level ping/pong.
Adds an opt-in that embeds a unique sessionId in message document names, allowing multiple providers with the same document name on one WebSocket; it defaults to false for v3 compatibility.
Performance 1
extension-redis now delays forwarding messages to Redis with setImmediate, improving performance when many users are connected to the same document.
Behavior and default changes 3
Updates are batched before being sent to clients.
The provider sends its package version in the authentication message; v3 servers safely ignore the extra field.
Unknown message types now log console.error instead of throwing, allowing future protocol additions without crashing the provider.
Fixes and other changes 13
Batched changes are sent when the page is hidden.
A pending reconnect is canceled when disconnect() or destroy() is called.
The retry cancel handle is kept until the connection attempt resolves.
Emits maxAttemptsFailed instead of an unhandled rejection when attempts fail.
Redis sync replies are published only to the requester.
Messages are ignored in awarenessUpdateHandler when origin is this.
Allows binding the server to a specific address.
Ensures server.destroy() only runs once.
Deletes the debouncer timer entry before awaiting the in-flight execution.
Fixes client-initiated broadcastStateless.
Scratch Awareness objects in MessageReceiver are destroyed to fix a memory leak.
Wraps awareness origin as TransactionOrigin.
When the WebSocket is not yet open and messages are queued, duplicate awareness messages for the same document are deduplicated, keeping only the latest one.
@hocuspocus/provider 312 changes
Breaking changes 2
Tightens the types for authorizedScope.
beforeSync is no longer awaited, to avoid breaking message order.
New APIs and options 2
A document now exposes lastChangeTime, which can be used to identify when it last had changes.
Adds a hook for re-syncing auth tokens.
Behavior and default changes 1
Redis unloading logic was rewritten to utilize before/after-unload hooks.
Fixes and other changes 7
Fixes websocket URLs ending with / so they work.
Fixes a memory leak under high load.
Prevents a crash related to awareness in extension-redis.
Fixes a memory leak in onStoreDocument in extension-redis.
Debounce now prevents a storeDocumentHook from running concurrently, even when a new debounced function starts before the previous one finishes.
Fixes timing issues when multiple users leave the same document together.
The onUpdate listener is bound before afterLoadDocument is called, so document changes can trigger storeDocumentHooks.