murmur

Your site answers its visitors.

murmur adds a chat bubble that answers from your own pages, cites them and links to the right heading. One script tag, no backend, the AI model you pick.

This demo has no key of its own: run a small model in your browser (WebGPU, about 1.1 GB once), bring your key (it stays encrypted in your browser) or point it at Ollama on your machine.

Plugging in the index…

  1. Every jack is a section of this site; cited ones light up.
  2. Waiting for a question.
One line
<script type="module" src="https://maxgfr.github.io/murmur/cdn/murmur.js"></script>

Set it up, copy one line.

Pick who holds the AI key, write a greeting, choose a colour. The snippet updates as you go; paste it before </body> on every page.

The key

How it answers

Any OpenAI-compatible endpoint works. The Cloudflare Worker in the repository is about 40 lines and keeps the key as a secret.

The content

The look

Works on any site that can take a script tag: GitHub Pages, Astro, Hugo, WordPress, Webflow, a plain HTML file.

From your pages to an answer, without a server.

Everything happens in the visitor's browser. Your site only serves static files.

  1. Index

    When you build. npx murmur-rag index reads your HTML or Markdown and writes murmur-index.json: your pages cut into passages under their headings. No index? The widget reads the page it is on.

  2. Search

    In the browser. The question is matched against the passages with keyword search (BM25): accents, plurals and typos are forgiven. The best few go to the model.

  3. Answer

    At the AI provider. The model writes from those passages only, cites them [1] [2] and links to the heading they come from. If your pages do not say it, it says so.

Your AI key never goes in your HTML.

Anything in a web page can be read by anyone. murmur gives you three ways around it.

Your proxy holds it

Deploy the example Cloudflare Worker (free tier) with your key as a secret. It only accepts your site's origin, fixes the model and caps each answer. Visitors chat with no setup.

data-endpoint="https://murmur-proxy.you.workers.dev/v1"

The Worker, ready to deploy

No key at all, by default

Without a proxy, the visitor's browser runs LFM3 1.7B (Liquid AI, October 2026) on WebGPU. About 1.1 GB downloads once, after the visitor agrees; then questions never leave the device. Slower and less precise than a hosted model.

<script type="module" src="…/murmur.js">

LFM3-1.7B

Or the visitor's own key

From the AI settings, visitors can connect a provider with their own key instead. llm-connect encrypts it in their browser (AES-GCM, a key the page cannot export) and sends it only to that provider. data-local="false" offers only this.

data-provider="openrouter" data-local="false"

How llm-connect stores keys

Take the whole thing, or one layer.

murmur-rag is one package with separate entry points. Use the bubble as is, or only the retrieval, or your own model and UI.

murmur-rag
createMurmur: ask a question, get a streamed answer and its sources. No UI.
murmur-rag/rag
Chunking, BM25 retriever, prompt grounding, citations. Bring your own Retriever for embeddings.
murmur-rag/indexer
Index HTML, Markdown or text, in Node or in the browser.
murmur-rag/llm
The llm-connect wiring: proxy settings, the visitor's settings store.
murmur-rag/widget
The <murmur-chat> element, mountMurmur(), the Markdown renderer.
npx murmur-rag index
Index a build folder, a set of files or a live sitemap.xml.
# install, then index your build output
npm install murmur-rag
npx murmur-rag index ./dist --out ./dist/murmur-index.json

// the bubble, from your own bundle
import { mountMurmur } from "murmur-rag/widget";
mountMurmur({ index: "/murmur-index.json", llm: { provider: "anthropic" } });

// or headless, with any AI SDK model
import { createMurmur } from "murmur-rag";
const murmur = createMurmur({ index, model });
const answer = await murmur.ask("What does the Pro plan include?");
for await (const part of answer.textStream) render(part);

What it does not do.

  • Keyword search, not meaningBM25 finds passages that share words with the question. Synonyms it has never seen can miss; plug in your own retriever for semantic search.
  • Small and medium sitesThe index downloads with the first question. A few hundred pages is fine; tens of thousands deserve a search service.
  • Providers that accept browsersIn visitor-key mode the browser calls the provider directly: OpenAI, Anthropic, Google, Mistral, OpenRouter, Groq and local servers do; some providers refuse.
  • Answers are as good as the modelGrounding and citations cut down invented answers, they do not end them. Check what the bubble says about prices or legal matters.
  • The in-browser model is smallLFM3 1.7B needs WebGPU (recent Chrome, Edge, Safari) and about 1.1 GB on first use. It answers in seconds once loaded, with less nuance than a hosted model.

Who wired this board.

GOLFIER MaximeSoftware engineer

murmur is made by Maxime Golfier, who designed and built it. He is a software engineer who specialises in information systems architecture.

  1. IBMHe worked at IBM, where he started as an architect developer.
  2. His own companyHe launched a social network for content creators.
  3. FreelanceNow with companies and startups, from the design of a project to production.

His rule, from his own site: software gets better when it is shared.

  • 195public repositories of his own
  • 442stars on them
  • 170followers
  • 2017on GitHub since January

Mostly TypeScript (68 repositories) and JavaScript (57), then Java, Rust and Shell. His most starred repository is csv-ai-analyzer, an AI CSV analyser that runs in the browser.

His GitHub profile opens on a TypeScript class, ConcreteEngineer, whose whatIDo() owns up: he fixes bugs, sometimes causes them, and keeps learning.

Also by the author, and close to murmur: ephemeral, live rooms and a one-line presence widget for static sites; llm-connect and llm-models, the model layer murmur runs on; hush, end-to-end encrypted messaging; and about two hundred more.

Figures from his public GitHub profile, October 2026.