A framework-free chat app with replies that stream as they arrive
A framework-free chat app with streamed Ollama replies, saved conversation context and cancellable requests.
A conversation with a reliable request lifecycle
Neptune is a chat interface built against Ollama’s API, with no framework on the front end and a small Express service behind it. The work was less about the chat bubbles than the request lifecycle around them: replies stream in as they are generated, a response can be cancelled or timed out mid-stream, and the interface reports whether the backend is actually reachable.
What it does
- Streamed replies. Fetch, a streamed reader and TextDecoder render Ollama responses as they arrive.
- Cancellation and timeouts. An AbortController ties stopping and timing out to each request.
- Saved context. Conversation context stays available between messages.
- Visible backend health. A heartbeat checks a health endpoint so the interface can report when the backend is unavailable.
- A compact mobile composer. Starting prompts, model controls and message actions remain within reach.
- Separated API responsibilities. Express routing, controllers, middleware and inference have clear boundaries.
The Express backend separates routing, controllers, middleware and inference, so the parts that validate a request are not tangled with the parts that talk to the model. Replies stream to the browser through the Fetch API and a streamed reader, decoded with TextDecoder and rendered as they arrive rather than waiting for the full response.
An AbortController ties cancellation and timeouts to each request, and a heartbeat polls a health endpoint so the interface can show when the backend is unavailable instead of failing silently. The API is rate-limited per IP with proxy-aware client detection, validated input and an environment-configured CORS allowlist, and it logs requests with timing and user-agent data. The front end deploys on GitHub Pages and the API on Render.