Release Notes
Compatibility: Works best with RealtimeKit Web UI Kit 2.0.0 or later.
This is a major breaking release. Several deprecated APIs have been removed and the plugin APIs have been completely redesigned. Review the migration guide below carefully before upgrading.
Plugin APIs — complete redesign
Plugins are no longer fetched from the server automatically. You now provide plugin configurations at SDK init time via defaults.plugins.
Before (v1.x):
// plugins were loaded via API in SDK internally
const meeting = await RealtimeKitClient.init({
authToken,
});
// Server-hosted plugins were auto-populated
const plugin = meeting.plugins.all.get(pluginId);
// Plugin rendered in an iframe managed by the SDK
plugin.addPluginView(iframeElement, 'plugin-main');
// Permissions checked via meeting.self.permissions.plugins.canStart / canClose
After (v2.0):
A plugin component is any HTMLElement. You can use a custom element, a framework component mounted to a container, or an iframe. The following example embeds a collaborative text editor as a plugin:
const editor = document.createElement('iframe');
editor.src = 'https://rustpad.io/#WKLJaD';
editor.style.width = '100%';
editor.style.height = '100%';
editor.style.border = 'none';
const meeting = await RealtimeKitClient.init({
authToken,
defaults: {
plugins: [
{
id: 'collaborative-editor', // SDK prefixes this with {meetingId}: to create the namespaced plugin.id
name: 'Collaborative Editor',
icon: 'https://example.com/editor.png',
permissions: {
canActivate: true,
canDeactivate: true,
},
component: editor,
},
],
},
});
// Plugin is registered and available
const plugin = meeting.plugins.all.get(pluginId);
// Activate — state is synced across all participants
await plugin.activate();
For a complete guide on building custom plugins, refer to Build your own plugins. If you need to record plugin content, you must build a custom recording app.
Key changes:
- New type exports:
ClientPluginConfig,ClientPluginPermissions. - Plugin
idis now namespaced: the SDK prefixes your providedidwith{meetingId}:to create the internalpluginId. - Plugin activation and deactivation state is now synced via a collaborative store (
__rtk_plugins__) instead of dedicated socket messages. - Plugins now have a
componentproperty (anyHTMLElement) instead of iframe-based rendering viaaddPluginView. - Per-plugin permissions (
plugin.permissions.canActivate/plugin.permissions.canDeactivate) replace the old globalmeeting.self.permissions.plugins.canStart/meeting.self.permissions.plugins.canClose.
Removed plugin APIs:
plugin.addPluginView(iframe, viewId)— pass anHTMLElementascomponentinClientPluginConfiginstead.plugin.removePluginView(viewId)— handled automatically by the UI Kit.plugin.enable()— useplugin.activate().plugin.disable()— useplugin.deactivate().plugin.sendIframeEvent()— removed. Communicate directly with your component.plugin.baseURL— removed. Plugins are no longer server-hosted.plugin.picture— useplugin.icon.plugin.description,plugin.organizationId,plugin.tags,plugin.type,plugin.staggered,plugin.private,plugin.published,plugin.createdAt,plugin.updatedAt— removed. No longer applicable.plugin.config(PluginConfig) — removed. No plugin manifest concept.meeting.self.permissions.plugins.canStart— useplugin.permissions.canActivate.meeting.self.permissions.plugins.canClose— useplugin.permissions.canDeactivate.modules.devTools.plugins(local dev plugin config) — usedefaults.pluginswith acomponentpointing to your local element.
Removed deprecated APIs
Client:
meeting.joinRoom()— usemeeting.join().meeting.leaveRoom()— usemeeting.leave().
Chat:
meeting.chat.getMessagesByUser(userId)— usemeeting.chat.fetchPublicMessages()with appropriate filters.meeting.chat.getMessagesByType(type)— usemeeting.chat.fetchPublicMessages()with appropriate filters.meeting.chat.getMessages(timestamp, size, reversed)— usemeeting.chat.fetchPublicMessages()ormeeting.chat.fetchPrivateMessages().meeting.chat.searchMessages(query, filters)— usemeeting.chat.fetchPublicMessages()ormeeting.chat.fetchPrivateMessages().meeting.chat.pinned(getter) — usemeeting.chat.fetchPinnedMessages().
Permissions (meeting.self.permissions):
permissions.produceVideo— usepermissions.canProduceVideo.permissions.produceAudio— usepermissions.canProduceAudio.permissions.produceScreenshare— usepermissions.canProduceScreenshare.permissions.waitingRoomType— usepermissions.waitingRoomBehaviour.permissions.canChangeParticipantRole— usepermissions.canChangeParticipantPermissions.permissions.canChangeTheme— removed (always returnedfalse).permissions.canPresent— check individualcanProduceAudio,canProduceVideo,canProduceScreenshare.permissions.requestProduce— check individual media permissions forCAN_REQUESTvalues.permissions.acceptPresentRequests— usepermissions.acceptStageRequests.permissions.maxScreenShareCount— usemeeting.self.config.maxScreenShareCount.PermissionPreset.fromResponse()— usePermissionPreset.init().PermissionPreset.default()— usePermissionPreset.init().
Participants:
meeting.participants.disableAudio(participantId)— usemeeting.participants.joined.get(participantId).disableAudio().meeting.participants.disableVideo(participantId)— usemeeting.participants.joined.get(participantId).disableVideo().meeting.participants.kick(participantId)— call kick on the participant directly.participant.clientSpecificId— useparticipant.customParticipantId.
Connected Meetings:
meeting.connectedMeetings.supportsConnectedMeetings— removed. Permission checks are now granular viameeting.self.permissions.connectedMeetings.
Enhancements
- Faster reconnection: Socket-only disconnects (where WebRTC transports remain healthy) now skip full transport re-setup. Producers are re-registered and existing consumers are remapped, significantly reducing reconnection time.
- Participants stay visible during reconnection: Participant tiles remain in the grid during a socket blip instead of disappearing and reappearing, providing a seamless experience.
- Double audio fix: Fixed an issue where other participants could hear double audio from a reconnected participant, caused by stale producers not being cleaned up.
- Socket reconnection resilience: Socket now supports up to 50 reconnection attempts with exponential backoff and jitter (up from 10), providing up to approximately four minutes of retry coverage when the internet is down.
- Store improvements:
StoreManagernow supportsrefresh(name)to re-fetch store data from the server, and reserved store names (__rtk_plugins__) are protected from user creation.
Fixes
- Fixed socket failing to reconnect if left disconnected for 30 seconds.
Compatibility: Works best with RealtimeKit Web UI Kit 1.2.0 or later.
Features
- Added a dedicated error code
0014for media (WebRTC) connection failures during room join, making it easier to distinguish media failures from socket and signaling failures.
Enhancements
- Init and join failures from
Client.init()andmeeting.join()now surface specific error codes and descriptive messages instead of generic or stacked errors. - Telemetry logs are now compressed using gzip when the browser supports the
CompressionStreamAPI, achieving approximately a 10:1 compression ratio. Older browsers and React Native fall back to uncompressed JSON with smaller batch sizes.
Fixes
- Fixed a regex-based issue where the Safari video middleware flag was incorrectly removed, potentially breaking video processing on Safari.
- Fixed an issue where
ClientErrorobjects were wrapped inside each other when the SDK retried failed API requests. This caused nested error messages, duplicateonErrorcallbacks, and redundantwindowerror events.
Removed APIs
- Removed the third-party flag service.
meeting.__internals__.featuresis now deprecated and will be removed in a future release.
Compatibility: Works best with RealtimeKit Android Core 2.0.0+ and RealtimeKit iOS Core 2.0.0+.
Features
- Added
meeting.__internals__.authTokento expose authentication token, enabling better integration between Web Core and UI Kit for future features and enhancements.
Fixes
- Proactively fixed an issue where participants with simulcast turned on would not be able to turn on their camera or microphone due to SDP failures in Chrome version 148+.
Enhancements
- SDK now uses
*.realtime.cloudflare.combase URI internally instead of the legacydyte.iobase URI. - Refactored error handling to properly catch and display error codes for SDK initialization failures, room join failures, and other errors.
Features
- Simulcast support is now available to all RealtimeKit clients. Configure it per participant in Preset via the RealtimeKit dashboard, Preset API using the
config.media.video.simulcastfield, or while initializing the SDK. - Added 4K UHD video support in media production (configurable in Preset and API). Falls back to the maximum supported resolution if the camera does not support 4K.
Compatibility: Works best with RealtimeKit Web UI Kit 1.1.1 or later.
Enhancements
- Implemented retry limits for ICE connection failures to prevent indefinite connection attempts and improve reliability.
- Improved error handling for room join operations to provide more descriptive and actionable error messages.
- Room join errors are now thrown consistently when network connectivity is blocked by firewalls or when TURN servers are unreachable.
Fixes
- Fixed an issue in Connected Meetings where peer IDs were not regenerated when switching between rooms. Peer IDs are now correctly assigned per room session.
Compatibility: Works best with RealtimeKit Web UI Kit 1.1.0 or later.
New APIs
Added chat pagination support with the following methods:
meeting.chat.fetchPinnedMessages- Fetch pinned messages from server.meeting.chat.fetchPublicMessages- Fetch public messages from server.meeting.chat.fetchPrivateMessages- Fetch private messages from server.
Enhancements
- Added JSDoc comments to all public-facing methods and classes for improved developer suggestions.
- Chat message operations (edit, delete, pin) are now available to all RealtimeKit clients without additional configuration.
pinMessageandunpinMessageevents onmeeting.chatnow emit reliably.- Message pinning (
meeting.chat.pinandmeeting.chat.unpin) is now available to all participants.
Removed APIs
Removed non-operational chat channel APIs to streamline the RealtimeKit SDK. Meeting chat (meeting.chat) remains fully operational.
- Removed
meeting.self.permissions.chatChannel. - Removed
meeting.self.permissions.chatMessage. Usemeeting.self.permissions.chatPublicandmeeting.self.permissions.chatPrivateinstead. - Removed
meeting.chat.channels. - Removed
meeting.chat.sendMessageToChannel. - Removed
meeting.chat.markLastReadMessage. - Removed events:
channelMessageUpdate,channelCreate, andchannelUpdatefrommeeting.chat.
API changes
- The following methods no longer accept a third optional
channelIdparameter:meeting.chat.editTextMessage(messageId, message)meeting.chat.editImageMessage(messageId, imageFile)meeting.chat.editFileMessage(messageId, file)meeting.chat.editMessage(messageId, messagePayload)meeting.chat.deleteMessage(messageId)
Deprecations
The following methods are deprecated due to scalability limitations (limited to 1,000 recent messages):
meeting.chat.messages- Only fetches recent messages and new messages after joining.meeting.chat.getMessagesByUser- Use new fetch methods for scalable message retrieval.meeting.chat.getMessagesByType- Use new fetch methods for scalable message retrieval.meeting.chat.getMessages- Usemeeting.chat.fetchPublicMessagesormeeting.chat.fetchPrivateMessagesinstead.meeting.chat.pinned- Usemeeting.chat.fetchPinnedMessagesinstead.meeting.chat.searchMessages- Usemeeting.chat.fetchPublicMessagesormeeting.chat.fetchPrivateMessagesinstead.
Known limitations
- Pinned messages are not supported for private chats.
Fixes
Fixed an issue where users who joined a meeting with audio and video disabled and then initiated tab screen sharing would experience SDP corruption upon stopping the screen share, preventing subsequent actions such as enabling audio or video.
Error thrown:
InvalidAccessError: Failed to execute 'setRemoteDescription' on 'RTCPeerConnection': Failed to set remote answer sdp: Failed to set remote audio description send parameters for m-section with mid='<N>'Fixed an issue where awaiting
RealtimeKitClient.initMediadid not return media tracksExample usage:
const media = await RealtimeKitClient.initMedia({ video : true, audio: true, }); const { videoTrack, audioTrack } = media;Fixed an issue where an undefined variable caused
TypeError: Cannot read properties of undefined (reading 'getValue')in media retrieval due to a race condition.
Fixes
- Fixed an issue where camera switching between front and rear cameras was not working on Android devices
- Fixed device selection logic to prioritize media devices more effectively
- Added PIP support for Reactions
Fixes
- Resolved an issue preventing default media device selection.
- Fixed SDK bundle to include
browser.jsinstead of incorrectly shippingindex.iife.jsin 1.2.0.
Enhancements
- External media devices are now prioritized over internal devices when no preferred device is set.
Features
Added support for configuring simulcast via
initMeeting:initMeeting({ overrides: { simulcastConfig: { disable: false, encodings: [{ scaleResolutionDownBy: 2 }], }, }, });
Fixes
- Resolved an issue where remote participants' video feeds were not visible during grid pagination in certain edge cases.
- Fixed a bug preventing participants from switching microphones if the first listed microphone was non-functional.
Breaking changes
- Legacy media engine support has been removed. If your organization was created before March 1, 2025 and you are upgrading to this SDK version or later, you may experience recording issues. Contact support to migrate to the new Cloudflare SFU media engine to ensure continued recording functionality.
Fixes
- Prevented speaker change events from being emitted when the active speaker does not change.
- Addressed a behavioral change in microphone switching on recent versions of Google Chrome.
- Added
deviceInfologs to improve debugging capabilities for React Native. - Fixed an issue that queued multiple media consumers for the same peer, optimizing resource usage.
Enhancements
- Internal changes to make debugging of media consumption issues easier and faster.
Fixes
- Improved React Native support for
AudioActivityReporterwith proper audio sampling. - Resolved issue preventing users from creating polls.
- Fixed issue where leaving a meeting took more than 20 seconds.
Fixes
- Livestream feature is now available to all beta users.
- Fixed Livestream stage functionality where hosts were not consuming peer videos upon participants' stage join.
- Resolved issues with viewer joins and leaves in Livestream stage.
Fixes
- Fixed issue where users could not enable video mid-meeting if they joined without video initially.
Fixes
- Fixed edge case in large meetings where existing participants could not hear or see newly joined users.
Features
- Added methods to toggle self tile visibility.
- Introduced broadcast functionality across connected meetings (breakout rooms).
New API
Broadcast messages across meetings:
meeting.participants.broadcastMessage("<message_type>", { message: "Hi" }, { meetingIds: ["<connected_meeting_id>"], });
Enhancements
- Reduced time to display videos of newly joined participants when joining in bulk.
- Added support for multiple meetings on the same page in RealtimeKit Core SDK.
Fixes
- Enhanced error handling for media operations.
- Fixed issue where active participants with audio or video were not appearing in the active participant list.
Fixes
- Resolved initial setup issues with Cloudflare RealtimeKit integration.
- Fixed meeting join and media connectivity issues.
- Enhanced media track handling.
Features
- Initial release of Cloudflare RealtimeKit with support for group calls, webinars, livestreaming, polls, and chat.