Nomad Zoo

Three chat products, each built the way that kind of chat product is actually built. They share no code and no dependencies — any one of them can be lifted out on its own.

Why three

The two AI chats are the same product built inside out, so the difference between the architectures is visible rather than described.

AtlasRelay
TransportServer-Sent EventsWebSocket
LanguagePython + FastAPINode + TypeScript
Source of truthServerClient
History lives inSQLite on the serverIndexedDB in the browser
Cancel isa separate HTTP requesta frame on the open socket
Survivesa page reload, mid-streama server restart, mid-conversation

Try it both ways. In Atlas, run localStorage.clear() mid-generation and reload — you lose only which stream was live; every message is intact, because the server is the truth. In Relay, run ./run.sh restart chat-ws mid-conversation — the page reconnects with the whole transcript, because the client never gave it away.