# Peerix | WebRTC development made simple
URL: https://peerix.dev/
Published: 2026-05-28

Open Source

Build peer-to-peer apps without headaches

Simple and extensible API, optimized for performance, for creating WebRTC applications

## Why Peerix?

## Peerix in 1 minute

[Video](https://peerix.dev/video/peerix-intro.webm)

[Video](https://peerix.dev/video/peerix-intro.mp4)

Your browser does not support video.

## Frequently Asked Questions

A lightweight JavaScript/TypeScript library that simplifies WebRTC by handling signaling, NAT traversal, and connection state so you can build peer-to-peer apps faster.

Yes — peers need signaling to discover each other; Peerix is transport-agnostic and supports drivers for different signaling backends. You can use built-in drivers or implement your own custom driver.

No — Peerix is not an SFU (Selective Forwarding Unit) or MCU (Multipoint Control Unit). It focuses on enabling direct peer-to-peer communication between clients, without server-side media processing or routing.

Peerix uses standard WebRTC techniques, such as ICE (Interactive Connectivity Establishment), STUN (Session Traversal Utilities for NAT), and TURN (Traversal Using Relays around NAT) servers, to handle NAT traversal and firewall restrictions, ensuring reliable peer-to-peer connections. You can specify public STUN servers or set up your own TURN server for better connectivity in restrictive network environments.

Both — documentation covers self-hosting your signaling/TURN infrastructure or using cloud hosting options.

Peerix targets all major browsers; the library and tests aim to ensure broad browser compatibility.

Peerix is an open-source project licensed under the Apache License, Version 2.0.

# Blog
URL: https://peerix.dev/blog/
Published: 2026-05-28

[RSS Feed](https://peerix.dev/blog/index.xml)


# Peerix v0.2 Released
URL: https://peerix.dev/blog/release-v0-2/
Published: 2026-05-13

Peerix `v0.2` is now available. This release expands signaling options, simplifies interoperability, and improves default privacy behavior in production environments.

## Highlights

### New signaling drivers

Peerix now includes two new built-in signaling drivers:

- [`SocketIoDriver`](https://peerix.dev/docs/drivers/socket-io/) for applications using Socket.IO infrastructure.
- [`SupabaseDriver`](https://peerix.dev/docs/drivers/supabase/) for projects built on Supabase Realtime.

These drivers make it easier to integrate Peerix into existing stacks without adding custom signaling glue code.

In `v0.2`, both drivers follow the same setup pattern used by other Peerix signaling drivers: create your transport client, pass it to the driver, then initialize `Peer` with that driver. This makes it simple to switch transports without changing application-level peer logic.

#### Socket.IO driver

[Socket.IO](https://socket.io/) is a popular real-time communication library that provides a WebSocket-like API with fallbacks for older browsers. The `SocketIoDriver` allows you to use Socket.IO as the signaling transport for Peerix, enabling seamless integration with existing Socket.IO servers.

```js
import { Peer, SocketIoDriver } from 'peerix';
import { io } from 'socket.io-client';

const socket = io('https://your-socket-server.example.com');

const driver = new SocketIoDriver({
  socket,
  prefix: 'peerix',
});

const peer = new Peer({ driver });
await peer.join({ room: 'my-room' });
```

Note that you will need a compatible server-side Socket.IO implementation to use this driver. See the [Socket.IO Driver docs](https://peerix.dev/docs/drivers/socket-io/#server-example) for a code example.

#### Supabase driver

[Supabase Realtime](https://supabase.com/docs/guides/realtime) is a serverless real-time database and messaging service built on PostgreSQL. The `SupabaseDriver` allows you to use Supabase Realtime as the signaling transport for Peerix, making it easy to integrate with applications already using Supabase.

```js
import { Peer, SupabaseDriver } from 'peerix';
import { createClient } from '@supabase/supabase-js';

const supabase = createClient(
  'https://your-project.supabase.co',
  'public-anon-key',
);

const driver = new SupabaseDriver({
  supabase,
  prefix: 'peerix',
});

const peer = new Peer({ driver });
await peer.join({ room: 'my-room' });
```

Note that you will need to set up a Supabase Realtime subscription on the server side to use this driver.

### NATS driver update

The `NatsDriver` now uses `nats-core` instead of `nats.ws` because of deprecation. This change improves consistency and aligns Peerix with the current direction of the NATS JavaScript ecosystem.

#### NATS (`nats-core`) example

```js
import { Peer, NatsDriver } from 'peerix';
import { wsconnect } from '@nats-io/nats-core';

const nc = await wsconnect({ servers: ['wss://demo.nats.io:8443'] });

const driver = new NatsDriver({
  nc,
  prefix: 'peerix',
});

const peer = new Peer({ driver });
await peer.join({ room: 'my-room' });
```

See [NATS Driver docs](https://peerix.dev/docs/drivers/nats/) for full details and migration guidance.

#### Driver cleanup with `destroy`

When your app unmounts a page, leaves a workspace, or otherwise tears down realtime state, explicitly destroy the driver to avoid dangling subscriptions or listeners:

```js
await peer.leave();
await driver.destroy();
```

### Serialization-friendly driver interface

The driver interface now favors plain arrays over typed arrays. This improves serialization across environments and transports, especially when messages cross boundaries where typed arrays can be awkward or lossy.

### Namespace hashing enabled by default

Namespace hashing is now enabled by default. This delivers two practical benefits:

- Better privacy by avoiding direct exposure of raw namespace values.
- Better compatibility by preventing issues with unsupported namespace characters.

## Upgrade notes

When moving to `v0.2`, review the following:

- If you rely on readable namespace values in infrastructure logs or tooling, account for hashing now being enabled by default.
- If your custom drivers depend on typed array assumptions, update them to work with plain arrays.
- If you use NATS signaling, verify your setup against the `nats-core` dependency.

## Thank you

Thanks to everyone trying Peerix early and sharing feedback. Your input helps shape the roadmap and improve real-world reliability.

More updates are coming soon, including continued work on drivers and developer experience.


# Peerix v0.3 Released
URL: https://peerix.dev/blog/release-v0-3/
Published: 2026-05-23

Peerix `v0.3` is now available. This release introduces a new SSE signaling driver, strengthens secure defaults, improves signaling efficiency, and updates compatibility and licensing for wider adoption.

## Highlights

### New `SseDriver` for signaling

Peerix now includes [`SseDriver`](https://peerix.dev/docs/drivers/sse/) for signaling over [Server-Sent Events (SSE)](https://developer.mozilla.org/docs/Web/API/Server-sent_events).

The SSE driver is a browser-friendly option for production signaling: incoming updates are delivered through a single SSE stream, while outbound signaling messages are sent via standard HTTP `POST` requests.

```js
import { Peer, SseDriver } from 'peerix';

const driver = new SseDriver({
  url: 'http://localhost:8080/api/sse',
  withCredentials: false,
});

const peer = new Peer({ driver });
await peer.join({ room: 'my-room' });
```

See the [SSE Driver docs](https://peerix.dev/docs/drivers/sse/) for full usage and a server example.

### Lower signaling overhead with ICE candidate debouncing

Peerix now debounces ICE candidate signaling. This reduces message bursts during negotiation and lowers transport load, especially in rooms where multiple peers join around the same time.

### More secure defaults

`v0.3` improves signaling security and identity defaults:

- Signaling encryption now uses derived keys instead of manually supplied secret keys.
- Signaling encryption is enabled by default.
- Peer IDs now use compressed public keys.
- `signalingHashing` has been renamed to `namespaceHashing` for clarity and consistency.

These updates make secure setups easier out of the box while preserving flexibility for advanced deployments.

### Modern runtime baseline

This release raises the minimum build target to `ES2020` to support modern JavaScript features such as `BigInt`.

### Updated licensing

Peerix is now licensed under `Apache-2.0`, replacing `GPL-3.0`. This makes adoption easier for both open-source and commercial projects.

## Upgrade notes

When upgrading to `v0.3`, review the following:

- If you used manually managed signaling secret keys, migrate to the new derived-key flow.
- If you configured `signalingHashing`, rename it to `namespaceHashing`.
- If your environment depends on older JavaScript targets, ensure your toolchain supports `ES2020`.
- If you need cross-browser/server signaling without WebSockets, consider moving to [`SseDriver`](https://peerix.dev/docs/drivers/sse/).

## Thank you

Thanks to everyone testing Peerix and sharing feedback. Your input continues to improve reliability, performance, and developer experience.

More improvements are coming soon across core functionality, drivers, examples, and documentation.


# Peerix v0.4 Released
URL: https://peerix.dev/blog/release-v0-4/
Published: 2026-05-28

We are thrilled to announce the `v0.4` release of the Peerix library. Peerix continues its mission of simplifying WebRTC development by abstracting the heavy lifting of signaling and connection management into a minimal, transport-agnostic API. This release focuses on expanding our signaling transport options for production environments, refining our API for a better developer experience, and optimizing performance under the hood.

## Highlights: New Signaling Drivers for Production Scale

While our earlier releases focused on getting peers connected, v0.4 is about moving from local prototypes to distributed production environments. We've added two major signaling drivers to support industry-standard messaging infrastructure.

### MQTT Driver

The `MqttDriver` enables signaling via the MQTT protocol and is specifically designed for MQTT over WebSockets. This allows developers to leverage robust brokers like Mosquitto for their signaling needs. It is an ideal choice for lightweight pub/sub signaling within existing messaging ecosystems.

- Requires the external `mqtt` module.
- Requires a running MQTT broker, for example, a [Mosquitto server](https://peerix.dev/docs/servers/self-hosting/#mosquitto-server).
- Documentation: [MQTT Driver](https://peerix.dev/docs/drivers/mqtt/)

### Centrifuge Driver

The `CentrifugeDriver` integrates with the Centrifugo real-time messaging server. This driver is built for developers who need high fan-out capabilities and reliable reconnection support in high-traffic production environments.

- Requires the external `centrifuge` module.
- Requires a running [Centrifugo server](https://peerix.dev/docs/servers/self-hosting/#centrifugo-server).
- Documentation: [Centrifuge Driver](https://peerix.dev/docs/drivers/centrifuge/)

### SSE Driver Enhancements

The `SseDriver` has been updated to default to the Mercure-compatible endpoint (`/.well-known/mercure`), making it easier for developers using the Mercure hub to get started without additional configuration. This change simplifies setup and reduces friction for those leveraging Mercure for their signaling needs.

- No external modules required.
- Requires a running [Mercure server](https://peerix.dev/docs/servers/self-hosting/#mercure-server) or another SSE-compatible server (with a code example provided).
- Documentation: [SSE Driver](https://peerix.dev/docs/drivers/sse/)

## Improved Developer Experience: Local Testing with Docker

To lower the barrier for local development, v0.4 now includes example code snippets and configurations for running signaling backends locally using Docker. You can now quickly spin up instances of NATS, Mercure, Mosquitto, and Centrifugo with standardized setups. This ensures that your local testing environment mirrors your production infrastructure as closely as possible.

## API Refinements

In our ongoing effort to create a more intuitive and consistent API, we have made some key changes to method naming conventions. The term `publish` has been reserved exclusively for the Signaling Layer to align with standard messaging terminology. For the Application Layer, we have introduced `share` and `unshare` to better describe how media and data streams are managed. This change helps avoid confusion between signaling events and application-level actions.

**Migration Mapping**

| Old Method        | New Method       | Layer                |
| ----------------- | ---------------- | -------------------- |
| `Driver.dispatch` | `Driver.publish` | Driver               |
| `Peer.publish`    | `Peer.share`     | Peer (media streams) |
| `Peer.unpublish`  | `Peer.unshare`   | Peer (media streams) |

## Performance and Technical Optimizations

As a core maintainer, my focus is often on the "under-the-hood" efficiencies that keep your apps performant. This release includes several technical wins for reducing message overhead:

- **Protobuf-like Format**: We have transitioned from a custom binary format to a Protobuf-like format for signaling messages. This transition allows us to use an industry-standard serialization method and reuse it across several internal components, reducing the need for custom parsing logic and minimizing message sizes.
- **ICE Candidate Debouncing**: To minimize signaling chatter, we've introduced the `iceCandidateDebounce` option in the Peer class. It defaults to `50ms`, batching candidates to reduce the frequency of messages sent during the negotiation phase.
- **SocketIoDriver Enhancements**: We have added an `ackTimeout` option to the SocketIoDriver, giving you granular control over how long the client waits for server acknowledgments.
- **Simplified Event Naming**: Most drivers now use peer or room identifiers directly as event names. By avoiding string concatenation, we've shortened name lengths to reduce signaling overhead.

## Upgrade and Migration Notes

If you are moving from `v0.3` to `v0.4`, please review these breaking changes:

- **Method Renaming**: All application-level calls to `publish` and `unpublish` must be updated to `share` and `unshare`. This change applies to both the `Peer` and `RemotePeer` classes.
- **Driver Active State**: The Driver class now initializes with the `active` accessor set to `false` by default. Ensure your logic accounts for the driver state during startup.
- **Prefix Handling & Separators**: Some drivers now use empty prefixes by default and no longer automatically include separators. If you require a separator, it must be part of your prefix string.
- _Example_: If your prefix is `peerix` and the event is `event`, it will result in `peerixevent`. To get `peerix:event`, you must define the prefix as `peerix:`.
- **Namespace Hashing Compatibility**: When namespaceHashing is disabled, the room property is now automatically escaped. This prevents character compatibility issues with certain signaling backends that do not support specific symbols or spaces.

## Conclusion

This release brings us closer to a truly plug-and-play WebRTC experience that scales. For full details on these changes, please visit our updated resources:

- 📚 [Documentation](https://peerix.dev/docs/)
- 📑 [API Reference](https://api.peerix.dev/)


# Welcome to Peerix
URL: https://peerix.dev/blog/welcome-to-peerix/
Published: 2026-05-06

My name is Anton Skshidlevsky (aka meefik), and I'm a software engineer with over twenty years of experience in software development and over ten years of experience in building WebRTC web applications. Today, I'm excited to announce the first release of Peerix, a JavaScript/TypeScript open-source library designed to simplify building WebRTC peer-to-peer applications. After months of development and testing, Peerix is now available for developers to use and contribute to.

## Background

Over ten years ago, I started building peer-to-peer web applications using WebRTC. It was an exciting but often frustrating journey, as I had to repeatedly solve the same problems around signaling, connection management, and media/data exchange across browsers and devices. However, from time to time, things went wrong. I wanted a simpler way to build these apps without reinventing the wheel every time, but existing libraries didn't quite fit the bill.

That's exactly why I created Peerix, which brings all of this expertise together. It abstracts away the complexities of WebRTC and provides a clean, minimal API for building peer-to-peer apps quickly and reliably. Whether you're building a simple chat app, a video conferencing service, a collaborative tool, or a more sophisticated multi-stream, multi-channel experience, Peerix aims to make it easier to get up and running without getting bogged down in the details of signaling and connection management. I'm excited to share it with the community and see what you build with it!

Currently, Peerix implements core functionality around WebRTC and peer-to-peer connections. Even now, it supports a wide range of use cases, from simple data sharing to multi-stream media applications. The core API is designed to be minimal and intuitive, with sensible defaults for signaling and connection management. Just a few lines of code are needed to get started. In the future, we plan to add more features and add-ons, as well as additional signaling drivers to further enhance the capabilities of Peerix.

## Why peer-to-peer

Peer-to-peer communication has many advantages, including lower latency, better privacy, and reduced server costs. By connecting peers directly, you can build applications that are more responsive and scalable, without relying on centralized servers for media processing or routing. Peerix is designed to make it easy to build these kinds of applications, allowing you to focus on building your application's features and user experience, rather than dealing with the complexities of WebRTC and signaling.

I admit that sometimes a server-side component is necessary, especially for media processing or routing in large-scale applications. However, for many use cases, a pure peer-to-peer architecture can provide significant benefits. With the correct configuration, each peer can connect to dozens of other peers without hitting performance issues, and the server can be reserved for signaling and coordination rather than media processing. You can have thousands of rooms with dozens of peers each, all without needing a single SFU or MCU. You can even do some media processing directly in the browser with add-ons, such as recording or mixing, without needing to route media through a server. So peer-to-peer is powerful and can be the right choice for many applications, and Peerix is here to make it easier to build those applications.

## Why Peerix

WebRTC is powerful but complex. Most apps re-implement the same boilerplate: signaling channels, ICE configuration, connection lifecycle, and multi-track negotiation. That complexity slows prototyping, increases bugs, and raises the barrier for developers who just want to share media or data peer-to-peer.

Interestingly, there are not many libraries that offer a clean, well-documented abstraction over WebRTC, including modern concepts like multi-track, data channels, and pluggable signaling. Many libraries focus on specific use cases (e.g., video calls) or require server-side components (e.g., SFUs). Peerix fills the gap for a flexible, transport-agnostic client-side library that abstracts away the common complexities of WebRTC while still allowing you to build a wide range of peer-to-peer applications.

## The problem it solves

Typical WebRTC apps face several challenges:

- Signaling vendor lock-in: many libraries tie you to a specific signaling method (e.g., WebSockets), making it hard to switch or support multiple transports.
- Hard-to-manage negotiations of multiple media streams and data channels across multiple peers in mesh and room-based topologies.
- STUN/TURN and reconnection complexities that leak into app code.
- Extra boilerplate for additional functionality like E2E encryption, recording, storage, state synchronization, etc.

Peerix centralizes these concerns in a single `Peer` class and a pluggable driver model for signaling, so the same API works locally (MemoryDriver), between tabs (BroadcastChannelDriver), or across the internet (NATS driver or custom drivers). It can be extended with add-ons without modifying your core app logic.

## Core idea

Peerix provides a simple yet powerful abstraction of WebRTC with transport-agnostic architecture and extends its capabilities with add-ons, all while keeping the API minimal.

At the heart of Peerix is a simple principle: a room-based topology involves a single connection per peer and multiplexes media tracks and data channels over that connection using transport-agnostic drivers. This reduces signaling chatter and avoids creating multiple redundant peer connections for each stream or channel. The pluggable driver model abstracts away the signaling transport, allowing you to choose or implement the one that best fits your use case without changing your app code. The library exposes clear lifecycle events so that apps can react declaratively.

## Advantages

Let's summarize the key advantages of Peerix:

- Minimal API surface: quick to learn and integrate.
- Pluggable signaling drivers: swap BroadcastChannel, NATS, or your own driver over WebSockets.
- Single-connection multiplexing: efficient resource use and simpler negotiation.
- Flexible: share multiple streams, open multiple data channels, and attach add-ons to extend functionality.

## Who is it for

Peerix is for developers building real-time apps such as chat, conferencing, file sharing, collaborative tools, and games who want to avoid reimplementing signaling and connection plumbing, and who need a flexible, extensible foundation for peer-to-peer communication in the browser. If you want to build peer-to-peer web apps without reinventing the wheel, Peerix is for you.

## When not to use it

If you need server-side media processing or routing, Peerix is not an SFU (Selective Forwarding Unit) or MCU (Multipoint Control Unit).

## License

Peerix is licensed under the Apache License, Version 2.0. This means you can use, modify, and distribute Peerix in your open-source or commercial projects without any restrictions. See the [LICENSE](http://www.apache.org/licenses/LICENSE-2.0) file for details.

## Future plans

In the future, we plan to expand Peerix with additional features and signaling drivers. Some of the upcoming features include:

- Additional signaling drivers: SSE driver, Socket.IO driver, Supabase driver, and more.
- Recording add-on: easily record media streams or data channels.
- State synchronization add-on: keep application state in sync across peers.
- Video/audio mixing add-on: mix multiple media streams together for composite outputs.

## Get started

A code snippet to illustrate how simple it is to get started with Peerix:

```js
import { Peer, BroadcastChannelDriver } from 'peerix';

// create a signaling driver
const driver = new BroadcastChannelDriver();

// create a Peer instance
const peer = new Peer({ driver });

// listen for events
peer.on('channel:open', ({ channel }) => channel.send('hello'));
peer.on('channel:message', ({ data }) => console.log('msg', data));

// open a data channel
peer.open({ label: 'chat' });

// join a room
peer.join({ room: 'room-id' });
```

See the Getting Started guide to install Peerix and try it in your browser. Contributions, issues, and driver add-ons are welcome — Peerix aims to be a practical, community-driven toolkit for peer-to-peer web apps.

Welcome aboard — now let's make peer-to-peer apps easier.

## Conclusion

Eventually, we hope Peerix will become a go-to library for developers building peer-to-peer web applications, providing a solid foundation that abstracts away the complexities of WebRTC while still allowing for flexibility and extensibility. We look forward to seeing what the community builds with Peerix and welcome contributions to help make it even better.

# Privacy Policy
URL: https://peerix.dev/privacy-policy/
Published: 2026-05-23

_Effective date: May 23, 2026_

## 1. Introduction

Peerix ("we", "us", or "our") is committed to protecting your privacy. This Privacy Policy explains what information we collect, how we use it, and your rights in relation to it. Please read it carefully.

## 2. Information We Collect

We may collect the following categories of information:

- Contact form submissions: name, email address, and message content when you contact us via the website.
- Usage data: anonymised analytics data (e.g. page views, browser type) to help us improve the website.
- Technical data: IP address, referring URL, and similar data collected automatically by our hosting provider.

We do not collect any data through the Peerix Library itself — it runs entirely in your application.

## 3. How We Use Your Information

We use the information we collect to:

- Respond to your enquiries and provide support.
- Improve the website and our Services.
- Comply with legal obligations.

We do not sell, rent, or share your personal data with third parties for marketing purposes.

## 4. Legal Basis for Processing

Where applicable (e.g. under UK GDPR or EU GDPR), we process your personal data on the following legal bases:

- Legitimate interests — to respond to enquiries and improve our Services.
- Contract performance — to fulfil license agreements.
- Legal obligation — where required by law.

## 5. Data Retention

We retain personal data only for as long as necessary to fulfil the purposes described in this Policy, or as required by law. Contact form enquiries are typically retained for up to 24 months.

## 6. Cookies

Our website may use cookies or similar technologies for analytics purposes. You may disable cookies in your browser settings, though this may affect the functionality of the website.

## 7. Third-Party Services

We may use third-party services (e.g. hosting providers, analytics tools) that process data on our behalf. These providers are contractually required to handle data securely and in accordance with applicable law.

## 8. Your Rights

Depending on your location, you may have the right to:

- Access the personal data we hold about you.
- Request correction of inaccurate data.
- Request deletion of your data.
- Object to or restrict our processing of your data.
- Lodge a complaint with a supervisory authority (e.g. the ICO in the UK).

To exercise any of these rights, please contact us via the [Contact page](https://peerix.dev/contact).

## 9. Security

We take reasonable technical and organisational measures to protect your personal data. However, no method of transmission over the internet is completely secure, and we cannot guarantee absolute security.

## 10. Changes to This Policy

We may update this Privacy Policy from time to time. We will indicate the date of the latest revision at the top of this document. Continued use of the Services after changes are posted constitutes acceptance of the revised Policy.

## 11. Contact

If you have any questions about this Privacy Policy, please contact us via the [Contact page](https://peerix.dev/contact) on the Peerix website.

# Terms of Service
URL: https://peerix.dev/terms-of-service/
Published: 2026-05-23

_Effective date: May 23, 2026_

## 1. Acceptance of Terms

By accessing or using Peerix (the "Library"), its documentation, or any associated services (collectively, the "Services"), you agree to be bound by these Terms of Service. If you do not agree, you must not use the Services.

## 2. License

Peerix is licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

## 3. Permitted Use

You may use the Services only for lawful purposes. You must not:

- Use the Services in any way that violates applicable law or regulation.
- Attempt to gain unauthorised access to any part of the Services.
- Distribute malicious code or use the Library to facilitate harm.
- Misrepresent the origin of the Library or remove any license notices.

## 4. Intellectual Property

All content, trademarks, and other intellectual property related to Peerix remain the property of the Peerix project and its contributors. Nothing in these Terms grants you any right to use the Peerix name, logo, or branding without prior written permission.

## 5. Third-Party Services

The Services may integrate with or reference third-party platforms (e.g. cloud hosting providers, signaling servers). We are not responsible for the terms, availability, or conduct of any third-party service.

## 6. Disclaimer of Warranties

The Library and Services are provided "as is" and "as available", without warranty of any kind. We make no warranties, express or implied, including but not limited to merchantability, fitness for a particular purpose, or non-infringement.

## 7. Limitation of Liability

To the fullest extent permitted by law, Peerix and its contributors shall not be liable for any indirect, incidental, special, consequential, or punitive damages arising from your use of, or inability to use, the Services.

## 8. Changes to These Terms

We may update these Terms from time to time. Continued use of the Services after changes are posted constitutes acceptance of the revised Terms. We will indicate the date of the latest revision at the top of this document.

## 9. Governing Law

These Terms are governed by the laws of TBC. Any disputes shall be subject to the exclusive jurisdiction of the courts of TBC.

## 10. Contact

For questions about these Terms, please contact us via the [Contact page](https://peerix.dev/contact) on the Peerix website.

# About
URL: https://peerix.dev/about/

Peerix is a compact JavaScript/TypeScript library that removes the friction from building WebRTC peer-to-peer applications. It abstracts signaling, connection lifecycle, and media/data multiplexing so developers can focus on features instead of plumbing.

## Core idea

Peerix provides a simple yet powerful abstraction of WebRTC with transport-agnostic architecture and extends its capabilities with add-ons, all while keeping the API minimal.

## What it solves

- **Signaling boilerplate:** pluggable drivers (BroadcastChannel, NATS, WebSockets, or your own) make discovery and messaging straightforward.
- **Serverless architecture:** no server-side code required, NATS can be used for signaling directly in the browser.
- **Room and state management:** built-in support for rooms, peer metadata, and labeling of streams and channels.
- **Connection complexity:** automatic lifecycle and negotiation handling for updating streams and channels.
- **Multi-track & data multiplexing:** share multiple streams and open many data channels over the same connection.
- **Developer experience:** built with TypeScript for better DX and type safety, with zero dependencies to minimize security risks and simplify deployment.

## Key features

- Easy-to-use API for peer connections, media streams, and data channels
- Transport-agnostic design that allows you to choose the best signaling method, including custom implementations
- Supports E2E encryption and compression for all signaling data
- Supports serverless architecture (no server-side code required)
- Room and state management features to simplify building complex applications
- Multiplexing multiple media streams and data channels over a single connection per peer
- Extensible architecture that allows you to build custom features and integrations
- Cross-browser compatibility with support for all modern browsers
- TypeScript support for a better developer experience and type safety
- Well-documented codebase with comprehensive examples and the API reference
- Automatically tested and optimized for performance and reliability
- Zero dependencies to reduce security risks
- Open-source, actively maintained project

## Who it's for

Developers building real-time apps such as chat, conferencing, file sharing and collaborative tools, as well as gaming apps, who want to avoid reimplementing signaling and connection plumbing, and who need a flexible, extensible foundation for peer-to-peer communication in the browser.

## When not to use it

If you need server-side media processing or routing. Peerix is not an SFU or MCU.

## License

Peerix is licensed under the Apache License, Version 2.0. See the [LICENSE](http://www.apache.org/licenses/LICENSE-2.0) file for details.

## Next

See the documentation for full guides, signaling details, and add-ons:

# Archives
URL: https://peerix.dev/archives/


# Contact us
URL: https://peerix.dev/contact/

If you have any questions, please don't hesitate to contact us. We are here to help you with any issues or inquiries you may have.

# Documentation
URL: https://peerix.dev/docs/

👋 Hello! Welcome to the Peerix documentation!

## What is Peerix?

Peerix is a powerful and flexible peer-to-peer communication library that enables developers to build real-time applications with ease. It provides a simple and intuitive API for creating peer connections, managing media streams and data channels, and handling signaling, allowing you to focus on building your application without worrying about the underlying complexities of WebRTC communication.

## Key Features

- Easy-to-use API for peer connections, media streams, and data channels
- Transport-agnostic design that allows you to choose the best signaling method, including custom implementations
- Supports serverless architecture (no server-side code required)
- Room and state management features to simplify building complex applications
- Multiplexing multiple media streams and data channels over a single connection per peer
- Extensible architecture that allows you to build custom features and integrations
- Cross-browser compatibility with support for all modern browsers
- TypeScript support for a better developer experience and type safety
- Well-documented codebase with comprehensive examples and the API reference
- Automatically tested and optimized for performance and reliability
- Zero dependencies to reduce security risks
- Open-source, actively maintained project

## When to Choose Peerix?

Peerix is designed to be a versatile and developer-friendly library that abstracts away the complexities of peer-to-peer communication. Whether you're building a simple chat application, a collaborative workspace, or a complex real-time game, Peerix provides the tools and flexibility you need to create robust and scalable P2P applications. With its transport-agnostic design, you can choose the signaling method that best fits your application's needs, whether it's a built-in driver or a custom implementation. Peerix's focus on simplicity, extensibility, and performance makes it an excellent choice for developers looking to build real-time applications with WebRTC.

If your application handles small or medium-sized groups of peers and does not require server-side media processing, Peerix is an ideal choice for your project.

## When Not to Choose Peerix?

Peerix is not an SFU or MCU, and it does not provide server-side media processing or routing capabilities. Instead, it focuses on enabling direct peer-to-peer communication between clients, allowing you to build applications that leverage the full potential of WebRTC without the need for a central media server.

## Questions or Feedback?

Have a question or feedback? Feel free to [open an issue](https://github.com/peerix-dev/peerix/issues)!

Discuss ideas and ask questions in [Discussions](https://github.com/peerix-dev/peerix/discussions)!

## Next

Dive right into the following section to get started:


# Add-ons
URL: https://peerix.dev/docs/addons/

The Add-ons section contains documentation for additional features that can be used with Peerix core to enhance your application. These add-ons provide extra functionality such as recording, synchronization, and more, allowing you to customize and extend the capabilities of your Peerix-based application.

Explore the following list of add-ons to see how you can integrate them into your project:


# Getting Started
URL: https://peerix.dev/docs/getting-started/

Peerix is a focused JavaScript library that makes building WebRTC peer-to-peer apps simple and reliable. Peerix uses WebRTC for peer-to-peer communication and relies on a signaling mechanism to facilitate peer discovery and connection management. The library abstracts away the complexities of WebRTC and provides a simple API for developers to create real-time peer-to-peer applications with media streaming and data sharing capabilities.

The following diagram provides a high-level overview of the Peerix architecture and its components:

```mermaid
graph TD
  PX{{Peerix}} --> SD(Signaling Drivers)
  SD --> SS[Signaling Servers]
  PX --> ICE[STUN/TURN Servers]
  PX --> PC(Peers)
  PC --> LCE(Lifecycle Events)
  PC --> MS(Media Streams)
  PC --> DC(Data Channels)
  PX --> ADD(Add-ons)
```

Peerix consists of several key components:

- **Peers**: The core component that manages the peer-to-peer connection, including media streams and data channels.
- **Lifecycle Events**: Handles events related to peer connections, such as joining/leaving rooms and connection state changes.
- **Media Streams**: Handles audio and video streams between peers.
- **Data Channels**: Manages arbitrary data communication between peers.
- **Signaling Drivers**: Abstracts the signaling process, allowing you to choose or implement your own signaling method.
- **Signaling Servers**: Responsible for peer discovery and message exchange between peers.
- **STUN/TURN Servers**: Used for NAT traversal and media relay when direct peer-to-peer communication is not possible.
- **Add-ons**: Extend the functionality of Peerix with additional features or integrations.

## Installation

Install the Peerix library using your preferred package manager:

```sh
npm install peerix
```

```sh
pnpm add peerix
```

```sh
yarn add peerix
```

## Using CDN

If you prefer to use a CDN without installing it as a package, you can include the library directly in your HTML file using a script tag. This allows you to quickly get started with Peerix without needing to set up a build process or package manager.

### ES Modules

If you want to use the ESM version of Peerix, you can import the library as follows:

```html
<script type="module">
  import { Peer, BroadcastChannelDriver } from 'https://esm.sh/peerix';
</script>
```

Alternatively, you can use an import map to simplify the imports in your JavaScript code:

```html
<script type="importmap">
  {
    "imports": {
      "peerix": "https://esm.sh/peerix@latest"
    }
  }
</script>
<script type="module">
  import { Peer, BroadcastChannelDriver } from 'peerix';
</script>
```

### UMD modules

If you prefer to use the UMD version of Peerix for broader compatibility, you can include it as follows:

```html
<script src="https://unpkg.com/peerix"></script>
<script>
  const { Peer, BroadcastChannelDriver } = window.peerix;
</script>
```

## Basic Usage

Use the Peerix library in your JavaScript or TypeScript project to create peer-to-peer applications. Below is a simple example that demonstrates how to set up a Peer instance with a specific signaling driver, open a data channel, and exchange messages between peers:

```js
import { Peer, BroadcastChannelDriver } from 'peerix';

// create a signaling driver
const driver = new BroadcastChannelDriver();

// create the Peer instance
const peer = new Peer({ driver });

// listen for open channel event
peer.on('channel:open', (e) => {
  const { remote, label } = e;
  const { name } = remote.metadata;
  remote.send(`Hello, ${name}!`, { label });
});

// listen for incoming messages
peer.on('channel:message', (e) => {
  const { remote, data } = e;
  const { name } = remote.metadata;
  console.log(`Received message from ${name}:`, data);
});

// open a data channel
peer.open({ label: 'chat' });

// join a room
peer.join({ room: 'room-id', metadata: { name: 'Guest' } });
```

You can run the above code in multiple browser tabs to see the peer-to-peer communication in action. Each tab will represent a peer that can connect to the same room and exchange messages via WebRTC data channel.

## Sandbox

Try out the Peerix library in the sandbox environment below. You can open multiple tabs with the sandbox in the same browser to simulate multiple peers and see how they interact with each other using Peerix.

See the project [Peerix Sandbox](https://v48.livecodes.io/?x=id/ywc4thzv7ad&mode=result) on [LiveCodes](https://livecodes.io).


# Peers
URL: https://peerix.dev/docs/peers/

Peerix is designed with a modular and extensible architecture that abstracts away the complexities of peer-to-peer communication while providing a flexible and powerful API for developers. The core of Peerix is built around the `Peer` class, which manages peer connections, media streams, data channels, and signaling. The library also includes various built-in signaling drivers and supports custom implementations, allowing you to choose the best signaling method for your application. Peerix's architecture is transport-agnostic, meaning it can work with any signaling method. This design allows developers to focus on building their applications without worrying about the underlying complexities of WebRTC communication. Additionally, Peerix provides an event-driven architecture that allows you to handle various events in the peer connection lifecycle, making it easier to manage peer interactions and build real-time applications. The library also supports add-ons, which allow you to extend its functionality and integrate with other services or features as needed. Overall, Peerix's architecture is designed to be simple, extensible, and performant, enabling developers to build robust and scalable peer-to-peer applications with ease.

Explore the following sections to learn how to use Peerix's core features:


# Server Infrastructure
URL: https://peerix.dev/docs/servers/

Peerix was designed to be decentralized: peers prefer direct peer-to-peer media connections and do not require a central media server. However, to discover peers and establish those connections, Peerix relies on two kinds of server infrastructure:

- A signaling server to exchange session setup messages between peers.
- TURN/STUN servers to improve connectivity when direct peer-to-peer connections are blocked or limited by NATs and firewalls.

```mermaid
graph TD
  PX[Peerix] --> SD[Signaling Driver]
  SD --> SS[Signaling Server]
  PX --> TURN[TURN/STUN Servers]
```

## Signaling

A signaling server is required for peers to find and communicate the session information needed to establish a direct connection (SDP, ICE candidates, etc.). Signaling does not carry media — it only exchanges metadata used to negotiate peer-to-peer sessions.

## TURN and STUN

STUN helps a client discover its public-facing IP and the NAT type it sits behind. TURN provides a relay for media when two peers cannot connect directly. In practice:

- Use STUN to gather public addresses and speed up NAT traversal where possible.
- Use TURN as a fallback relay to guarantee connectivity in restrictive networks (corporate proxies, symmetric NATs, strict firewalls).

## Recommended setup

- Run or use a lightweight signaling server (there are many open-source drivers and hosted options).
- Deploy a TURN server (or use a trusted hosted TURN provider) if you need reliable connectivity across restrictive networks.

## Deployment options

Choose one of the following approaches depending on your needs and operational preferences:


# Signaling Drivers
URL: https://peerix.dev/docs/drivers/

Signaling is a crucial part of any WebRTC application, as it enables peers to discover each other and exchange the necessary information to establish a peer-to-peer connection. Peerix provides a flexible signaling mechanism that allows you to choose from several built-in drivers or implement your own custom driver.

Peerix's transport-agnostic design means that you can use any signaling method that suits your application's needs, whether it's a simple in-memory driver for testing, a browser-based communication channel, or a more robust messaging system for production use. This flexibility allows you to build applications that can scale and adapt to different environments and requirements without being tied to a specific signaling implementation.

Peerix uses several techniques to secure and minimize the number and size of signaling messages required to establish and maintain peer connections, such as negotiating multiple media streams and data channels:

- Each peer connection negotiates a data channel for signaling after the initial connection is established, eliminating the need for a signaling server for the lifetime of the connection.
- Uses a binary format instead of JSON for signaling messages, minimizing message overhead.
- Reduces the frequency of candidate exchanges and the number of signaling messages by debouncing ICE candidates.
- Uses compression to reduce the size of signaling messages, further lowering overhead and load on the signaling server.
- Provides built-in namespace hashing and end-to-end encryption (E2EE) for signaling messages to protect sensitive information during transmission.

As a result, Peerix manages peer connections and media streams with minimal signaling overhead, protecting private data and making it a strong choice for real-time applications that require low latency and high performance.

```mermaid
sequenceDiagram
  Peer A -->> Peer B: broadcast announce
  Peer B ->> Peer A: invoke
  Peer A ->> Peer B: SDP offer
  Peer B ->> Peer A: SDP answer
  Peer B <<->> Peer A: ICE candidates
```

The diagram shows a typical signaling flow between two peers in a Peerix application. This internal process runs automatically during negotiation and connection management. The driver you choose will handle signaling messages so peers can discover each other and establish connections without requiring you to manage the signaling logic directly.

Here is a table comparing raw, compressed, and encrypted signaling:

| Signaling Type                   | Sent Size (bytes) | Overhead (%) |
| -------------------------------- | ----------------- | ------------ |
| Raw Signaling                    | 1468              | 0%           |
| Encrypted Signaling              | 1551              | +5%          |
| Compressed Signaling             | 806               | -45%         |
| Compressed & Encrypted Signaling | 891               | -40%         |

Connecting two peers requires about **4 messages** per peer (8 in total), which amounts to approximately **1 KB** of data with compression and encryption enabled. This includes the initial announce and invoke messages, the SDP offer/answer, and the ICE candidates exchanged between the peers.

## Built-in Signaling Drivers

Peerix supports multiple signaling drivers for peer discovery and connection management. Choose the driver that best fits your application's needs:

To use a built-in signaling driver, import the driver and create an instance of the `Peer` class with it:

```js
import { Peer, BroadcastChannelDriver } from 'peerix';

// create the driver instance
const driver = new BroadcastChannelDriver();

// use the driver
const peer = new Peer({ driver });
```

## Custom Signaling Drivers

You can also implement your own custom signaling driver by adhering to the following interface:

```js
import { Driver } from 'peerix';

class MyDriver extends Driver {
  async subscribe(namespace, handler) {
    // implement subscription logic for the given namespace and handler
  }

  async unsubscribe(namespace, handler) {
    // implement unsubscription logic for the given namespace and handler
  }

  async dispatch(namespace, message) {
    // implement dispatch logic for the given namespace and message
  }
}
```

This interface lets you integrate Peerix with any signaling transport you prefer, such as WebSocket.


# Starter Kits
URL: https://peerix.dev/docs/kits/

Explore a variety of ready-made applications that demonstrate how to use Peerix in different scenarios, including real-time chat applications, collaborative whiteboards, multiplayer games, and more. These applications provide practical implementations of Peerix's features and can serve as a starting point for your own projects.

More starter kits will be added in the future, so stay tuned for updates! If you are interested in ready-made applications, feel free [to request us](https://peerix.dev/contact) to create a starter kit for a specific use case or application type.


# Troubleshooting
URL: https://peerix.dev/docs/troubleshooting/

This section provides troubleshooting tips and solutions for common issues you may encounter when using Peerix. If you are experiencing problems with your WebRTC application, check the following guides to help identify and resolve the issue.

## Debugging

Peerix provides built-in verbose logging that can help you diagnose and troubleshoot issues with your WebRTC application. You can enable debug logging to get detailed information about the internal workings of the library, including signaling messages, connection states, and errors.

Peerix uses a popular logging approach. It displays debug logs in the browser console for the desired module names or patterns. This allows you to selectively enable debug logging for specific Peerix modules or namespaces, making it easier to focus on relevant information when troubleshooting.

To enable debug logging, set the `debug` item in `localStorage` to a comma-separated list of module names or patterns that you want to log. For example:

```js
// enable debug logging for all modules
localStorage.debug = '*';
```

Possible patterns:

- `'*'`: enable debug logging for all modules including third-party modules
- `'peerix:*'`: enable debug logging for all Peerix modules
- `'peerix:peer:*'`: enable debug logging for all subnamespaces under `peerix:peer`
- `'-peerix:peer:*'`: disable debug logging for all subnamespaces under `peerix:peer`
- `'peerix:*,-peerix:peer:*'`: enable debug logging for all subnamespaces under `peerix` but disable it for all subnamespaces under `peerix:peer`

With debug logging enabled, you can inspect the logs in the browser console to identify any issues with your WebRTC application. Look for error messages, connection state changes, and signaling messages to help diagnose the problem.

## Reporting Issues

If you encounter a bug or issue with Peerix that you cannot resolve, please report it to the Peerix team. You can create a new issue on the [Peerix GitHub repository](https://github.com/peerix-dev/peerix/issues).
When reporting an issue, please provide as much detail as possible, including:

- A clear description of the problem you are experiencing
- Steps to reproduce the issue
- The expected behavior and the actual behavior you are seeing
- Any relevant error messages or logs from the browser console
- The version of Peerix you are using
- The browser and operating system you are using
- A minimal code example or a link to a repository that demonstrates the issue (if possible)

This information will help the Peerix team understand and investigate the issue more effectively, and work towards providing a solution in a timely manner.


# BroadcastChannel Driver
URL: https://peerix.dev/docs/drivers/broadcast-channel/

The BroadcastChannel Driver is a signaling driver that utilizes the [BroadcastChannel API](https://developer.mozilla.org/docs/Web/API/BroadcastChannel) to enable communication between different tabs or windows of the same browser. This driver is ideal for scenarios where you want to establish peer-to-peer connections between multiple tabs or windows without the need for a server or external signaling mechanism.

## Usage

To use the BroadcastChannel Driver, simply import it from the Peerix library and create an instance:

```js
import { BroadcastChannelDriver } from 'peerix';

// create a new BroadcastChannel driver instance with a channel name
const driver = new BroadcastChannelDriver('peerix');
```

In this example, we create a new instance of the BroadcastChannel Driver and specify a channel name (`'peerix'`) that will be used for communication between tabs. All tabs that create a BroadcastChannel Driver instance with the same channel name will be able to discover each other and exchange messages.


# Centrifuge Driver
URL: https://peerix.dev/docs/drivers/centrifuge/

The Centrifuge Driver is a signaling driver that uses [Centrifugo](https://centrifugal.dev/) as the real-time transport layer between peers. It is a good choice when you want reliable pub/sub signaling with reconnect support, and when you need a production-ready server designed for high fan-out messaging.

Peerix uses this driver to exchange signaling messages via channels on your Centrifugo backend. Peers that connect to the same Centrifugo deployment and join the same namespaces can discover each other and establish direct peer-to-peer connections.

## Usage

To use the Centrifuge Driver, import the driver from Peerix, create a Centrifuge client, connect it to your server, and then pass that client instance to the driver.

```js
import { CentrifugeDriver } from 'peerix';
import { Centrifuge } from 'centrifuge';

// connect to a Centrifuge server
const centrifuge = new Centrifuge('ws://localhost:8000/connection/websocket');
centrifuge.connect();

// create a Centrifuge driver instance
const driver = new CentrifugeDriver({ centrifuge });
```

In this setup, the Centrifuge client handles transport-level concerns (connection lifecycle, reconnects, subscriptions), while the Peerix driver handles signaling semantics.

You need to have a Centrifugo server running and properly configured to use this driver. See the [self-hosting guide](https://peerix.dev/docs/servers/self-hosting/#centrifugo-server) for more information.

## Installation

Install the `centrifuge` browser client package in your project.

```sh
npm install centrifuge
```

```sh
pnpm add centrifuge
```

```sh
yarn add centrifuge
```


# Cloud Hosting
URL: https://peerix.dev/docs/servers/cloud-hosting/

## Managed Servers for Signaling

These providers offer managed signaling or real-time messaging layers suitable for exchanging session descriptions, ICE candidates, presence, and lightweight control messages between peers. They typically provide WebSocket or HTTP-based APIs and handle scaling, reliability, and security for you. When choosing a provider, consider factors such as latency, geographic coverage, pricing, and support for your preferred signaling protocol.

Peerix protects all data sent through the signaling layer with built-in encryption and namespace hashing, so you can use any provider that meets your requirements without worrying about data security. For production applications, we recommend choosing a provider that supports secure connections (e.g., `wss://` or `https://`) and offers authentication mechanisms to protect your signaling messages from unauthorized access.

### NATS

The [NATS](https://nats.io/) messaging system is a popular choice for signaling due to its high performance, scalability, and support for pub/sub messaging patterns.

NATS services suitable for signaling:

- [Synadia Cloud](https://www.synadia.com/cloud): a fully managed NATS service with global coverage and support for WebSocket connections.

Free public NATS endpoints for development:

- Official demo server: `wss://demo.nats.io:8443`

### MQTT Brokers

[MQTT](https://mqtt.org/) is a lightweight messaging protocol designed for low-bandwidth, high-latency networks.

MQTT brokers suitable for signaling:

- [HiveMQ](https://www.hivemq.com/mqtt/public-mqtt-broker/): free public MQTT broker with WebSocket support.
- [EMQX](https://www.emqx.com/cloud): managed MQTT service with a free tier and WebSocket support.

Free public MQTT endpoints for development:

- EMQX: `wss://broker.emqx.io:8084/mqtt`
- HiveMQ: `wss://broker.hivemq.com:8084/mqtt`

### Mercure Hubs

[Mercure](https://mercure.rocks/) is a real-time hub for publishing and subscribing to updates, built on HTTP and Server-Sent Events (SSE).

Mercure services suitable for signaling:

- [Mercure Cloud](https://mercure.rocks/)

Free public Mercure endpoints for development:

- Mercure: `https://demo.mercure.rocks/.well-known/mercure`

### Other Providers

Other real-time messaging providers that can be used for signaling include:

- [Centrifugo](https://centrifugal.dev/): a real-time messaging server with WebSocket support and alternative transport options.
- [Supabase Realtime](https://supabase.com/realtime): a real-time database and messaging service built on top of PostgreSQL.

## Cloud TURN Servers

If you do not want to self-host TURN, start with a managed provider that offers a free tier. These services provide TURN servers that can relay media when direct peer-to-peer connections are not possible due to network restrictions. When choosing a provider, consider factors such as geographic coverage, reliability, pricing, and support for short-lived credentials.

### Free TURN Providers

| Provider                                                        | Free Tier | Best For                                | Notes                                                                                                                        |
| --------------------------------------------------------------- | --------- | --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| [Cloudflare Realtime TURN](https://dash.cloudflare.com/)        | Yes       | Teams already using Cloudflare services | Strong global network and ecosystem integration; check current limits and product requirements in your Cloudflare dashboard. |
| [ExpressTURN](https://www.expressturn.com/)                     | Yes       | Fast setup for small pilots             | Easy to evaluate and deploy; always confirm reliability, limits, and retention policies before production.                   |
| [turnix.io](https://turnix.io/)                                 | Yes       | API-driven deployments                  | Focuses on programmable infrastructure; verify free-tier quotas and geographic coverage for your users.                      |
| [Metered (Open Relay)](https://www.metered.ca/tools/openrelay/) | Yes       | Quick testing and prototypes            | Simple onboarding and useful tools; free access and limits may differ by region and plan.                                    |

### How to Choose

For production workloads, compare providers using the criteria below rather than choosing solely by price:

- Coverage and latency for the regions where your peers connect.
- Quotas and rate limits for free plans.
- Authentication model (static credentials vs. time-limited credentials).
- Support for UDP and TCP/TLS relay paths.
- Reliability guarantees, logging policy, and compliance requirements.
- Pricing predictability when you outgrow the free tier.

### Recommendation

- Development and demos: any provider with a free tier is usually fine.
- Staging and pre-production: choose a provider that supports short-lived credentials and has coverage near your test users.
- Production: use paid managed TURN or self-host for full control and predictable behavior.

### Verify Before Shipping

Regardless of provider, validate your TURN setup before release:

1. Open the [Trickle ICE WebRTC](https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/) test page.
2. Add your TURN endpoint and credentials.
3. Gather candidates and confirm at least one `relay` candidate is returned.
4. Repeat this test from different networks (home, office, mobile hotspot, and VPN).

If you cannot consistently obtain `relay` candidates, review credentials, firewall rules, and provider limits before moving forward.


# Custom Add-on
URL: https://peerix.dev/docs/addons/custom-addon/

You can create your own custom add-ons by extending the `Addon` class and implementing the desired functionality. This allows you to tailor the behavior of Peerix to fit the specific needs of your application. For example, you could create an add-on that provides a custom data synchronization mechanism, or one that integrates with a third-party service for additional features.

```js
class CustomAddon {
  constructor(options) {
    // initialize your add-on with the provided options
  }
  attach(peer) {
    // handle attaching the add-on to the peer instance
  }
  detach(peer) {
    // handle detaching the add-on from the peer instance
  }
}

// create the add-on instance
const addon = new CustomAddon({
  /* options */
});
// attach the add-on to the peer instance
peer.attach(addon);
// later, if you want to detach the add-on from the peer instance
peer.detach(addon);
```


# Custom Driver
URL: https://peerix.dev/docs/drivers/custom/

Sometimes, the built-in signaling drivers may not fit your specific use case or requirements. In such cases, you can implement your own custom signaling driver by adhering to the following interface:

```js
import { Driver } from 'peerix';

class MyDriver extends Driver {
  async subscribe(namespace, handler) {
    // implement subscription logic for the given namespace and handler
  }
  async unsubscribe(namespace, handler) {
    // implement unsubscription logic for the given namespace and handler
  }
  async dispatch(namespace, message) {
    // implement dispatch logic for the given namespace and message
  }
}
```

This driver interface allows you to integrate Peerix with any signaling mechanism you prefer, such as WebSocket transport.

```js
const driver = new CustomDriver();
```

To better illustrate how to implement a custom signaling driver, here is an example of a minimal in-memory driver that can be used for testing purposes:

```js
// Minimal in-memory signaling driver
class MemoryDriver extends Driver {
  constructor() {
    super();
    this.handlers = new Map();
  }
  subscribe(namespace, handler) {
    const k = namespace.join(':');
    if (!this.handlers.has(k)) {
      this.handlers.set(k, new Set());
    }
    this.handlers.get(k).add(handler);
  }
  unsubscribe(namespace, handler) {
    const k = namespace.join(':');
    this.handlers.get(k)?.delete(handler);
  }
  dispatch(namespace, message) {
    const k = namespace.join(':');
    if (!this.handlers.has(k)) return;
    for (const handler of this.handlers.get(k)) {
      setTimeout(() => handler(message), 0);
    }
  }
}
```


# Data Channels
URL: https://peerix.dev/docs/peers/data-channels/

Data channel is a powerful feature of WebRTC that allows you to exchange arbitrary data between peers in a room. In Peerix, you can open data channels to send messages, files, or any other type of data that does not fit into media streams.

```mermaid
sequenceDiagram
    autonumber
    Note over Peer A, Peer B: Open a data channel
    Peer B ->> Peer A: Is polite?<br>signaling DC: channel + options
    Peer A ->> Peer A: Is impolite?<br>Create the data channel
    Peer A ->> Peer B: channel event: new
    Note over Peer A, Peer B: Channel is created
```

## Opening Data Channels

You can open data channels to exchange arbitrary data with other peers in the room using the `open` method:

```js
// listen for data channel open event
peer.on('channel:open', (e) => {
  const { remote, label } = e;
  console.log('Channel was opened with peer:', remote.id, 'label:', label);
});

// open a data channel
peer.open({ label: 'chat' });
```

Peerix allows you to open multiple data channels with different labels that should be unique, and you can also specify options for each channel, such as the ordered or unordered delivery of messages and other channel-specific settings.

## Closing Data Channels

To stop exchanging data over a data channel, you can close it specifically by its label:

```js
// listen for data channel close event
peer.on('channel:close', (e) => {
  const { remote, label } = e;
  console.log('Channel was closed with peer:', remote.id, 'label:', label);
});

// close a data channel with a specific label
peer.close({ label: 'chat' });
```

> [!NOTE]
> You can open a data channel before or after connecting to a room, and the library will handle the sharing of the channel as needed with other peers in the room.

## Sending and Receiving Messages

To send a message to all connected peers over open data channels, you can use the `send` method with the message and optionally a channel label:

```js
// send a message to all connected peers and all open channels
peer.send('Hello, peers!');
// or with the channel label
peer.send('Hello, peers!', { label: 'chat' });
```

To listen for incoming messages on a data channel, you can use the `channel:message` event:

```js
// listen for incoming messages on a specific channel
peer.on('channel:message', (e) => {
  const { remote, label, data } = e;
  console.log('Message from:', remote.id, 'label:', label, 'data:', data);
});
```

## Selective Operations

Peerix allows you to open, close, send messages and listen for events on specific peer connections, rather than on all of them in the room.

To send a message to a specific peer over a data channel, you can get the remote peer instance and use the `send` method with the message:

```js
const remote = peer.connections.get('peer-id');
if (remote) {
  remote.send('Hello, peer!', { label: 'chat' });
}
```

The same way you can use the `open` and `close` methods on the remote peer instance and listen for events with the `remote.on` method to handle data channels with specific peers in the room.

Please note that these operations continue to run while the peer connection is established. If the connection is closed, you will need to open the data channels again to exchange data with that peer, even if they are reconnected later.


# Media Streams
URL: https://peerix.dev/docs/peers/media-streams/

Media Stream is a fundamental part of WebRTC applications, allowing you to share audio and video content between peers. In Peerix, you can share media streams with connected peers and subscribe to streams shared by others.

```mermaid
sequenceDiagram
    autonumber
    Note over Peer A, Peer B: Share media streams
    Peer A ->> Peer A: Add transceiver
    Peer A ->> Peer B: signaling DC: offer
    Peer B ->> Peer B: Add transceiver
    Peer B ->> Peer A: signaling DC: answer
    Peer B -x Peer A: signaling DC: offer (collision)
    Note over Peer A, Peer B: Streams shared
```

## Sharing Streams

You can share media streams with the room using the `share` method:

```js
// get a media stream from the user's camera and microphone
const cameraStream = await navigator.mediaDevices.getUserMedia({
  video: true,
  audio: true,
});

// share the camera stream with the room
peer.share(cameraStream);
```

This allows other peers in the room to subscribe to your media streams and view or listen to them.

You can share multiple streams using the same `share` method:

```js
// get another media stream from the user's screen
const screenStream = await navigator.mediaDevices.getDisplayMedia({
  video: true,
});

// share the screen stream with the room
peer.share(screenStream);
```

You can also provide a label for each stream to manage them more easily and then unshare or update them later:

```js
// get a media stream from the user's camera and microphone
const cameraStream = await navigator.mediaDevices.getUserMedia({
  video: true,
  audio: true,
});

// share the stream with a specific label and mark it as managed
peer.share({ label: 'camera', stream: cameraStream, managed: true });

// get another media stream from the user's microphone only
const newCameraStream = await navigator.mediaDevices.getUserMedia({
  video: false,
  audio: true,
});

// update the existing stream with new tracks, keeping the same label,
// previously shared stream will be stopped automatically since it is marked as managed
peer.share({ label: 'camera', stream: newCameraStream, managed: true });
```

Managed streams are automatically stopped when they are unshared or updated, which is useful for handling media streams tied to specific user actions or states. For example, a camera stream should be stopped when it is unshared or when the user switches to a different camera.

> [!NOTE]
> When you share a media stream, Peerix will automatically negotiate the connection with all connected peers in the room and share the stream with them. This means that you can share a stream before or after joining a room, and the library will handle the sharing of the stream as needed.

You can also set optional sender parameters for shared streams in order to control the bitrate, frame rate, and priority of the audio and video track encodings:

```js
// share the camera stream with a bitrate
peer.share({
  label: 'camera',
  stream: cameraStream,
  audioParameters: {
    maxBitrate: 16000, // 16 kbps for audio tracks
  },
  videoParameters: {
    maxBitrate: 64000, // 64 kbps for video tracks
  },
});
```

## Unsharing Streams

To stop sharing a media stream with other peers, you can unshare it using the `unshare` method:

```js
// unshare the specific stream
peer.unshare(cameraStream);
// or unshare the stream with the specified label
peer.unshare('camera');
// or the same with label parameter
peer.unshare({ label: 'camera' });
```

> [!NOTE]
> When a peer unshares a track from a stream, Peerix will automatically stop sharing that track with all connected peers in the room. If the stream has no more tracks after unsharing, the library will also stop sharing the entire stream.

## Subscribing to Stream Changes

To receive media streams shared by other peers or watch for changes in existing streams, you can listen for the `track:add` and `track:remove` events emitted by the `Peer` instance:

```js
// listen for peer adding a track to a stream
peer.on('track:add', (e) => {
  const { remote, stream, track, label } = e;
  console.log('Added new track:', track.id, 'label:', label);
});

// listen for peer removing a track from a stream
peer.on('track:remove', (e) => {
  const { remote, stream, track, label } = e;
  console.log('Removed track:', track.id, 'label:', label);
});
```

> [!TIP]
> You can use these events to update your application's UI. For example, you can show or hide video elements based on the presence of video tracks in the shared streams.

You can also listen for the `stream:add` and `stream:remove` events to track when new streams are shared or unshared by peers:

```js
// listen for peer adding a new stream
peer.on('stream:add', (e) => {
  const { remote, stream, label } = e;
  console.log('Added new stream:', stream.id, 'label:', label);
});

// listen for peer removing a stream
peer.on('stream:remove', (e) => {
  const { remote, stream, label } = e;
  console.log('Removed stream:', stream.id, 'label:', label);
});
```

## Selective Operations

Peerix allows you to share, unshare and listen for events on specific peer connections, rather than on all of them in the room.

To share a stream with a specific peer, you can get the remote peer instance and use the `share` method with the stream:

```js
const remote = peer.connections.get('peer-id');
if (remote) {
  remote.share({ label: 'camera', stream });
}
```

The same way you can use the `unshare` method on the remote peer instance and listen for events with the `remote.on` method to handle media streams with specific peers in the room.

Please note that these operations continue to run while the peer connection is established. If the connection is closed, you will need to share the streams again to share them with that peer, even if they are reconnected later.


# Memory Driver
URL: https://peerix.dev/docs/drivers/memory/

The Memory Driver is a simple in-memory signaling driver that allows you to exchange messages between peers within the same JavaScript environment. This driver is useful for testing and development purposes, as it does not require any external dependencies or network communication.

## Usage

To use the Memory Driver, simply import it from the Peerix library and create an instance:

```js
import { MemoryDriver } from 'peerix';

// create a new Memory driver instance
const driver = new MemoryDriver();
```

You can then use this driver instance to create several `Peer` instances and establish connections between them. Since the Memory Driver operates within the same JavaScript environment, all peers that share the same driver instance will be able to discover each other and exchange messages. This makes it ideal for testing and development scenarios where you want to simulate peer-to-peer communication without the need for a real signaling server or network communication.


# MQTT Driver
URL: https://peerix.dev/docs/drivers/mqtt/

The MQTT Driver is a signaling driver that uses [MQTT](https://mqtt.org/) as the transport layer to exchange signaling messages between peers via a broker such as [Mosquitto](https://mosquitto.org/). It is a good choice when you want lightweight pub/sub signaling, broad protocol support, and compatibility with existing IoT or messaging infrastructure.

Peerix uses this driver to publish and subscribe to signaling messages in namespaces mapped to MQTT topics. Peers connected to the same broker and namespace can discover each other and establish direct peer-to-peer connections.

## Usage

To use the MQTT Driver, import it from Peerix, create an MQTT client, connect the client to your broker over WebSocket, and pass the client to the driver.

```js
import { MqttDriver } from 'peerix';
import { connect } from 'mqtt';

// connect to an MQTT broker over WebSocket
const client = connect('wss://broker.emqx.io:8084/mqtt');

// create an MQTT driver instance
const driver = new MqttDriver({
  // the MQTT client instance
  client,
  // optional prefix for MQTT topics
  prefix: 'peerix/',
});
```

In this setup, the MQTT client manages broker connectivity while the Peerix driver handles signaling semantics. In production, prefer using `wss://` with authentication and access control enabled on the broker.

## Broker Setup

You need an MQTT broker with WebSocket support enabled for browser clients. For local development, Mosquitto is a common choice.

For a self-hosted setup, see the [Mosquitto self-hosting guide](https://peerix.dev/docs/servers/self-hosting/#mosquitto-server). For a managed option, see the [cloud hosting guide](https://peerix.dev/docs/servers/cloud-hosting/#mqtt-brokers) for recommended providers and free public endpoints.

## Installation

Install the `mqtt` package in your project to use the MQTT Driver in the browser.

```sh
npm install mqtt
```

```sh
pnpm add mqtt
```

```sh
yarn add mqtt
```


# NATS Driver
URL: https://peerix.dev/docs/drivers/nats/

The NATS Driver is a signaling driver that utilizes the [NATS messaging system](https://nats.io/) to enable communication between peers across different browsers and devices. This driver is ideal for scenarios where you want to establish peer-to-peer connections between multiple clients without the need for a custom signaling server.

Benefits of using the NATS Driver:

- **Effectiveness**: NATS supports namespace-based messaging, allowing Peerix to efficiently route signaling messages to the appropriate peers based on their namespaces, reducing unnecessary overhead.
- **Scalability**: NATS is designed for high performance and can handle a large number of connections and messages, making it suitable for applications with many peers.
- **Cross-platform**: NATS can be used across different platforms and environments, making it a versatile choice for signaling in peer-to-peer applications.
- **Security**: NATS supports secure connections and authentication, allowing you to protect your signaling messages and ensure that only authorized peers can connect.
- **Open-source**: NATS is an open-source project with an active community, providing ongoing support and improvements.
- **Integration**: NATS can be easily integrated with other systems and services, allowing you to build complex applications that leverage the full potential of the NATS ecosystem.

## Usage

To use the NATS Driver, import it from the Peerix library and create an instance:

```js
import { NatsDriver } from 'peerix';
import { wsconnect } from '@nats-io/nats-core';

// connect to a NATS server (e.g. the public demo server)
const nc = await wsconnect({ servers: ['wss://demo.nats.io:8443'] });

// create a NATS driver instance
const driver = new NatsDriver({
  // the NATS connection instance
  nc,
  // optional prefix for NATS subjects
  prefix: 'peerix.',
});
```

In this example, we create a new instance of the NATS Driver and specify the URL of the NATS server (`wss://demo.nats.io:8443`). All peers that connect to the same NATS server (or cluster) will be able to discover each other and exchange messages.

For production deployments, it is recommended to set up [your own NATS server](https://peerix.dev/docs/servers/self-hosting/#nats-server) to ensure better performance and security.

## Migration from `nats.ws`

When upgrading existing apps, make these changes:

- Replace the package `nats.ws` with `@nats-io/nats-core`.
- Replace old imports with `import { wsconnect } from '@nats-io/nats-core';`.
- Continue using `NatsDriver` with the `nc` connection and your preferred `prefix`.

## Installation

Install the `@nats-io/nats-core` package to use the NATS Driver; it provides a WebSocket client for connecting to NATS servers from the browser. You can install it using your preferred package manager:

```sh
npm install @nats-io/nats-core
```

```sh
pnpm add @nats-io/nats-core
```

```sh
yarn add @nats-io/nats-core
```


# Peer Connections
URL: https://peerix.dev/docs/peers/peer-connections/

The `Peer` class provides methods for joining and leaving rooms, sharing and subscribing to media streams, opening and closing data channels, and handling various events related to peer connections. The library will automatically manage the underlying WebRTC connections, including peer discovery, connection negotiation, media stream handling, and data channel communication. You can focus on building your application logic while Peerix takes care of the complexities of WebRTC.

## Creating Peer Instance

The `Peer` class is the core of the library. It manages peer connections, media streams, and data channels. You can create an instance of `Peer` by providing a signaling driver and optional configuration parameters:

```js
import { Peer, BroadcastChannelDriver } from 'peerix';

// create the specific driver instance
const driver = new BroadcastChannelDriver('my-app-channel');

// create the Peer instance with the driver
const peer = new Peer({ driver });
```

> [!IMPORTANT]
> You should choose the signaling driver that best fits your application's needs.

Peerix provides several built-in drivers, such as the Memory Driver for testing and development, the BroadcastChannel Driver for communication between tabs in the same browser, and the NATS Driver for communication between peers across different browsers and devices. You can also implement your own custom signaling driver if needed.

For NAT traversal, you should use a STUN server, for example `stun.l.google.com:19302` for free. However, for better connectivity, especially in restrictive network environments, it is recommended to use a TURN server. You should specify TURN/STUN servers in the `iceServers` configuration option:

```js
iceServers: [
  { urls: 'stun:stun.l.google.com:19302' },
  {
    urls: 'turn:turn.example.com:3478',
    username: 'user',
    credential: 'pass',
  },
];
```

> [!TIP]
> Use TURN servers for production applications.

For production applications, it is highly recommended to set up your own TURN server or use a reliable TURN service provider to ensure better connectivity and performance for your users. Relying on public STUN servers may lead to connectivity issues, especially in restrictive network environments where TURN servers are required for successful peer-to-peer connections.

## Connection Management

Peerix will automatically handle peer discovery, connection management, media streams and data channels negotiation. To join a room and start sharing media streams or sending messages, simply call the `join` method with the desired room ID:

```js
// listen for peer joining the room
peer.on('connection', (e) => {
  const { remote, state } = e;
  console.log(`Peer: ${remote.id}, State: ${state}`);
});

// listen for connection errors
peer.on('error', (e) => {
  const { error } = e;
  console.error('Error:', error);
});

// join a room
peer.join({
  room: 'room-id',
  metadata: {
    /* optional metadata */
  },
});

// later, if you want to leave the room
peer.leave();
```

Optionally, you can provide metadata with the `join` method that will be shared with other peers in the room. This can include information such as the peer's name or any other relevant data.

When you call the `join` method, Peerix will use the provided signaling driver to discover other peers in the specified room and establish peer-to-peer connections with them. The library will automatically handle the negotiation of media streams and data channels between connected peers, allowing you to focus on building your application logic without worrying about the underlying WebRTC complexities.

Peerix establishes a peer connection with a negotiated data channel for signaling after the initial connection is established, eliminating the need for a signaling server during the lifetime of the peer connection. This design allows for efficient communication between peers while minimizing signaling overhead and improving performance. So, even you do not share media streams or open data channels, the library will still establish a peer connection and wait for you to share media streams or open data channels to start sharing with other peers in the room. This allows for a more flexible and dynamic communication experience, as peers can join a room and establish connections without needing to immediately share media or data, while still being ready to do so when needed.

```mermaid
sequenceDiagram
    Note over Peer A, Peer B: Join the same room
    Peer A -->> Peer B: signaling: announce
    autonumber
    Peer B ->> Peer A: signaling: invoke
    Peer A ->> Peer A: Create Peer Connection +<br>Signaling Data Channel
    Peer A ->> Peer B: signaling: SDP offer
    Peer B ->> Peer B: Create Peer Connection +<br>Signaling Data Channel
    Peer B ->> Peer A: signaling: SDP answer
    autonumber off
    Peer A <<->> Peer B: signaling: ICE candidates
    Note over Peer A, Peer B: Connection established
```

> [!TIP]
> Use one connection per peer to share multiple media streams and data channels in both directions for better performance and resource usage.

Peerix allows you to use a single connection with each other peer in the room to share multiple media streams and data channels in two directions. This means that you can share multiple media streams and open multiple data channels with the same peer without needing to establish separate connections for each stream or channel. The library will manage the negotiation and sharing of all streams and channels over the single connection, optimizing the communication between peers and reducing load on client resources, signaling, and STUN/TURN servers.

## Lifecycle Events

Peerix uses an event-driven architecture that allows you to listen for and handle various events related to peer connections, media streams, and data channels. This design makes it easier to manage peer interactions and build real-time applications. You can listen for events such as when a peer joins or leaves a room, when a media stream is added or removed, when a data channel is opened or receives a message, and many more.

Lifecycle events include:

- `connection[:new,:connecting,:connected,:disconnected,:failed,:closed]`: a peer's connection state changes.
- `channel[:new,:open,:close,:message,:error]`: a data channel's state changes or it receives a message.
- `stream[:add,:remove]`: a remote peer shares or unshares a media stream.
- `track[:add,:remove]`: a track is added or removed from a media stream by a remote peer.
- `error`: an error occurs with a peer connection, media stream, data channel, or signaling.

You can subscribe to either group or specific events using the `:event` suffix.


# Self Hosting
URL: https://peerix.dev/docs/servers/self-hosting/

Peerix relies on signaling servers and TURN servers for media relay under certain network conditions. You can self-host these servers as part of your deployment or use managed services provided by Peerix.

Below are short guides for setting up open-source signaling and TURN servers using [Docker](https://www.docker.com/) for development and production.

## Signaling Server

You can use several open-source signaling servers that implement pub/sub functionality, such as NATS, MQTT, Mercure, and more. Peerix is designed to work with any signaling server that can exchange messages between peers, so choose the one that best fits your needs.

> [!IMPORTANT]
> For production, enable authentication and TLS on your signaling server and use `https://` or `wss://` URLs for secure communication.

### NATS Server

The [NATS](https://nats.io/) server handles signaling messages between peers. It lets peers discover each other and exchange messages needed to establish peer-to-peer connections. Use the official NATS server image to run a NATS server for development or production.

Run a local NATS server with WebSocket support:

```sh
cat << EOF > /tmp/nats-server.conf
websocket: {
  port: 8080,
  no_tls: true,
  same_origin: false
}
EOF

docker run --rm -p 4222:4222 -p 8080:8080 \
  -v /tmp/nats-server.conf:/nats-server.conf \
  nats:latest -c /nats-server.conf
```

Then use the URL `ws://localhost:8080` to connect to your NATS server. How to use it with Peerix is described in the [NATS driver](https://peerix.dev/docs/drivers/nats/) section.

### Mercure Server

The [Mercure](https://mercure.rocks/) server is another option. It is a real-time hub for publishing and subscribing to updates using Server-Sent Events (SSE). Use the official Mercure server image for development or production.

Run a local Mercure server:

```sh
docker run --rm -p 8080:80 \
  -e SERVER_NAME=':80' \
  -e MERCURE_PUBLISHER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' \
  -e MERCURE_SUBSCRIBER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' \
  dunglas/mercure:latest caddy run --config /etc/caddy/dev.Caddyfile
```

Then use the URL `http://localhost:8080/.well-known/mercure` to connect. How to use it with Peerix is described in the [SSE driver](https://peerix.dev/docs/drivers/sse/) section.

### Mosquitto Server

[Eclipse Mosquitto](https://mosquitto.org/) is a lightweight MQTT broker that can be used for signaling. It's well suited to low-bandwidth or high-latency networks.

Run a local Mosquitto server with WebSocket support:

```sh
cat << EOF > /tmp/mosquitto.conf
listener 9001
protocol websockets
allow_anonymous true
EOF

docker run --rm -p 1883:1883 -p 9001:9001 \
  -v /tmp/mosquitto.conf:/mosquitto.conf \
  eclipse-mosquitto:latest \
  mosquitto -c /mosquitto.conf
```

Then use the URL `ws://localhost:9001/mqtt` to connect. How to use it with Peerix is described in the [MQTT driver](https://peerix.dev/docs/drivers/mqtt/) section.

### Centrifugo Server

[Centrifugo](https://centrifugal.dev/centrifugo/) is a real-time messaging server that supports WebSocket and HTTP communication. Use the official image to run Centrifugo for development or production.

Run a local Centrifugo server:

```sh
docker run --rm --ulimit nofile=65536:65536 -p 8000:8000 \
  -e CENTRIFUGO_CLIENT_ALLOWED_ORIGINS='*' \
  -e CENTRIFUGO_CLIENT_INSECURE=true \
  centrifugo/centrifugo centrifugo
```

Then use the URL `ws://localhost:8000/connection/websocket` to connect. How to use it with Peerix is described in the [Centrifuge driver](https://peerix.dev/docs/drivers/centrifuge/) section.

## TURN Server

A TURN server relays media when direct peer-to-peer communication is not possible. This is useful when NATs or firewalls prevent direct connections between peers. You can use [Coturn](https://github.com/coturn/coturn) to run your own TURN server for development and production.

### Setting Up TURN Server

Start the TURN server with:

```sh
docker run -d \
  --name coturn \
  --network host \
  --tmpfs /var/lib/coturn:uid=0,gid=0,mode=1777 \
  -e DETECT_EXTERNAL_IP=yes \
  -e DETECT_RELAY_IP=yes \
  coturn/coturn:latest \
  --listening-port=3478 \
  --realm=your-realm \
  --user=username:password \
  --lt-cred-mech \
  --log-file=stdout
```

See the [Coturn Docker image](https://hub.docker.com/r/coturn/coturn) page for more configuration details.

Use it in Peer configuration:

```js
const peer = new Peer({
  driver,
  iceServers: [
    {
      urls: 'turn:your-turn-server:3478',
      username: 'username',
      credential: 'password',
    },
  ],
});
```

> [!IMPORTANT]
> Replace `your-turn-server`, `username`, and `password` with your TURN server's address and credentials.

### Testing TURN Server

To verify your TURN server, use the [Trickle ICE](https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/) page from the WebRTC project:

1. Open the Trickle ICE page.
2. Add your TURN server details to the ICE server configuration.
3. Click "Gather candidates".
4. Review the gathered candidates to confirm your TURN server is used for relaying.

If configured correctly, you should see candidates with the type `relay`, indicating that media would be relayed through your TURN server when needed.


# Socket.IO Driver
URL: https://peerix.dev/docs/drivers/socket-io/

The Socket.IO Driver is a signaling driver that uses [Socket.IO](https://socket.io/) to relay signaling messages between peers through your own server. It is a good choice when you want browser and device communication over a transport you control, with support for rooms, reconnection, and the rest of the Socket.IO ecosystem.

You can use the Socket.IO Driver with any Socket.IO server implementation, including your existing WebSocket infrastructure. The driver expects a simple pub/sub pattern: clients subscribe to namespaces, and the server relays messages between clients in the same namespace.

## Usage

To use the Socket.IO Driver, import the driver from Peerix, create a Socket.IO client connection, and pass that socket to the driver instance:

```js
import { SocketIoDriver } from 'peerix';
import { io } from 'socket.io-client';

// connect to your Socket.IO server
const socket = io('http://localhost:8080');

// create the Socket.IO driver instance
const driver = new SocketIoDriver({
  // the Socket.IO client instance
  socket,
  // optional prefix for Socket.IO events
  prefix: 'peerix:',
});
```

All peers that connect to the same Socket.IO server and subscribe to the same namespace can discover each other and exchange signaling messages.

## Installation

You need the `socket.io-client` package in the browser and a Socket.IO server implementation to forward signaling messages between clients.

```sh
npm install socket.io-client socket.io
```

```sh
pnpm add socket.io-client socket.io
```

```sh
yarn add socket.io-client socket.io
```

## Expected Events

The Socket.IO Driver expects the following event names. The `prefix` option lets you customize the event namespace used by the client and server.

- Client to server: `prefix:subscribe`, `prefix:unsubscribe`, `prefix:dispatch`
- Server to client: `prefix:message`

This is the typical signaling flow:

```mermaid
sequenceDiagram
    participant A as Peer A
    participant S as Socket.IO Server
    participant B as Peer B

    A->>S: peerix:subscribe(namespace)
    B->>S: peerix:subscribe(namespace)
    A->>S: peerix:dispatch(namespace, payload)
    S->>B: peerix:message(namespace, payload)
    B->>S: peerix:unsubscribe(namespace)
```

## Backend Server

Your Socket.IO server should subscribe clients to namespaces and broadcast dispatched messages to other peers in the same namespace.

Here is a simple Node.js example using the `socket.io` package that implements the required server logic for the Socket.IO Driver:

```js
const { Server } = require('socket.io');

const io = new Server(8080, {
  cors: { origin: '*' },
});

io.on('connection', (socket) => {
  socket.on('peerix:subscribe', (namespace, callback) => {
    socket.join(namespace);
    if (callback) callback();
  });

  socket.on('peerix:unsubscribe', (namespace, callback) => {
    socket.leave(namespace);
    if (callback) callback();
  });

  socket.on('peerix:dispatch', (namespace, payload, callback) => {
    socket.broadcast.to(namespace).emit('peerix:message', namespace, payload);
    if (callback) callback();
  });
});
```

In this setup, each namespace acts like a signaling room. When one peer dispatches a signaling message, the server relays it to the other peers subscribed to that namespace.


# SSE Driver
URL: https://peerix.dev/docs/drivers/sse/

The SSE Driver is a signaling driver that uses [Server-Sent Events](https://developer.mozilla.org/docs/Web/API/Server-sent_events) for receiving real-time updates from [Mercure](https://mercure.rocks/)-compatible servers over an HTTP connection. It uses standard HTTP `POST` requests for publishing messages to the server and an SSE stream for receiving messages from the server. This makes it a good choice when you want a simple, browser-friendly real-time transport without depending on WebSockets.

## Usage

To use the SSE Driver, import the driver from Peerix, point it at your server endpoint, and create an instance:

```js
import { SseDriver } from 'peerix';

const publisherJwtKey = 'mercure-publisher-jwt-key';

const driver = new SseDriver({
  url: 'http://localhost:8080/.well-known/mercure',
  publisher: {
    headers: {
      Authorization: `Bearer ${publisherJwtKey}`,
    },
  },
});
```

The `url` option should point to a server endpoint that can both open an SSE stream for incoming updates and accept `POST` requests for outbound messages. You can provide additional options for `publisher` (fetch options) and `subscriber` (EventSource options) as needed. All peers that connect to the same server endpoint can discover each other and exchange signaling messages.

You can use this JWT publisher key with the Mercure server's default configuration for testing purposes:

`eyJhbGciOiJIUzI1NiJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdLCJzdWJzY3JpYmUiOlsiKiJdfX0.bVXdlWXwfw9ySx7-iV5OpUSHo34RkjUdVzDLBcc6l_g`

## Message Flow

The SSE Driver uses two transport directions: HTTP `POST` from peer to server for outgoing messages, and SSE from server to peers for incoming messages.

```mermaid
sequenceDiagram
  participant A as Peer A
  participant S as SSE Server
  participant B as Peer B

  A->>S: GET /.well-known/mercure?topic=... (open SSE stream)
  B->>S: GET /.well-known/mercure?topic=... (open SSE stream)
  A->>S: POST /.well-known/mercure?topic=... (signal payload)
  S-->>B: SSE event: data: payload
  B->>S: POST /.well-known/mercure?topic=... (signal payload)
  S-->>A: SSE event: data: payload
```

## Backend Server

You can deploy a [self-hosted Mercure server](https://peerix.dev/docs/servers/self-hosting/#mercure-server) or create your own custom SSE server that follows the same conventions.

Here is a simple Node.js example that implements the required endpoints for the SSE Driver:

```js
const express = require('express');
const cors = require('cors');

const app = express();
app.use(express.urlencoded({ extended: true }));
app.use(cors({ origin: true, credentials: true }));

const namespaces = new Map();

// route for outgoing messages (subscribe/stream)
app.get('/.well-known/mercure', (req, res) => {
  const { topic } = req.query;
  if (!topic) return res.status(400).end();
  // support multiple topics in a single request
  const topics = Array.isArray(topic) ? topic : [topic];
  for (const t of topics) {
    const clients = namespaces.get(t) || new Set();
    namespaces.set(t, clients);
    clients.add(res);
  }
  // set headers to establish the SSE stream
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');
  res.flushHeaders();
  // clean up if the browser closes the page or disconnects
  req.on('close', () => {
    for (const t of topics) {
      const clients = namespaces.get(t);
      if (clients) {
        clients.delete(res);
        if (!clients.size) namespaces.delete(t);
      }
    }
    res.end();
  });
});

// route for incoming messages (publish)
app.post('/.well-known/mercure', (req, res) => {
  const { topic, data = '' } = req.body || {};
  if (topic) {
    const topics = Array.isArray(topic) ? topic : [topic];
    for (const t of topics) {
      const clients = namespaces.get(t);
      if (clients) {
        for (const client of clients) {
          client.write(`data: ${data}\n\n`);
        }
      }
    }
  }
  res.status(200).end();
});

app.listen(8080);
```

This example uses the Express and CORS modules, so install them in your project:

```sh
npm install express cors
```

```sh
pnpm add express cors
```

```sh
yarn add express cors
```

In this setup, each topic acts like a signaling channel. When one peer posts a message, the server relays it to every other connected client in the same topic through the SSE stream.


# Supabase Driver
URL: https://peerix.dev/docs/drivers/supabase/

The Supabase Driver is a signaling driver that uses [Supabase Realtime](https://supabase.com/docs/guides/realtime) to relay signaling messages between peers via your Supabase project. It is a good choice when you want browser-to-device communication over infrastructure you already manage.

To use the Supabase Driver, you must have a Supabase project with Realtime enabled. The driver uses a simple pub/sub pattern: clients subscribe to channels based on a prefix, and the server relays messages between clients in the same channel. Each channel represents a peer room where signaling messages are exchanged between peers in that room.

## Usage

To use the Supabase Driver, import the driver from Peerix, create a Supabase client, and pass that client to the driver instance:

```js
import { SupabaseDriver } from 'peerix';
import { createClient } from '@supabase/supabase-js';

// connect to your Supabase project
const supabase = createClient('your_project_url', 'your_supabase_api_key');

// create the Supabase driver instance
const driver = new SupabaseDriver({
  // the Supabase client instance
  supabase,
  // optional prefix for signaling channels
  prefix: 'peerix:',
});
```

All peers that connect to the same Supabase project and use the same prefix can discover each other and exchange signaling messages.

## Installation

You need the `@supabase/supabase-js` package in the browser to use the Supabase Driver.

```sh
npm install @supabase/supabase-js
```

```sh
pnpm add @supabase/supabase-js
```

```sh
yarn add @supabase/supabase-js
```

# Glossary
URL: https://peerix.dev/glossary/

- **Peerix**: A JavaScript library for building WebRTC peer-to-peer applications
- **API**: Application Programming Interface — a set of functions and protocols for building software applications
- **CDN**: Content Delivery Network — a distributed network of servers that delivers content to users based on their geographic location
- **ESM**: ECMAScript Module — a standardized module system for JavaScript that allows for modular code organization and reuse
- **UMD**: Universal Module Definition — a JavaScript module format that supports both AMD and CommonJS module systems, as well as global variable usage in browsers
- **WebRTC**: Web Real-Time Communication — a set of APIs and protocols enabling peer-to-peer communication in web browsers
- **Signaling**: The process of exchanging control messages to establish and manage a WebRTC connection
- **WebSocket**: A protocol providing full-duplex communication channels over a single TCP connection, often used for signaling in WebRTC applications
- **ICE**: Interactive Connectivity Establishment — a framework for NAT traversal in WebRTC
- **STUN**: Session Traversal Utilities for NAT — a protocol for discovering the public IP address and port of a device behind a NAT
- **TURN**: Traversal Using Relays around NAT — a protocol for relaying media when direct peer-to-peer communication is not possible
- **Data Channel**: A WebRTC API for sending arbitrary data directly between peers
- **Media Stream**: A WebRTC API representing a stream of media content, such as audio or video
- **NAT**: Network Address Translation — a method used by routers to translate private IP addresses to public IP addresses
- **Peer-to-Peer** (P2P): A communication model where each participant (peer) can directly communicate with others without a central server
- **SFU**: Selective Forwarding Unit — a media server that receives streams from participants and forwards selected streams to others, enabling multi-party conferencing with lower server-side processing
- **MCU**: Multipoint Control Unit — a media server that mixes incoming media into a single composite stream for distribution to participants
- **NATS**: A high-performance messaging system often used for signaling in WebRTC applications



---
Generated on 2026-05-29 12:34:42 UTC
Site: https://peerix.dev/