ChatChat — Open AI Chat Client

A no-build, single-page chat interface for OpenAI-compatible chat completion APIs. Point it at LM Studio running locally or a cloud provider, and you're chatting in seconds.

No bundler. No package manager. No backend. Just HTML, CSS, and JS — open index.html and go.

ChatChat hero screen — dark themed landing page with an orb, mode pills (Chat / Story), prompt starter chips, and the hero input box.
Open, type, send. That's it.

What it is

ChatChat is a chat UI I built because LM Studio's built-in interface is fine, but I wanted something with a bit more personality — a story mode for interactive fiction, better markdown rendering, import/export, configurable sampling parameters, and the ability to switch between a local model and a cloud provider without reloading.

It's all client-side. Your chats, your config, your API keys — everything stays in your browser's localStorage. Nothing is sent anywhere except the messages you explicitly send to the API endpoint you configure.

What it does

  • Chat mode — freeform conversation with any OpenAI-compatible API. System prompt, temperature, repetition penalty — all configurable.
  • Story mode — three styles of interactive fiction:
    • Adventure (CYOA) — second-person narration, every reply ends with 2-3 numbered choices.
    • Roleplay — the AI plays your lead character and NPCs; you direct the story or speak in character.
    • Game Master — the AI runs the scene like a tabletop GM, narrating outcomes for what you attempt.
  • Streaming — responses appear token-by-token as they're generated, rendered at ~30fps to avoid layout thrash.
  • Markdown rendering — assistant responses render markdown with syntax-highlighted code blocks, powered by marked + DOMPurify + highlight.js.
  • Regeneration — cycle through alternate responses for any message without losing the originals.
  • Compression — older turns can be summarized into a single message to keep context under control.
  • Provider switching — toggle between Local (LM Studio at localhost:1234) and NanoGPT (cloud) without reloading.
  • Import / Export — export all your chats as JSON, or import them back. Story configs export as JSON or plain text.
ChatChat hero screen showing the orb, mode pills, and prompt chips.
The landing screen — pick a mode, click a starter, or just type.
ChatChat with text typed in the hero input box.
Type anything in the hero input.
ChatChat chat view with a message composed in the input bar.
Chat view — the input bar slides in when you start a conversation.
ChatChat story mode configuration — scene, characters, tags, first prompt.
Story mode — set the scene, add characters, pick a style, define the first prompt.
ChatChat configuration panel with temperature slider, rep penalty, system prompt, and keyboard shortcuts.
Configuration — temperature, repetition penalty, system prompt, appearance, and shortcuts.

Running it

Just open index.html in a browser, or serve the directory statically:

python3 -m http.server
For the default "Local" provider, LM Studio needs to be running at http://localhost:1234 with a model loaded.

Tech stack

  • Zero build tools — plain HTML, CSS, and vanilla JS.
  • CDN-loaded: marked (markdown parsing), DOMPurify (sanitization), highlight.js (syntax highlighting).
  • Everything persists to localStorage — chats, settings, generation history, story configs.
  • Provider abstraction: local (LM Studio) and nanogpt (cloud) registered in state.js.
  • Two conversation modes with their own system prompt builders: chat (freeform) and story (CYOA / roleplay / GM).
  • Streaming via raw SSE parsing — no SDK, no dependencies.

Want to check it out?

It's open source. Check the repo on GitHub.

AI Disclaimer

I have used AI to assist in the development of this project.