Guide · How it works
How NulBridge works
NulBridge connects two browsers directly and encrypts everything end to end, with keys made on your device. This guide follows a session from the link you share to the safety code you compare, and shows what every server involved can and can’t see.
- Updated
- Protocol
- Version 2
- Reading time
- 9 minutes
- Covers
- Links, codes, networks
01Overview
The short version
Three steps, no account, nothing to install. The rest of this guide opens up each one.
- 01
Create
Open a private link or get a 6-digit code. Your browser makes fresh encryption keys on the spot.
- 02
Share
Send the link or read out the code, through any channel. The secret part of a link never reaches a server.
- 03
Connect
Their browser connects to yours. Compare the safety code, then chat, send files or call.
The idea
Servers introduce the two browsers. They never see what you say.
02Option A
Private link
The default way to connect, and the strongest. The link carries a 256-bit secret that only the two of you ever hold.
Before you share
- 01
Your browser
Your browser creates the keys
A fresh ECDH P-256 key pair, made with the browser’s Web Crypto API. The private half is non-extractable: the page can use it, but can’t read it out or send it anywhere. - 02
Your browser to Signaling server
It registers a random peer ID
An ID such asnb-3f9c…8293, 96 random bits, goes to the signaling server. From now on, another browser can ask to be introduced to yours. - 03
Your browser
It writes the link
Your browser draws 256 random bits for the secret and builds/join/<peer ID>#<secret>. Nothing about the secret is sent anywhere. - 04
You to Them
You send it
Use any channel you trust: a messenger, email or the QR code. The part after # is a URL fragment, and browsers never send fragments to a server. Not to this website, not to the signaling server.
https://nulbridge.pages.dev/join/nb-3f9c0a1b2c3d4e5f60718293#KXK7BE2W3yhxugNMld4ncLkCS5TdJm-4AUqT3CVutwA
- Site and path
- Sent to the website when the link is opened, like any page address.
- Room ID
- Your random peer ID (96 bits). It tells their browser whom to call. The website sees it too.
- Secret · 256 bits
- Everything after the #. Browsers never send it to any server.
When they open it
- 05
Their browser
They open it and click Join
The join page moves the secret out of the address bar and into the tab’s memory, then waits for a click on Join session. Email scanners and link previews open links on their own; the click keeps them from using up the session. - 06
Their browser to Signaling server to Your browser
The browsers find each other
Their browser registers its own random ID and asks the signaling server to connect it to yours. The two swap network addresses and open a WebRTC data channel, directly whenever the network allows. - 07
Both browsers
They agree on keys
Over that channel they exchange public keys and random nonces. Each side mixes its ECDH result with the link secret through HKDF-SHA-256 and arrives at the same two AES-256-GCM keys, one per direction. - 08
Both browsers
They prove it
Each side sends an encrypted “ready” message that only a holder of the right secret can produce. Their browser goes first; yours answers only after checking it. A wrong secret or a tampered connection stops here, and no session opens. - 09
Both browsers
The session opens
Both screens show the chat and the same safety code. From now on, your tab turns away anyone else who tries the link.
03Option B
6-digit code
Easier to read out loud when copying a link is awkward. A code is short, so it is protected differently, and comparing the safety code matters more.
- 01
Your browser to Signaling server
Keys and ID, as before
Your browser creates a fresh key pair and registers a random peer ID with the signaling server, exactly as for a private link. - 02
Your browser to Code service
It asks for a code
The code service draws six digits from a cryptographic random generator and stores the code with your peer ID and an expiry time. An unused code stops working after 10 minutes. - 03
You to Them
You pass it on
Read it out on a call, send it in a message or show your screen. The code is all they need. - 04
Their browser to Code service
They claim it, once
Their browser registers with the signaling server first, then trades the code for your peer ID. The service deletes the code in the same step, so a second claim finds nothing. - 05
Both browsers
Same handshake, different secret
The browsers connect and run the same handshake as with a private link. Instead of a link secret, a SHA-256 hash of the code is mixed into the keys. - 06
You to Them
Compare the safety code
A 6-digit code has only a million possible values. Comparing the safety code is how you know nobody stepped into the middle: read it aloud and check that it matches. Why this matters
04Data paths
What travels where
Several servers help two browsers find each other. None of them can read what you say, and only a relay ever carries it, encrypted.
- Your conversation: messages, files and calls, end-to-end encrypted
- Connection setup only: IDs, network addresses, the code
- Fallback through a relay, used only when no direct path works
| Data | Path | Who can see it |
|---|---|---|
| Messages, files and calls | Between the two browsers over WebRTC: directly, or through a TURN relay when no direct path works. | Only the two of you. A relay forwards encrypted bytes it can’t read. |
| Encryption keys | Never sent. Each browser derives them on its own, and private keys can’t be exported. | Nobody but the two browsers. |
| The link secret, after the # | Only inside the link. Browsers never send the part after # to a server. | Whoever holds the link, including any app you send it through. |
| Connection setup: peer IDs, network addresses, WebRTC certificate fingerprints | Through the signaling server (a PeerJS server), on the way to the other browser. | The signaling server and the other browser. |
| Your public IP address | Seen by every server you reach: the website, signaling, STUN, the code service and a relay, if used. Shared with the other browser to find a direct path. | Those services, and the person you connect with, even on a relayed connection. |
| A 6-digit code and your peer ID | Stored by the code service (Supabase) until claimed. Unusable after 10 minutes, then deleted. | The code service. |
| A peppered hash of your IP address | Kept by the code service for rate limiting (IPv6: the /64 prefix), deleted after about an hour. | The code service. |
| The room ID in a /join/ link | Part of the link’s path, so the website receives it when the link is opened. | The website host, in its request logs. |
Who can see what
Messages, files and calls
- Path
- Between the two browsers over WebRTC: directly, or through a TURN relay when no direct path works.
- Who can see it
- Only the two of you. A relay forwards encrypted bytes it can’t read.
Encryption keys
- Path
- Never sent. Each browser derives them on its own, and private keys can’t be exported.
- Who can see it
- Nobody but the two browsers.
The link secret, after the #
- Path
- Only inside the link. Browsers never send the part after # to a server.
- Who can see it
- Whoever holds the link, including any app you send it through.
Connection setup: peer IDs, network addresses, WebRTC certificate fingerprints
- Path
- Through the signaling server (a PeerJS server), on the way to the other browser.
- Who can see it
- The signaling server and the other browser.
Your public IP address
- Path
- Seen by every server you reach: the website, signaling, STUN, the code service and a relay, if used. Shared with the other browser to find a direct path.
- Who can see it
- Those services, and the person you connect with, even on a relayed connection.
A 6-digit code and your peer ID
- Path
- Stored by the code service (Supabase) until claimed. Unusable after 10 minutes, then deleted.
- Who can see it
- The code service.
A peppered hash of your IP address
- Path
- Kept by the code service for rate limiting (IPv6: the /64 prefix), deleted after about an hour.
- Who can see it
- The code service.
The room ID in a /join/ link
- Path
- Part of the link’s path, so the website receives it when the link is opened.
- Who can see it
- The website host, in its request logs.
05Networks
Direct vs. relayed connections
WebRTC always tries the most direct route first. Here is what happens when a network stands in the way.
- NATNetwork address translation
- Your router shares one public address among your devices. Nothing outside can reach a device directly until it reaches out first.
- STUNSession Traversal Utilities for NAT
- A STUN server tells your browser which public address it appears from. The browsers swap these addresses and try to reach each other directly.
- TURNTraversal Using Relays around NAT
- When no direct route works, a TURN server relays the traffic. It forwards encrypted bytes it can’t read, and it sees both IP addresses.
Your browsers talk straight to each other. The lowest delay, and nothing in between.
A TURN server forwards the traffic. It stays end-to-end encrypted, but the relay sees both IP addresses and how much data flows.
Usually the direct route works. It can fail when both sides sit behind strict firewalls or certain carrier-grade NATs, as on some corporate and mobile networks. Then a relay is the only way through. The chat header shows DIRECT or RELAY, so you always know which route you’re on.
| Signaling server | 0.peerjs.com (public PeerJS server) |
|---|---|
| STUN servers | stun.l.google.com, stun1.l.google.com, stun.cloudflare.com |
| TURN relay | Not configured. Some strict networks can’t connect. |
| 6-digit codes | Available |
Read from this site’s build configuration. Not sure about your own network? Run the connection check.
06Requirements
What you need
Nothing to install and no account. A current browser on each side, and a network that lets WebRTC through.
A current browser
Chrome, Edge, Firefox or Safari, on a computer or a phone, with JavaScript turned on.
WebRTC and Web Crypto
A secure (HTTPS) page with WebRTC data channels and the Web Crypto API. Current browsers have both; some extensions and policies block WebRTC.
Both of you, at once
There is no server to hold messages, so both tabs stay open for the whole conversation.
A network that allows WebRTC
Most home, office and mobile networks do. Strict firewalls can block direct connections.
Camera and microphone, for calls
Your browser asks for permission when you start or accept a call. Chat and files don’t need it.
Files up to 500 MB
Each file travels in encrypted chunks. Big files need free memory on the receiving device.
Not sure about your setup? The connection check tests your browser and network and tells you what will work.
Run the connection check07Trade-offs
Limitations, by design
NulBridge does one thing: a private, temporary conversation between two people. That focus has costs, and you should know them before you rely on it.
- 01
One-to-one only
A session connects exactly two browsers. Anyone else who tries the link or code is turned away. There are no group chats. - 02
Both of you must be online
Messages go straight to the other browser. If it isn’t there, nothing is sent: no server holds messages for later. - 03
No history
Close the tab and the conversation is gone, for both of you. Nothing to back up, nothing to restore. Files you saved stay where you saved them. - 04
The other person can see your IP address
Browsers exchange network addresses to find a direct route, even when the connection ends up relayed. Connect only with people you’re comfortable sharing that with, or use a trusted VPN. - 05
Phones can pause background tabs
Mobile browsers suspend pages in the background to save power, which can drop the session. Keep NulBridge in front while you talk. - 06
Some networks can’t connect
Strict firewalls and some carrier-grade NATs block direct connections, and this site has no relay to fall back on. - 07
Not independently audited yet
The protocol and its code use standard Web Crypto primitives, but no outside firm has reviewed them so far.
For what NulBridge protects against and what it can’t, read the threat model.