by Naima B.

MiroTalk P2P is an open-source, self-hosted video conferencing platform using peer-to-peer WebRTC for secure, real-time communication up to 8K@60fps, with a full REST API, webhook support, and Docker/Kubernetes deployment.
This block provides the complete MiroTalk P2P server — a self-hosted WebRTC video conferencing backend built on Node.js, Express, and Socket.IO. It handles room signaling, REST API endpoints, JWT token management, STUN/TURN integration, and optional third-party service hooks (Mattermost, OpenAI, Sentry, ngrok). The typical buyer is a backend developer embedding a private video conferencing capability into an existing Node.js application or deploying it as a standalone microservice.
.github/ - CI workflows and issue templates for the upstream projectapp/ - Core server source: Express app, Socket.IO signaling, REST API, SSL config, and utility modulescoturn/ - TURN server configuration templates and Docker Compose for self-hosted TURNdocs/ - Self-hosting guides for coturn, ngrok, and general deploymentkubernetes/ - Kubernetes manifests for deploying MiroTalk P2P in a clusterpublic/ - Static frontend assets served by Express (HTML, CSS, JS, images)webhook/ - Webhook integration examples and handler stubswidgets/ - Embeddable widget code for third-party site integration.prettierrc.js - Prettier formatting configuration (semi, singleQuote, tabWidth: 4)package.json - NPM manifest declaring all runtime dependenciesinstall.sh - Automated install script for bare-metal Linux deploymentdocker-compose.template.yml - Docker Compose template for containerized deploymentdocker-compose-mailpit.yml - Docker Compose variant adding Mailpit for local email testingnpm install @mattermost/client @ngrok/ngrok @sentry/node axios chokidar colors compression cors crypto-js dompurify dotenv express express-openid-connect express-rate-limit he helmet httpolyglot js-yaml jsdom jsonwebtoken nodemailer openai qs socket.io swagger-ui-express
No native module compilation or platform-specific prebuild steps are required. Node.js 18+ is recommended. If deploying with TLS via httpolyglot, ensure your SSL certificate files are present at the paths specified in app/ssl/ (see app/ssl/README.md).
Copy the source/ directory into your project root or a dedicated subdirectory (e.g., ).
Spin up an isolated sandbox and run it server-side — no local setup.
Tetrees AI Review of this version
This Express backend / api completed archive review with strong static results. Structure, dependency manifests, documentation, functional source, and common risk patterns were checked by the Tetrees verification pipeline; runtime phases are stated separately.
Deterministic AVCP artifact review
Pipeline avcp-2026-08-04.1 · SHA-256 8e27796031fadf8b…
This version-scoped review deterministically inspects the submitted archive for structure, dependencies, documentation, functional source, and common malicious or high-risk signals. Build and test phases are reported as passed only after an isolated sandbox audition. It is not a guarantee of perfect security.
Reviewed Aug 4, 2026
Push this product straight into your AI IDE, web builder or cloud IDE.
Connect Tetrees to a compatible AI IDE, list products you own, and request the verified ZIP without exposing seller upload controls.
No reviews yet.
Sign in to join the discussion
Loading discussion…
./mirotalk/Copy source/app/src/config.template.js to source/app/src/config.js and populate all required fields:
cp source/app/src/config.template.js source/app/src/config.js
.env file at the project root. The server reads environment variables via dotenv. Required variables include at minimum:# .env
HTTPS=false
HOST=localhost
PORT=3000
API_KEY_SECRET=your_api_key_here
JWT_KEY=your_jwt_secret_here
SENTRY_DSN= # optional
NGROK_ENABLED=false
NGROK_AUTH_TOKEN= # optional
OIDC_ENABLED=false
tsconfig.json so imports resolve correctly:{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"mirotalk/*": ["source/app/src/*"]
}
}
}
node source/app/src/server.js
Or require it programmatically (see examples below).
app/src/server.js// Entry point — starts the Express + Socket.IO server
// No named exports; execute directly with Node or require() to bootstrap
import './source/app/src/server.js';
The main server module sets up Express routes, mounts the Swagger UI at /api/docs, registers Socket.IO signaling handlers, and begins listening on the configured port. Require or import this file to start the full conferencing backend as part of a larger application.
app/src/tokenManager.js// Signs and verifies JWT tokens for API and room access
// Exports functions accessible via require('./tokenManager')
const tokenManager = require('./source/app/src/tokenManager');
tokenManager.sign(payload: object, secret: string, options?: object): string;
tokenManager.verify(token: string, secret: string): object | null;
Use sign to generate short-lived tokens for room join links or API authentication. Use verify in middleware to validate inbound tokens before allowing socket or REST access.
app/src/validate.js// Input validation helpers used by REST endpoints
const validate = require('./source/app/src/validate');
validate.isValidRoomId(roomId: string): boolean;
validate.isValidToken(token: string): boolean;
Call these helpers before processing room creation or join requests to reject malformed input early, preventing downstream signaling errors.
app/src/xss.js// XSS sanitization using DOMPurify + jsdom
const xss = require('./source/app/src/xss');
xss.sanitize(input: string): string;
Run all user-supplied strings (display names, chat messages, room IDs) through sanitize before broadcasting over Socket.IO to prevent stored XSS in connected clients.
Start the MiroTalk server as a subprocess from your orchestrator process so it runs on a separate port alongside your application.
import { spawn } from 'child_process';
import path from 'path';
const mirotalkEntry = path.resolve(__dirname, 'source/app/src/server.js');
const mirotalk = spawn('node', [mirotalkEntry], {
env: {
...process.env,
PORT: '3030',
HTTPS: 'false',
API_KEY_SECRET: process.env.MIROTALK_API_KEY ?? 'changeme',
JWT_KEY: process.env.MIROTALK_JWT_KEY ?? 'changeme',
},
stdio: 'inherit',
});
mirotalk.on('exit', (code) => {
console.error(`MiroTalk exited with code ${code}`);
});
Use the token manager to produce a time-limited URL for a room that your application controls.
import tokenManager from './source/app/src/tokenManager.js';
const JWT_KEY = process.env.JWT_KEY ?? 'changeme';
function createRoomJoinUrl(roomId: string, username: string): string {
const payload = {
room: roomId,
username,
iat: Math.floor(Date.now() / 1000),
};
const token = tokenManager.sign(payload, JWT_KEY, { expiresIn: '1h' });
return `https://yourdomain.com/join/${roomId}?token=${token}`;
}
const url = createRoomJoinUrl('engineering-standup', 'alice');
console.log('Join URL:', url);
MiroTalk exposes a REST API (documented via Swagger at /api/docs). Use axios to call it from a backend service.
import axios from 'axios';
const BASE_URL = 'http://localhost:3030';
const API_KEY = process.env.MIROTALK_API_KEY ?? 'changeme';
async function createMeeting(): Promise<string> {
const response = await axios.post(
`${BASE_URL}/api/v1/meeting`,
{},
{
headers: {
authorization: API_KEY,
'Content-Type': 'application/json',
},
}
);
// Returns { meeting: '<room-id>' }
return response.data.meeting as string;
}
(async () => {
const roomId = await createMeeting();
console.log('Created meeting room:', roomId);
})();
Before accepting a display name or chat message from an untrusted source, sanitize it.
import xss from './source/app/src/xss.js';
function handleChatMessage(rawMessage: string): string {
const clean = xss.sanitize(rawMessage);
// safe to store in DB or emit over socket
return clean;
}
const safe = handleChatMessage('<img src=x onerror=alert(1)>Hello');
console.log(safe); // 'Hello'
app/src/server.js - Primary entry point; instantiates Express, Socket.IO, and all middleware. Run this to start the server.app/src/config.template.js - Template for the runtime configuration file; copy to config.js and fill in secrets before starting.app/src/tokenManager.js - JWT signing and verification used by both REST API auth and room join token flows.app/src/validate.js - Input validation functions protecting API and socket endpoints.app/src/xss.js - DOMPurify-backed sanitization to strip XSS payloads from user-supplied strings.app/src/api.js - Registers Express REST routes; mounts Swagger UI and delegates to handler modules.app/src/host.js - Resolves the public host/IP of the server for STUN/TURN and signaling URLs.app/src/logs.js - Configures the logger (colors, log levels) used throughout the application.app/src/htmlInjector.js - Injects dynamic server-side values into served HTML pages.app/src/mattermost.js - Optional Mattermost webhook integration for room event notifications.app/src/lib/nodemailer.js - Nodemailer wrapper for sending email invitations and notifications.app/api/ - Per-endpoint API examples in JS, PHP, Python, and shell for each REST route.app/ssl/ - SSL certificate placement guide and HTTPS configuration reference.coturn/ - TURN server Docker Compose template and turnserver.conf for NAT traversal.public/ - Static frontend (HTML/CSS/JS) served at the web root by Express.webhook/ - Webhook payload examples for room lifecycle events.widgets/ - Embeddable iframe/widget snippets for integrating a join button into external sites.kubernetes/ - YAML manifests for Deployment, Service, Ingress, and TLS cert in Kubernetes.docs/ - Markdown guides: coturn setup, ngrok tunneling, and self-hosting checklist.config.js not found on startup - config.template.js is the template; copy it to config.js before running: cp app/src/config.template.js app/src/config.js.JWT_KEY in .env must match the value used when tokenManager.sign was called; mismatched secrets cause silent null returns from verify.coturn/ on a public IP, set external-ip in turnserver.conf, and add the TURN credentials to config.js; missing TURN is the most common cause of one-way media.httpolyglot crashes with ENOENT on SSL files - When HTTPS=true, the cert/key paths in config.js must exist; either provide real certs or set HTTPS=false for local development.express-rate-limit is active by default; raise the window/max values in config.js or disable it in non-production environments.authorization header must carry the exact value of API_KEY_SECRET; the header name is lowercase and the value is the raw secret string, not a Bearer token.I have a Node.js/TypeScript project and I want to integrate MiroTalk P2P (npm: user@example.com) as a self-hosted WebRTC video conferencing backend.
The full source is in the `source/` directory of this project. The integration guide is in `USAGE.md`.
Please do the following step by step:
1. Read USAGE.md and the file structure under source/ to understand the available modules.
2. Copy source/app/src/config.template.js to source/app/src/config.js and scaffold the required .env variables listed in USAGE.md.
3. Add a startup script or module in my project that launches source/app/src/server.js with the correct environment, either as a child process or a direct require/import.
4. Wire source/app/src/tokenManager.js into my existing auth middleware so that room join URLs are signed with JWT.
5. Apply source/app/src/xss.js sanitization to any user-supplied input before it is stored or broadcast.
6. Expose the MiroTalk REST API at /api/v1 in my Express router by importing source/app/src/api.js.
7. Confirm all imports reference only real exports visible in the source files and USAGE.md — do not invent any symbols.
8. List any missing .env values I must fill in before the server will start.
MiroTalk P2P is released under the GNU Affero General Public License v3.0 (AGPLv3). Any modifications to the source, or any software that incorporates it and is run over a network, must be released under the same license. Commercial one-time-fee licenses are available separately via CodeCanyon.
Upstream repository and package: github.com/miroslavpejic85/mirotalk / npm: mirotalk.
This product’s unique contribution is clean room implementation of valuable code block into AVCP compatible standard.
The full install guide and integration prompts unlock after purchase.
Mobile App Templates & App Source Code
Free