NovexChat
A complete messenger: one-to-one and group chat, reactions, typing and presence, per-recipient read receipts, and peer-to-peer voice and video calls. It exists as a reference build — clients ask for these capabilities inside their own product, and this is how we deliver them without starting from zero.
“We need chat in our app” usually gets quoted as a rewrite.
Realtime messaging and in-app calling look simple until you meet the parts that are not: waking a terminated phone for an incoming call, keeping presence correct across three devices, and showing honest delivery ticks in a group.
NovexChat is the reference implementation of those parts. When a client needs messaging or calling inside their own product, the hard problems are already solved and the work becomes fitting them to the product — not discovering them at integration time.
Every surface, by us.
The hard parts are the ones nobody demos.
Every item below is a problem that only appears in production, on a real device, at the worst possible moment.
Waking a killed iOS app needs PushKit
Android receives a data-only push for an incoming call. iOS receives a PushKit VoIP push sent straight to Apple, because the ordinary push service cannot send one and nothing else reliably wakes a terminated iOS app. Both token kinds live side by side, separated by platform, and the ordinary push queries deliberately exclude the VoIP ones.
Presence is a counter, not a boolean
Online state is a per-user counter in Redis rather than a flag, so somebody signed in on a phone, a tablet and the web does not appear offline the moment they close one of them.
Delivery state is per-recipient
Receipts are stored per recipient rather than as a single status on the message. That is what makes sent, delivered and read honest in a group chat instead of reflecting whichever member happened to answer first.
Only signalling crosses the server
Call media flows directly between peers, with a relay used solely when address translation leaves no alternative. The server sees who is calling whom, not the conversation.
Rooms per user and per conversation
Each connection joins a room for the user and a room for each of their conversations, which keeps fan-out proportionate to the audience of a message rather than to the size of the service.
What it runs on.
We build these for ourselves. We build them for clients too.
Everything on this page was designed, built, deployed and is operated by the same small senior team. If you have a product that needs the same treatment, start with a conversation.