How I made OpenAI, Claude, Gemini, Ollama, Mistral, Groq and Azure look identical to the browser — with no database, no backend secrets, and the user's API key never leaving their machine for longer than one request.
I built a small open-source Next.js app where a visitor picks an LLM provider, pastes their own API key, and streams a response. The fun part wasn't the UI — it was a constraint I set early:
The client must have exactly one code path for streaming, no matter which of the seven providers is selected.
That sounds obvious until you actually look at how these APIs stream. They disagree on almost everything: the transport, the chunk shape, where the system prompt goes, and how the stream ends. This post is how I collapsed all of that into a single contract.
The mess you're actually dealing with






