From zoom-skills
Provides pre-built React-based UI toolkit for Zoom Video SDK, enabling instant video conferencing sessions in web apps with composite UI or individual components. Supports React, Vue, Angular, Next.js, vanilla JS.
npx claudepluginhub zoom/skills --plugin zoom-skillsThis skill uses the workspace's default tool permissions.
Pre-built video conferencing UI powered by Zoom Video SDK. Drop-in solution for web applications.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Provides ClickHouse patterns for MergeTree schemas, query optimization, aggregations, window functions, joins, and data ingestion for high-performance analytics.
Pre-built video conferencing UI powered by Zoom Video SDK. Drop-in solution for web applications.
Official Documentation: https://developers.zoom.us/docs/video-sdk/web/ui-toolkit/ API Reference: https://marketplacefront.zoom.us/sdk/uitoolkit/web/ NPM Package: https://www.npmjs.com/package/@zoom/videosdk-zoom-ui-toolkit Live Demo: https://sdk.zoom.com/videosdk-uitoolkit
New to UI Toolkit? Follow this path:
Having issues?
The Zoom Video SDK UI Toolkit is a pre-built video UI library that renders complete video conferencing experiences with minimal code. Unlike the raw Video SDK, the UI Toolkit provides:
When to use UI Toolkit:
When to use raw Video SDK instead:
npm install @zoom/videosdk-zoom-ui-toolkit jsrsasign
npm install -D @types/jsrsasign
Note: React support depends on the UI Toolkit version. Check the package peer dependencies for your installed version (React 18 is commonly required).
import uitoolkit from "@zoom/videosdk-zoom-ui-toolkit";
import "@zoom/videosdk-ui-toolkit/dist/videosdk-zoom-ui-toolkit.css";
const container = document.getElementById("sessionContainer");
const config = {
videoSDKJWT: "your_jwt_token",
sessionName: "my-session",
userName: "John Doe",
sessionPasscode: "",
features: ["video", "audio", "share", "chat", "users", "settings"],
};
uitoolkit.joinSession(container, config);
uitoolkit.onSessionJoined(() => {
console.log("Session joined");
});
uitoolkit.onSessionClosed(() => {
console.log("Session closed");
});
'use client';
import { useEffect, useRef } from 'react';
export default function VideoSession({ jwt, sessionName, userName }) {
const containerRef = useRef<HTMLDivElement>(null);
const uitoolkitRef = useRef<any>(null);
useEffect(() => {
let isMounted = true;
const init = async () => {
const uitoolkitModule = await import('@zoom/videosdk-zoom-ui-toolkit');
const uitoolkit = uitoolkitModule.default;
uitoolkitRef.current = uitoolkit;
// If TypeScript complains about CSS imports, configure your app to allow them
// (for example via a global `declare module \"*.css\";`), or import the CSS from
// a global entrypoint (Next.js layout/_app) instead of inlining here.
await import('@zoom/videosdk-ui-toolkit/dist/videosdk-zoom-ui-toolkit.css');
if (!isMounted || !containerRef.current) return;
const config: any = {
videoSDKJWT: jwt,
sessionName: sessionName,
userName: userName,
sessionPasscode: '',
features: ['video', 'audio', 'share', 'chat', 'users', 'settings'],
};
uitoolkit.joinSession(containerRef.current, config);
uitoolkit.onSessionJoined(() => console.log('Joined'));
uitoolkit.onSessionClosed(() => console.log('Closed'));
};
init();
return () => {
isMounted = false;
if (uitoolkitRef.current && containerRef.current) {
try {
uitoolkitRef.current.closeSession(containerRef.current);
} catch (e) {}
}
};
}, [jwt, sessionName, userName]);
return <div ref={containerRef} style={{ width: '100%', height: '100vh' }} />;
}
| Feature | Description |
|---|---|
video | Enable video layout and send/receive video |
audio | Show audio button, send/receive audio |
share | Screen sharing |
chat | In-session messaging |
users | Participant list |
settings | Device selection, virtual background |
preview | Pre-join camera/mic preview |
recording | Cloud recording (paid plan) |
leave | Leave/end session button |
Required: Generate JWT tokens on your server, never expose SDK secret client-side.
import { NextRequest, NextResponse } from 'next/server';
import { KJUR } from 'jsrsasign';
const ZOOM_VIDEO_SDK_KEY = process.env.ZOOM_VIDEO_SDK_KEY;
const ZOOM_VIDEO_SDK_SECRET = process.env.ZOOM_VIDEO_SDK_SECRET;
export async function POST(request: NextRequest) {
const { sessionName, role, userName } = await request.json();
if (!sessionName || role === undefined) {
return NextResponse.json({ error: 'Missing params' }, { status: 400 });
}
const iat = Math.floor(Date.now() / 1000);
const exp = iat + 60 * 60 * 2; // 2 hours
const oHeader = { alg: 'HS256', typ: 'JWT' };
const oPayload = {
app_key: ZOOM_VIDEO_SDK_KEY,
role_type: role, // 0 = participant, 1 = host
tpc: sessionName,
version: 1,
iat,
exp,
user_identity: userName || 'User',
};
const signature = KJUR.jws.JWS.sign(
'HS256',
JSON.stringify(oHeader),
JSON.stringify(oPayload),
ZOOM_VIDEO_SDK_SECRET
);
return NextResponse.json({ signature });
}
| Field | Required | Description |
|---|---|---|
app_key | Yes | Your Video SDK Key |
role_type | Yes | 0 = participant, 1 = host |
tpc | Yes | Session/topic name |
version | Yes | Always 1 |
iat | Yes | Issued at (Unix timestamp) |
exp | Yes | Expiration (Unix timestamp) |
user_identity | No | User identifier |
uitoolkit.joinSession(container, config);
uitoolkit.closeSession(container);
uitoolkit.onSessionJoined(callback);
uitoolkit.onSessionClosed(callback);
uitoolkit.offSessionJoined(callback);
uitoolkit.offSessionClosed(callback);
uitoolkit.showChatComponent(container);
uitoolkit.hideChatComponent(container);
uitoolkit.showUsersComponent(container);
uitoolkit.hideUsersComponent(container);
uitoolkit.showControlsComponent(container);
uitoolkit.hideControlsComponent(container);
uitoolkit.showSettingsComponent(container);
uitoolkit.hideSettingsComponent(container);
uitoolkit.hideAllComponents();
<link rel="stylesheet" href="https://source.zoom.us/uitoolkit/2.3.5-1/videosdk-zoom-ui-toolkit.css" />
<script src="https://source.zoom.us/uitoolkit/2.3.5-1/videosdk-zoom-ui-toolkit.min.umd.js"></script>
<div id="sessionContainer"></div>
<script>
const uitoolkit = window.UIToolkit;
uitoolkit.joinSession(document.getElementById('sessionContainer'), {
videoSDKJWT: 'your_jwt',
sessionName: 'my-session',
userName: 'User',
features: ['video', 'audio', 'chat']
});
</script>
When deploying Next.js under a subpath:
// next.config.ts
const nextConfig = {
basePath: "/your-app-path",
assetPrefix: "/your-app-path",
};
Fetch API routes with full path:
fetch('/your-app-path/api/token', { ... })
| Browser | Version |
|---|---|
| Chrome | 78+ |
| Firefox | 76+ |
| Safari | 14.1+ |
| Edge | 79+ |
| Issue | Solution |
|---|---|
peer react@"^18.0.0" error | Use the React version required by the installed UI Toolkit package (check peer deps; React 18 is common) |
| CSS import TypeScript error | Configure TS/CSS handling (prefer a global *.css module declaration); avoid @ts-ignore except in throwaway demos |
| Config type error | Type config as any |
| API returns HTML not JSON | Check basePath in fetch URL |
This section was migrated from SKILL.md.
Complete navigation for all UI Toolkit documentation.
New to the UI Toolkit? Follow this learning path:
Understanding how UI Toolkit works:
Complete API documentation:
Core Methods (see skill.md)
joinSession() - Start a video sessioncloseSession() - End session and remove UIdestroy() - Clean up UI Toolkit instanceleaveSession() - Leave without destroying UIComponent Methods (see skill.md)
showControlsComponent() - Display control barshowChatComponent() - Display chat panelshowUsersComponent() - Display participants listshowSettingsComponent() - Display settings panelhideAllComponents() - Hide all componentsEvent Listeners (see skill.md)
onSessionJoined() - Session joined successfullyonSessionClosed() - Session endedonSessionDestroyed() - UI Toolkit destroyedonViewTypeChange() - View mode changedon() - Subscribe to Video SDK eventsoff() - Unsubscribe from eventsInformation Methods (see skill.md)
getSessionInfo() - Get session detailsgetCurrentUserInfo() - Get current usergetAllUser() - Get all participantsgetClient() - Get underlying Video SDK clientversion() - Get version infoControl Methods (see skill.md)
changeViewType() - Switch view modemirrorVideo() - Mirror self videoisSupportCustomLayout() - Check device supportStatistics Methods (see skill.md)
subscribeAudioStatisticData() - Audio quality statssubscribeVideoStatisticData() - Video quality statssubscribeShareStatisticData() - Share quality statsFeature Configuration (see skill.md)
featuresOptions structureSession Configuration (see skill.md)
videoSDKJWT, sessionName, userNamesessionPasscode, sessionIdleTimeoutMinsSee: troubleshooting/common-issues.md
Official Repositories:
| Framework | Repository | Key Features |
|---|---|---|
| React | videosdk-zoom-ui-toolkit-react-sample | Hooks, TypeScript |
| Vue.js | videosdk-zoom-ui-toolkit-vuejs-sample | Composition API |
| Angular | videosdk-zoom-ui-toolkit-angular-sample | Services, Guards |
| JavaScript | videosdk-zoom-ui-toolkit-javascript-sample | Vanilla JS |
| Auth Endpoint | videosdk-auth-endpoint-sample | Node.js JWT |
import uitoolkit from "@zoom/videosdk-zoom-ui-toolkit";
import "@zoom/videosdk-ui-toolkit/dist/videosdk-zoom-ui-toolkit.css";
const config = {
videoSDKJWT: "YOUR_JWT",
sessionName: "test-session",
userName: "User",
featuresOptions: {
video: { enable: true },
audio: { enable: true }
}
};
uitoolkit.joinSession(document.getElementById("container"), config);
uitoolkit.onSessionJoined(() => console.log("Joined"));
uitoolkit.onSessionClosed(() => uitoolkit.destroy());
destroy() on cleanuponSessionClosed cleanupjoinSessionNavigation: ← Back to SKILL.md
.env keys and where to find each value.