← back
foss p2p networking

Kiyeovo - a decentralized peer-to-peer messenger

How to use the app & optionally self-host your own Kiyeovo bootstrap, relay and ICE servers

Intro

Kiyeovo is a P2P messenger that has 2 network modes: Fast and Anonymous. Fast uses the clearnet and should be used for day-to-day activities - it also enables audio/video calling. Anonymous routes the whole traffic through Tor - slower, but stronger anonymity.

Some of the features include:

  • realtime direct messages are end-to-end encrypted
  • messages can fall back to offline delivery when the other side is not online
  • fast mode is for normal day-to-day use: lower latency, relays, and 1:1 audio/video calling
  • anonymous mode is for Tor-routed messaging. Better anonymity, but slower and less convenient
  • group chats, encrypted file transfer, and trusted profile import/export
  • no central account or message server; you can use the default bootstrap/relay setup or self-host (see the guide)

But, you can read all about that on my Github page, here.

In the next chapters, I will show you the basic usage, and how to self-host. Let’s begin.

Basic usage

After you have cloned the app, you need to run npm run setup inside the app directory. In case you do not plan on using the anonymous mode, npm install is sufficient.

Now, all you need to run is npm run start:local, and the app should start up. In case you also want to find & report bugs, run npm run start:local:debug so that you can provide logs.

If the app has started successfully, you should see this: App startup

Let’s try out the fast mode first! Select FAST and create an identity - just input the password, optionally remember it if you have a keychain installed on your machine, and PLEASE write down the recovery phrase. If you lose your password, only the recovery phrase can help you.

The app should look like this now: Init

Let’s try to connect to a bootstrap and relay nodes so that I can talk to somebody. Click on the connection status and type in the bootstrap address (if you’re reading this before April 19th 2026, you can even use one of mine). After you “Retry bootstrap connection”, it should look like this: Bootstrap

Great! Now do the same thing for the “Relays”, and it should look like this: Relay

Let’s register ourselves so that we can find people on the network, and that other people can find us. There is an alternative way to connect with people which I explained here (coming in an hour…), but DHT is much quicker. Click the button left “Register Identity” button and let’s give ourselves a creative name! Register

Great, we should be registered now! Let’s go contact our friend alice by clicking on the ”+” button in the sidebar’s header and selecting New Conversation. Type in alice’s username or peer ID (shared via third party like whatsapp, viber, bitchat…), compose an inital greeting and hit “Send”. You should see this: Greeting

While alice sees this: Worm

After alice accepts, you can chat with her, create groups with her and have audio/video calls. Since typing is a low bandwidth output action, and we don’t have telepathy yet, let’s try calling her. For calls, we need STUN server, and if our routers are being difficult, we also need TURN servers - so let’s add them. I started a coturn service on the same node that hosts the bootstrap and relay servers, so I will just input that information, like this: ICE

After that, we can call her! call

Self-hosting

Fast mode

For the purpose of this tutorial, I bought a fresh DigitalOcean instance for a whopping price of $6. After being financially ruined by the previously mentioned purchase, I have set up the firewall - ALLOW TCP on ports 9000 (bootstrap) and 4002 (relay).

If you want to be able to call, you need to also ALLOW TCP and UDP on port 3478 and UDP on port range 49160:49200.

If you’re using ufw, it should look like this after running ufw status: fw

Great, now it’s easy. Clone the repository and position yourself in it.

Bootstrap and relay nodes

Firstly, Install dependencies

ROLE=bootstrap npm install

Start the bootstrap node:

BOOTSTRAP_NETWORK_MODE=fast \
BOOTSTRAP_ANNOUNCE_ADDRS=/ip4/YOUR_PUBLIC_IP/tcp/9000 \
npm run bootstrap

You should see this: new_bootstrap

Start the relay node:

RELAY_ANNOUNCE_ADDRS=/ip4/YOUR_PUBLIC_IP/tcp/4002 \
npm run relay

You should see this: new_relay

Super! Now you can connect with your client to your bootstrap and relay nodes! connectedtonew

STUN/TURN servers

For enabling calls, we will be using coturn. It depends on your system how you set it up, but for my Ubuntu machine, I installed it using apt install coturn, ran sed -i 's/^#TURNSERVER_ENABLED=.*/TURNSERVER_ENABLED=1/' /etc/default/coturn and configured the turnserver.conf like this:

listening-port=3478
fingerprint
lt-cred-mech
realm=kiyeovo
user=USERNAME:PASSWORD
external-ip=PUBLIC_IP
min-port=49160
max-port=49200
no-cli

and then sudo systemctl enable --now coturn

That should be it! We can now add that server and use it to make calls!

stun