npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rqmeet/web-sdk

v1.2.3

Published

RQMeet Web SDK for video meetings integration

Downloads

155

Readme

RQMeet Web SDK

A TypeScript SDK for integrating RQMeet video meetings into web applications. Build powerful video conferencing features with a simple, intuitive API.

npm version License: MIT

🚀 Live Demo – Try the SDK in action!

Features

  • 🎥 Video Meetings - Full video conferencing with audio, video, and screen sharing
  • 🎨 Drop-in Components - Pre-built React components for rapid integration
  • 👥 Participant Management - Role-based permissions (Host, Co-Host, Participant)
  • 🚪 Waiting Room - Secure waiting room with host approval workflow
  • 💬 Chat - Real-time messaging during meetings
  • 🔴 Recording - Start and stop meeting recordings
  • 🖼️ Virtual Backgrounds - Blur or custom image backgrounds
  • 📱 Responsive - Optimized mobile controls and layouts
  • 🌍 Localization - Built-in support for English (LTR) and Arabic (RTL)
  • 🔒 Secure - Token-based authentication with invite links

What's New in v1.2.2

  • 📱 Mobile Optimized Controls: Better layout for mobile devices with a bottom sheet menu for secondary actions.
  • 🌍 Localization Support: Added built-in support for Arabic (RTL) including UI mirroring.
  • 👤 Default Name: New defaultName prop to pre-fill participant name in PreJoin screen.
  • 🧪 Improved Responsiveness: Better adaptation to small screens and window resizing.
  • 🛠️ Bug Fixes: improved stability and error handling.

Getting Started

  1. Register at developer.rqmeet.com to create your account
  2. Get your API key from the dashboard
  3. Install the SDK and start building!

Installation

npm install @rqmeet/web-sdk

Quick Start

Option 1: Drop-in Component (Recommended)

The easiest way to add video meetings to your React app:

import { RQMeetClient, MeetingView } from '@rqmeet/web-sdk';

// The SDK automatically detects the environment:
// - http://localhost:3000 for local development
// - https://developer.rqmeet.com for production
const client = new RQMeetClient({
  apiKey: 'your_api_key'
});

function App() {
  return (
    <MeetingView
      client={client}
      meetingId="meeting_abc123"
      inviteToken="invite_token_from_api"
      branding={{
        logo: '/your-logo.png',
        primaryColor: '#6366f1',
        title: 'My Meeting'
      }}
      defaultName="User Name"            // Optional: Pre-fill display name
      language="en"                      // Optional: 'en' or 'ar'
      direction="ltr"                    // Optional: 'ltr' or 'rtl'
      onLeave={() => console.log('Left meeting')}
      onMeetingEnded={() => console.log('Meeting ended')}
      onError={(error) => console.error(error)}
    />
  );
}

Option 2: Individual Components

For more control, use the PreJoin and MeetingRoom components separately:

import { 
  RQMeetClient, 
  PreJoin, 
  MeetingRoom, 
  RQMeetRoom,
  ParticipantRole,
  SocketPermissions 
} from '@rqmeet/web-sdk';

function CustomMeeting() {
  const [room, setRoom] = useState<RQMeetRoom | null>(null);
  const [joinData, setJoinData] = useState<{
    role: ParticipantRole;
    permissions: SocketPermissions;
  } | null>(null);

  const handleJoin = async (data) => {
    const newRoom = new RQMeetRoom(
      meetingId,
      data.serverUrl,
      data.token,
      {
        audioEnabled: data.audioEnabled,
        videoEnabled: data.videoEnabled,
        virtualBackground: data.virtualBackground
      }
    );
    await newRoom.connect();
    setRoom(newRoom);
    setJoinData({ role: data.role, permissions: data.permissions });
  };

  if (!room) {
    return (
      <PreJoin
        client={client}
        meetingId="meeting_abc123"
        inviteToken="invite_token"
        onJoin={handleJoin}
      />
    );
  }

  return (
    <MeetingRoom
      room={room}
      client={client}
      meetingId="meeting_abc123"
      role={joinData.role}
      permissions={joinData.permissions}
      onLeave={() => setRoom(null)}
    />
  );
}

Option 3: Programmatic Control

For full control without React components:

import { RQMeetClient, RQMeetRoom, RoomEvent } from '@rqmeet/web-sdk';

const client = new RQMeetClient({
  apiKey: 'your_api_key'
});

// Create a meeting
const meeting = await client.createMeeting({
  name: 'Team Standup',
  maxParticipants: 10,
  enableRecording: true,
  enableChat: true
});

// Join the meeting
const room = await client.joinMeeting({
  meetingId: meeting.id,
  participantName: 'John Doe',
  participantId: 'user_123',
  audioEnabled: true,
  videoEnabled: true
});

// Listen to events
room.on(RoomEvent.ParticipantJoined, (participant) => {
  console.log(`${participant.name} joined`);
});

room.on(RoomEvent.MessageReceived, (message) => {
  console.log(`${message.senderName}: ${message.content}`);
});

// Media controls
await room.enableVideo();
await room.enableAudio();
await room.shareScreen();

// Send chat message
await room.sendMessage('Hello everyone!');

// Leave meeting
await room.leave();

Components

MeetingView

A complete meeting experience handling the entire flow from pre-join to meeting room.

<MeetingView
  client={client}                    // Required: RQMeetClient instance
  meetingId="meeting_id"             // Required: Meeting ID
  inviteToken="token"                // Recommended: Secure invite token
  initialIdentity="user_123"         // Optional: User identity (legacy)
  isHost={false}                     // Optional: Host flag (legacy, use inviteToken)
  branding={{                        // Optional: Custom branding
    logo: '/logo.png',
    primaryColor: '#6366f1',
    title: 'My Meeting'
  }}
  defaultName="John Doe"             // Optional: Pre-fill display name
  language="en"                      // Optional: 'en' or 'ar'
  direction="ltr"                    // Optional: 'ltr' or 'rtl'
  onLeave={() => {}}                 // Optional: Leave callback
  onMeetingEnded={() => {}}          // Optional: Meeting ended callback
  onDismissed={(reason) => {}}       // Optional: Dismissed from waiting room
  onError={(error) => {}}            // Optional: Error callback
/>

PreJoin

Pre-join screen with device selection, video preview, and waiting room support.

<PreJoin
  client={client}                    // Required: RQMeetClient instance
  meetingId="meeting_id"             // Required: Meeting ID
  inviteToken="token"                // Recommended: Secure invite token
  identity="user_123"                // Optional: User identity
  role={ParticipantRole.Participant} // Optional: Participant role
  defaultName="John"                 // Optional: Default display name
  language="en"                      // Optional: 'en' or 'ar'
  direction="ltr"                    // Optional: 'ltr' or 'rtl'
  showVideoPreview={true}            // Optional: Show video preview
  allowDeviceSelection={true}        // Optional: Allow device selection
  branding={{...}}                   // Optional: Custom branding
  onJoin={(data) => {                // Required: Join callback
    // data includes: token, serverUrl, role, permissions, 
    // displayName, audioEnabled, videoEnabled, virtualBackground
  }}
  onDismissed={(reason) => {}}       // Optional: Dismissed callback
  onMeetingEnded={() => {}}          // Optional: Meeting ended callback
  onError={(error) => {}}            // Optional: Error callback
/>

MeetingRoom

Full meeting room experience with video grid, controls, chat, and participant management.

<MeetingRoom
  room={room}                        // Required: Connected RQMeetRoom
  client={client}                    // Required: RQMeetClient instance
  meetingId="meeting_id"             // Required: Meeting ID
  role={ParticipantRole.Host}        // Required: Participant role
  permissions={permissions}          // Required: Participant permissions
  inviteToken="token"                // Optional: Invite token
  socket={socketClient}              // Optional: Socket client for real-time
  branding={{...}}                   // Optional: Custom branding
  language="en"                      // Optional: 'en' or 'ar'
  direction="ltr"                    // Optional: 'ltr' or 'rtl'
  enableChat={true}                  // Optional: Enable chat panel
  enableScreenShare={true}           // Optional: Enable screen sharing
  enableRecording={true}             // Optional: Enable recording (hosts)
  onLeave={() => {}}                 // Optional: Leave callback
  onMeetingEnded={() => {}}          // Optional: Meeting ended callback
/>

API Reference

RQMeetClient

Main client for API interactions.

const client = new RQMeetClient({
  apiKey: 'your_api_key',
  apiSecret: 'your_api_secret',      // Optional
  baseUrl: 'https://custom.domain',  // Optional: Override auto-detection
  timeout: 30000,                    // Optional: Request timeout (default: 30000ms)
  headers: { 'X-Custom': 'value' }   // Optional: Custom headers
});

// Note: baseUrl is auto-detected if not provided:
// - http://localhost:3000 when running on localhost
// - https://developer.rqmeet.com for production

Meeting Management

// Create a meeting
const meeting = await client.createMeeting({
  name: 'My Meeting',
  maxParticipants: 50,
  enableRecording: true,
  enableChat: true,
  enableScreenShare: true,
  scheduledStart: new Date('2024-01-01T10:00:00'),
  metadata: { customField: 'value' }
});

// Get meeting details
const meeting = await client.getMeeting('meeting_id');

// List meetings
const response = await client.listMeetings({
  page: 1,
  limit: 10,
  status: MeetingStatus.Active,
  sortBy: 'createdAt',
  sortOrder: 'desc'
});

// End a meeting
await client.endMeeting('meeting_id');

// Update meeting settings
await client.updateMeetingSettings('meeting_id', {
  enableWaitingRoom: true,
  autoAdmit: false
});

Joining Meetings

// Join with full room creation
const room = await client.joinMeeting({
  meetingId: 'meeting_id',
  participantName: 'John Doe',
  participantId: 'user_123',
  isHost: false,
  audioEnabled: true,
  videoEnabled: true
});

Participant Management

// Get participants
const participants = await client.getParticipants('meeting_id');

// Mute a participant
await client.muteParticipant('meeting_id', 'participant_id', true);

// Unmute a participant
await client.muteParticipant('meeting_id', 'participant_id', false);

// Mute all participants
await client.muteAllParticipants('meeting_id');

// Remove a participant
await client.removeParticipant('meeting_id', 'participant_id');

Recording

// Start recording
const recording = await client.startRecording('meeting_id');

// Start with options
const recording = await client.startRecordingWithOptions('meeting_id', {
  layout: 'speaker',
  fileType: 'mp4',
  videoBitrate: 3000000
});

// Stop recording
await client.stopRecording('meeting_id');

// Get recording status
const status = await client.getRecordingStatus('meeting_id');

// List recordings
const recordings = await client.listRecordings('meeting_id');

// Get download URL
const url = await client.getRecordingDownloadUrl('recording_id');

// Delete recording
await client.deleteRecording('recording_id');

Media Devices

// Get available devices
const devices = await client.getMediaDevices();
// devices.audioInputs, devices.audioOutputs, devices.videoInputs

// Request permissions
const stream = await client.requestMediaPermissions(true, true);

RQMeetRoom

Represents an active meeting connection with media controls.

Properties

room.id                    // Meeting ID
room.roomName              // Room name
room.isConnected           // Connection status
room.connectionState       // ConnectionState enum
room.localParticipant      // Local participant info
room.participants          // Map of remote participants
room.chatMessages          // Array of chat messages
room.virtualBackground     // Current virtual background settings
room.layoutContext         // Layout/focus mode context

Methods

// Connection
await room.connect();
await room.leave();

// Audio controls
await room.enableAudio();
await room.disableAudio();
await room.toggleAudio();
room.isAudioEnabled();

// Video controls
await room.enableVideo();
await room.disableVideo();
await room.toggleVideo();
room.isVideoEnabled();

// Screen sharing
await room.shareScreen();
await room.stopScreenShare();
room.isScreenSharing();

// Virtual background
await room.setVirtualBackground({ type: 'blur', blurRadius: 25 });
await room.setVirtualBackground({ type: 'image', imageUrl: '/bg.jpg' });
await room.setVirtualBackground({ type: 'none' });

// Device selection
await room.setAudioDevice('device_id');
await room.setVideoDevice('device_id');
await room.setAudioOutputDevice('device_id');
const devices = await room.getAvailableDevices();

// Chat
await room.sendMessage('Hello!');

// Focus mode
room.setFocusedTrack(trackReference);
room.clearFocusedTrack();

Events

import { RoomEvent } from '@rqmeet/web-sdk';

room.on(RoomEvent.Connected, () => {});
room.on(RoomEvent.Disconnected, (reason) => {});
room.on(RoomEvent.Reconnecting, () => {});
room.on(RoomEvent.Reconnected, () => {});
room.on(RoomEvent.ParticipantJoined, (participant) => {});
room.on(RoomEvent.ParticipantLeft, (participant) => {});
room.on(RoomEvent.TrackSubscribed, (track, publication, participant) => {});
room.on(RoomEvent.TrackUnsubscribed, (track, publication, participant) => {});
room.on(RoomEvent.TrackMuted, (track, participant) => {});
room.on(RoomEvent.TrackUnmuted, (track, participant) => {});
room.on(RoomEvent.ActiveSpeakersChanged, (speakers) => {});
room.on(RoomEvent.MessageReceived, (message) => {});
room.on(RoomEvent.RecordingStarted, () => {});
room.on(RoomEvent.RecordingStopped, () => {});
room.on(RoomEvent.ConnectionQualityChanged, (quality, participant) => {});
room.on(RoomEvent.MediaDeviceError, (error) => {});

DeveloperSocketClient

Real-time socket client for waiting room and host controls.

import { DeveloperSocketClient, SocketEvent } from '@rqmeet/web-sdk';

const socket = new DeveloperSocketClient({
  apiKey: 'your_api_key'
  // baseUrl is auto-detected (same as RQMeetClient)
});

// Connect
await socket.connect();

// Check into meeting with invite token (recommended)
socket.checkWithToken({
  inviteToken: 'invite_token',
  name: 'John Doe'
});

// OR legacy method with identity
socket.check({
  meetingId: 'meeting_id',
  identity: 'user_123',
  name: 'John Doe'
});

// Host: Register to receive waiting room updates
socket.registerHostWithToken({
  meetingId: 'meeting_id',
  inviteToken: 'host_invite_token'
});

// Host: Admit participant from waiting room
socket.allowParticipant({ meetingId: 'meeting_id', identity: 'user_123' });

// Host: Dismiss participant from waiting room
socket.dismissParticipant({ 
  meetingId: 'meeting_id', 
  identity: 'user_123',
  reason: 'Not authorized' 
});

// Host: Mute all participants
socket.muteAll({ meetingId: 'meeting_id' });

// Host: Ask participant to unmute
socket.askToUnmute({ 
  meetingId: 'meeting_id', 
  participantIdentity: 'user_123' 
});

// Host: Update participant role
socket.updateRole({
  meetingId: 'meeting_id',
  identity: 'user_123',
  role: ParticipantRole.CoHost,
  permissions: { canStartRecording: true }
});

// Host: End meeting for all
socket.endMeeting({ meetingId: 'meeting_id' });

// Events
socket.on('connected', () => {});
socket.on('disconnected', (reason) => {});
socket.on('allowed', (data) => {
  // data.token, data.serverUrl, data.role, data.permissions
});
socket.on('dismissed', (data) => {
  // data.reason
});
socket.on('waitingListUpdated', (data) => {
  // data.waitingList: WaitingUser[]
});
socket.on('participantJoined', (data) => {});
socket.on('participantLeft', (data) => {});
socket.on('muteAll', () => {});
socket.on('unmuteRequest', () => {});
socket.on('meetingEnded', () => {});
socket.on('roleUpdated', (data) => {
  // data.role, data.permissions
});
socket.on('error', (error) => {});

// Disconnect
socket.disconnect();

Types

Enums

import {
  MeetingStatus,      // Created, Active, Ended
  ParticipantRole,    // Host, CoHost, Participant
  TrackKind,          // Audio, Video
  TrackSource,        // Camera, Microphone, ScreenShare, ScreenShareAudio
  ConnectionState,    // Disconnected, Connecting, Connected, Reconnecting
  ConnectionQuality,  // Unknown, Poor, Good, Excellent
  RoomEvent,          // All room events
} from '@rqmeet/web-sdk';

Interfaces

import type {
  // Client & Config
  RQMeetClientConfig,
  MeetingConfig,
  JoinMeetingOptions,
  
  // Meeting & Participants
  Meeting,
  Participant,
  ParticipantInfo,
  MeetingSettings,
  
  // Tracks & Media
  Track,
  TrackReference,
  MediaDevice,
  VirtualBackground,
  
  // Chat & Recording
  ChatMessage,
  RecordingInfo,
  RecordingOptions,
  
  // Developer Features
  SocketPermissions,
  ExtendedTokenResponse,
  WaitingUser,
  DeveloperMeetingSettings,
  DeveloperMeetingConfig,
  ParticipantRoleDefinition,
  
  // Component Props
  PreJoinProps,
  MeetingRoomProps,
  BrandingConfig,
  
  // Utilities
  LayoutContext,
  UserChoices,
  PaginatedResponse,
} from '@rqmeet/web-sdk';

Error Handling

import { RQMeetError, ErrorCode } from '@rqmeet/web-sdk';

try {
  await client.joinMeeting({...});
} catch (error) {
  if (error instanceof RQMeetError) {
    switch (error.code) {
      case ErrorCode.Unauthorized:
        console.log('Invalid API key');
        break;
      case ErrorCode.NotFound:
        console.log('Meeting not found');
        break;
      case ErrorCode.MeetingFull:
        console.log('Meeting is full');
        break;
      case ErrorCode.ConnectionFailed:
        console.log('Failed to connect');
        break;
      default:
        console.log(error.message);
    }
  }
}

Browser Support

  • Chrome 74+
  • Firefox 78+
  • Safari 14.1+
  • Edge 79+

Peer Dependencies

  • react ^18.0.0
  • react-dom ^18.0.0

License

MIT © RQMeet