npm / socket.io
socket.io
What changed in socket.io 2 to 4, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-23.
18 breaking1 deprecations8 new APIs and options1 performance2 behavior and defaults9 fixes and other
See which of these apply to your code, ranked, in your agent:
npx @unstale/cli initsocket.io 414 changes
Breaking changes 2
Stateful regular expressions are rejected for dynamic namespaces.
Calling io.to(...) or another broadcast modifier now returns an immutable instance, preventing later broadcasts from being affected by earlier calls.
Deprecations 1
url.parse() is deprecated and has been replaced by new URL().
New APIs and options 4
io.to(...) now accepts an array.
Broadcasting can exclude specific rooms.
Support for typed events was added.
Some utility methods were added.
Fixes and other changes 7
The types allow emitWithAck() for events with void callbacks.
The http module is imported correctly in the types.
Pending acknowledgements are cleaned up on timeout to prevent a memory leak.
Prevents uWebSockets.js from serving missing client files.
Calling io.close() on a stopped server no longer throws.
adapter.init() is now called when creating each namespace.
The io.close() function was improved.
socket.io 317 changes
Breaking changes 14
Clients with no namespace are now closed.
The connected map was renamed to sockets.
Connecting to a different namespace no longer implicitly connects to the default namespace.
The Engine.IO id is no longer reused.
Middleware errors now emit an Error object.
Namespace#connected is now a Map instead of an object.
The origins option was removed; configure CORS with cors and use allowRequest for validation.
Using reserved event names now throws.
The backward-compatibility Server#set() method was removed.
Socket#binary() was removed; this use case is covered by providing a custom parser.
Socket#join() is synchronous and no longer accepts a callback; custom adapters can use await.
Socket#leave() is synchronous and no longer accepts a callback argument; custom adapters can use await.
Socket#rooms is now a Set instead of an object.
The Socket#use() method was removed.
New APIs and options 3
Catch-all listeners are now supported.
An ES6 module export is now available.
A msgpack bundle is now served.
socket.io 28 changes
Breaking changes 2
null is no longer accepted as an argument.
A breaking change to utf-8 encoding in engine.io-parser makes this release not backward-compatible.
New APIs and options 1
Applications can provide a custom parser to meet their needs.
Performance 1
Engine.IO and Socket.IO handshake packets were merged, reducing the roundtrips needed to establish a connection.
Behavior and default changes 2
The join method now allows joining several rooms at once.
path.resolve is used by default, with require.resolve as a fallback.
Fixes and other changes 2
Connections are now properly closed on error.
The socket id on the client now matches the id on the server-side.