What Leaves the Browser—and Why

For NextChat, “local-first” describes where the application keeps its working state; it does not describe every place a prompt, credential, or generated result may go. This chapter separates local persistence from provider processing, then compares export, synchronization, and deployment choices so readers can identify the data boundary of a particular setup. The practical goal is to choose portability or convenience without assuming that either one comes with security properties the open-source path does not show.

What stays in the client by default

NextChat’s ordinary conversation state is held in client-side stores. Sessions contain messages, masks, model settings, summaries, and the metadata needed to decide what belongs in a later request. Other stores hold access settings, prompts, plugins, and synchronization configuration. The persistence layer uses IndexedDB and falls back to local storage when IndexedDB is unavailable or fails. In a browser, this means the working archive can exist without a central NextChat chat database.

That design has two consequences that pull in opposite directions. It gives the user direct control over the local archive: conversations can be created, forked, cleared logically, configured, and exported from the client. It also makes the browser profile part of the trust boundary. The repository’s storage helper serializes state as JSON; the inspected path does not add encryption for IndexedDB or local storage. A person who controls or compromises the relevant browser profile may therefore have access to data that the application calls local.

The same distinction applies to files. The service worker handles cache requests for uploaded images or audio by placing them in same-origin CacheStorage and returning a local URL. If that path is unavailable, the image helper can compress an image in the browser and use the resulting data in the request instead. These are different storage and transmission behaviors, even though both begin with an attachment in the chat box. A local cache URL is not evidence that the model will not receive the image; it only describes how the client prepares the content.

The provider request is the first unavoidable outward path. NextChat selects a context, translates it for the chosen model, and sends it through either a server-mediated route or a more direct desktop path. The provider must receive the selected request to produce a response. It may not receive the entire locally stored session, because the context policy can omit old messages, but it can receive system instructions, mask prompts, recent history, summaries, images, and the current input when those items are selected.

This is why the question “Is the chat stored locally?” is incomplete. It describes the archive, not the processing event. A user may keep the full transcript in a browser while sending a much smaller constructed request to a provider. Conversely, a local-first application can still disclose sensitive content through that request if the user includes it in the active context. Storage locality and provider locality are separate properties.