// the idea
Open WebUI is a capable front-end for Ollama and it served well for setting up the RAG knowledge base. But it's someone else's product — generic branding, generic layout, and no way to make it feel like something you built. The next step was to replace it entirely with a custom interface built to match the cyber-wyse aesthetic.
The goal was straightforward: a single HTML file that talks directly to the Ollama REST API, branded to match this site, and accessible from any device on the local network — no Docker, no npm, no build step. Just a file you open in a browser.
The result is exactly that. One file. Drop it anywhere. Open it. It works. And because it calls Ollama's API directly, it's as capable as any other interface — streaming responses, model switching, session history, suggested prompts — all of it custom built.
// the design
The interface uses the same design language as cyber-wyse.com — the same colour palette, the same typefaces (Share Tech Mono, Syne, DM Sans), the same noise overlay and grid background, the same dark base with #00e5b4 as the primary accent. It feels like a product that belongs to this project rather than a generic tool dropped in.
cyber-wyse logo, model selector, live Ollama connection indicator, and new chat button — all in the site's monospace style.
Text streams in as the model generates it — the same behaviour as any cloud AI product, running entirely locally.
Conversations are stored in session memory and listed in a sidebar with titles and message counts. Click any to reload it.
The welcome screen shows context-specific chips — WyseDSP RAG queries alongside general questions — to demonstrate both capabilities.
Switch between all installed Ollama models from the header. WyseDSP Coder (DeepSeek) is the default, with Mistral, Qwen2.5, and TinyLlama available.
No frameworks, no build tools, no npm. Pure HTML, CSS, and vanilla JS. The whole thing is one file you can open directly from disk.
// how it works
Ollama exposes a simple HTTP API on port 11434. The chat interface calls two endpoints — one to check which models are available, and one to stream a conversation. That's it. No middleware, no proxy, no backend code to maintain.
Each message sends the full conversation history to Ollama's /api/chat endpoint with stream: true. The response is a newline-delimited stream of JSON chunks, read with the browser's Fetch API:
// Send message + full history, stream the response
const response = await fetch(`http://localhost:11434/api/chat`, {
method: 'POST',
body: JSON.stringify({
model: 'deepseek-coder',
messages: conversationHistory,
stream: true
})
});
const reader = response.body.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
// Parse each JSON chunk and append to the UI
const data = JSON.parse(decoder.decode(value));
fullText += data.message?.content || '';
}
The model selector in the header maps display names to actual Ollama model identifiers, so "WyseDSP Coder" routes to deepseek-coder without the user needing to know the internal name.
The entire connection target lives in a single variable at the top of the file: const OLLAMA_BASE = 'http://localhost:11434'. Change this to your machine's IP and every device on the network can use it.
// network access
This is where it gets genuinely useful. Because Ollama is bound to 0.0.0.0 (set up in the Local AI project), and because the HTML file just makes HTTP requests, any device on the same network can access the full AI setup — without installing anything.
$ ip addr show | grep "inet " | grep -v 127.0.0.1
inet 192.168.1.45/24 brd 192.168.1.255 scope global
// Change this one line:
const OLLAMA_BASE = 'http://192.168.1.45:11434';
Python's built-in HTTP server is the simplest option — no install needed:
$ mkdir ~/cyber-wyse-ui
# Copy cyberwyse-chat.html into that folder, then:
$ cd ~/cyber-wyse-ui && python3 -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 ...
To have the server start automatically whenever the Ubuntu machine boots:
$ sudo nano /etc/systemd/system/cyberwyse-ui.service
[Unit]
Description=cyber-wyse UI
After=network.target
[Service]
ExecStart=/usr/bin/python3 -m http.server 8080
WorkingDirectory=/home/eamon/cyber-wyse-ui
Restart=always
[Install]
WantedBy=multi-user.target
$ sudo systemctl enable cyberwyse-ui
$ sudo systemctl start cyberwyse-ui
MacBook, Windows PC, iPhone, iPad — anything on the same network can now open http://192.168.1.45:8080/cyberwyse-chat.html and get the full interface, backed by local AI running on the Ubuntu machine. No apps, no accounts, no internet required.
// what this demonstrates
The difference between a tool and a product is ownership. Open WebUI is a tool — useful, functional, but entirely someone else's. The custom interface is a product: it looks like it belongs to this project, it reflects deliberate design decisions, and it can be changed, extended, or handed to someone else without explanation.
It also demonstrates something more practical: you don't need a server, a deployment pipeline, or a cloud account to ship a working AI interface. A single HTML file and a repurposed laptop is enough infrastructure to give every device in a building access to a capable, private, offline AI assistant.
The Ollama REST API is simple enough that you could build this in an afternoon. The design work — getting it to feel polished, on-brand, and genuinely usable — is where the real effort went. And that's exactly the kind of work AI accelerates most effectively: moving quickly from a functional prototype to something that looks like it was made on purpose.