Posted by: Tim Bell Comments: 0

Building A Simple Peer-to-Peer WebRTC Chat with Temasys SkylinkJS

Reading Time: 9 minutes


Audio/Video communication is not the only thing that WebRTC enables you to do. The data channel offers a variety of use-cases, too, by sending information from one peer to another without going through a server. In this tutorial, we show you how to build a simple chat.

I’m using our open-source Temasys SkylinkJS library to build this. It takes care of the hard parts of introducing peers in different network environments and makes WebRTC really easy to use. If you haven’t seen my Getting Started tutorial, you can find it here.

Tip: You can click on the function and event names in this tutorial to see the corresponding entry in our API documentation.

See the Pen WebRTC Chat with Temasys SkylinkJS by Temasys (@temasys) on CodePen.

Step 1: Include Temasys SkylinkJS into your website

In the head of our super simple chat website, we embed the complete version of Temasys SkylinkJS. It comes with all the dependencies that we need to get started. In the header, we add input fields for my name and chat messages and some buttons that allow me to trigger my setName(), joinRoom(), leaveRoom() and sendMessage() functions later. The two divs underneath is where we want the chat messages to appear.

Step 2: Instantiate Skylink and creating simple helper functions

var skylink = new Skylink();

We create a new Skylink object and now go on to define the functions that we were referencing in the onclick attribute of my buttons before. The following lines of code describe where we get to trigger actions on Skylink, that other peers then will receive and react to.

 function setName() {
var input = document.getElementById('name');
name: input.value

In the setName function, we simply read out the string value that the user has written into our name
input field and use Skylink setUserData() function to pass any kind of user information in form of a JavaScript object into Skylink. This can be done before or after you join a room context and will automatically become available to every peer joining the same room context.

 function joinRoom() {

Here, we just call joinRoom() on Skylink. This tells the Skylink signaling server that I’m now ready to be connected to other peers joining the default room context.

 function leaveRoom() {

leaveRoom() leaves little surprise, here.

 function sendMessage() {
var input = document.getElementById('message');
input.value = '';

This is really where the magic happens. We use the sendP2PMessage() function to directly send my string message from the message input field, to all connected peers in my room. This happens one-by-one in a peer-to-peer fashion and through an encrypted transmission. No data touches a server. It’s a great way to have super private conversations. (Be aware: This is pretty safe to use for private data exchange, but nothing is ever totally safe!)

 function addMessage(message, className) {
var chatbox = document.getElementById('chatbox'),
div = document.createElement('div');
div.className = className;
div.textContent = message;

This is our helper function, to add a new message to the chatbox div that we created earlier. We can also pass a className variable to leverage CSS, so we can make different messages stand out. We use the textContent property of the div element to avoid that somebody can send me script tags or HTML inside a message that gets executed.

Step 3: Subscribing the Skylink events

When we use the functions above on one peer in the room, the other peers will get notified. Skylink informs them with events. In order for us to react to those event, we need to subscribe to them and execute our own functionality when they get triggered.

 skylink.on('peerJoined', function(peerId, peerInfo, isSelf) {
var user = 'You';
if(!isSelf) {
user = || peerId;
addMessage(user + ' joined the room', 'action');

peerJoined: When somebody joins the chat room, we want to be informed and show a little action message. We use the isSelf parameter to determine if it’s myself joining the room or somebody else and in the latter case we use Skylinks peerInfo attribute to retrieve the userData object that the user might have set earlier using Skylinks setUserData function. If there is no name set yet, we fall back and use Skylinks peerId.

 skylink.on('peerUpdated', function(peerId, peerInfo, isSelf) {
if(isSelf) {
user = || peerId;
addMessage('You're now known as ' + user, 'action');

peerUpdated: It may happen that a peer updates its userData object while connected to the room. In this case the peerUpdated event is fired. We receive the new userData object the same way we got it in the peerJoined event earlier.

 skylink.on('peerLeft', function(peerId, peerInfo, isSelf) {
var user = 'You';
if(!isSelf) {
user = || peerId;
addMessage(user + ' left the room', 'action');

peerLeft: When a peer leaves the chatroom, we also write a short message into the chat room to inform the user.

 skylink.on('incomingMessage', function(message, peerId, peerInfo, isSelf) {
var user = 'You',
className = 'you';
if(!isSelf) {
user = || peerId;
className = 'message';
addMessage(user + ': ' + message.content, className);

incomingMessage: This event is triggered whenever Skylink receives a public or private message from another peer. Messages sent with sendP2PMessage() are always private messages, although they could have been sent to multiple peers. If you want to find out if a message was a non-peer-to-peer public broadcast, you can check peerInfo.isPrivate to be false.

Step 4: Initialize!


By calling init(), Temasys SkylinkJS starts establishing a signaling connection with our servers and requires your App key as a parameter. Only after calling this function, you’re able to join room contexts.

If you don’t have one yet, you can register and get your own App key using our Developer Console. You can make a lot fancier of a chat than this, but this example shows pretty well that creating a chat is not as hard anymore as it used to be. Leave us your feedback on our support portal! We’d love to hear from you. 🙂


Leave a Reply

Your email address will not be published. Required fields are marked *