"Runs in your browser" is a privacy claim that needs auditing, not trust. Browser-based AI means the computation happens locally, but the browser still makes network requests for many other reasons: loading the app, downloading model weights, fetching fonts, calling remote APIs, sending analytics beacons. An on-device chatbot can still leak your conversation to a server if any part of the pipeline phones home. This post is a practical checklist for figuring out what actually leaves the device — the same audit ReLU.chat's design aims to make trivially passable: no servers, no LLMs, no tracking, MIT-licensed and open source at https://github.com/yunusemrejr/relu-chat.
The Six-Step Audit
Step 1: Inventory the First Load
The most important network traffic happens before you type anything. Open DevTools, switch to the Network tab, and hard-reload the page with an empty cache (Ctrl+Shift+R). Then categorize every request:
- The app's own HTML, JavaScript, and CSS.
- Model weights. An on-device embedding model like all-MiniLM-L6-v2 (quantized ONNX, roughly 22 MB) is fetched once. ReLU.chat's service worker pre-caches the model and policy weights, so the download happens once and subsequent visits load from cache.
- Third-party content: fonts, CDNs, analytics scripts, ad networks.
Anything in the last category deserves scrutiny. A "privacy-first" app should have none of it, or at most self-hosted fonts and resources.
Step 2: Watch a Live Conversation
Now type a message and watch the Network tab while the response streams. Filter to Fetch/XHR and WebSocket to ignore static resources. Ask three questions:
- Does any request fire per message? If yes, where does it go? That request carries the conversation to a server.
- Are there periodic beacons? Some apps send telemetry on a timer regardless of what you type.
- Do the requests carry query text in the URL or body? Inspect the payload of any request you find.
A useful trick is the Performance API, which lists every resource the page loaded without needing to watch the Network tab live:
const resources = performance.getEntriesByType("resource");
const dataCalls = resources.filter(r =>
r.initiatorType === "fetch" || r.initiatorType === "xmlhttprequest"
);
console.table(dataCalls.map(r => ({
url: r.name,
size: r.transferSize
})));
Step 3: Go Offline and Keep Talking
The single most convincing test is to cut the network. In DevTools, open the Network tab, set throttling to "Offline", reload the page, and have a conversation.
- If chat still works, inference is genuinely local: the model, the retrieval index, and the policy all live in the page or the service worker cache.
- If the page refuses to load at all, check whether the service worker was installed on a previous visit (Application tab → Service Workers). A properly pre-cached app loads fully offline.
- If the page loads but responses stall or error, something in the pipeline needs the network — a remote LLM, a search API, or an analytics endpoint that fails loudly.
ReLU.chat's service worker pre-caches model and policy weights precisely so that the heavy lifting works from cache; the three chatbots — Game Theory Chat, Golden Age Inquiry, and Data Science Chat at https://relu.chat/chat/game-theory-chat/, https://relu.chat/chat/golden-age-inquiry/, and https://relu.chat/chat/data-science-chat/ — plus the interactive ML tools at https://relu.chat/tools/ are designed to run fully in-browser.
Step 4: Audit Storage and Persistence
Network is not the only channel. Browsers provide several persistent stores, and each one can hold data you did not expect:
- localStorage and sessionStorage — check the Application tab. Is a transcript being written to disk? Is it cleared when you leave the site? Does a "clear conversation" button actually wipe it?
- IndexedDB — commonly used by ML pipelines for caching; inspect its contents.
- Cache Storage — this is where service worker caches live. Cached model weights are fine; a cached transcript is data-at-rest you should know about.
For a chat app, ask: after closing the tab and reopening, does the conversation come back? If yes, it was persisted somewhere — find out where and whether clearing site data removes it. Session-only memory is the stricter privacy posture: state lives in the running page and evaporates with the tab.
Step 5: Read the Source
Closed-source claims of privacy are unverifiable. Open source is the only way to confirm that the code does what the landing page says. For ReLU.chat the repo is at https://github.com/yunusemrejr/relu-chat under the MIT license. When auditing a browser-AI project, look for:
- Hardcoded API endpoints: search the source for
fetch(,axios,WebSocket,XMLHttpRequest, and URL strings pointing at external hosts. - Third-party scripts included from other domains in the HTML head.
- Telemetry libraries (analytics, crash reporting, session replay) that initialize on page load.
- The model itself: where do the weights come from, and is the runtime (ONNX Runtime, transformers.js, WebGPU) doing inference locally?
The point of the audit is not to find malicious code — it is to confirm the absence of anything that transmits user data, because that is a property you can only verify, never assume.
Step 6: Consider the Residual Risks
Even a perfectly local app has a small residual surface:
- The model weights themselves reveal nothing about the user, but their download footprint is visible to the network operator (only that a download happened, not its content).
- The page's JavaScript can be updated by a future deployment; a privacy audit is a snapshot, not a guarantee. Pin versions and re-audit after updates.
- Browser extensions and the browser's own telemetry are outside the site's control.
None of these undermine the on-device model; they just mean "verified today" rather than "true forever".
Key Takeaway
Privacy in browser-based AI is a checklist, not a slogan: inventory the first load, watch a live conversation for per-message requests, test offline, audit storage, and read the source. An open-source, serverless design — no LLM calls, no tracking, weights pre-cached by a service worker — makes every step of that checklist trivially green, which is exactly what a privacy-first chatbot should do.