Privacy
This page describes how Private Local Chat works today, written from the deployed app and its hosting setup. It says what stays on your device, what leaves it, and who receives it.
The short version
- With on-device chat, your messages are processed in your browser and are not sent to a server to generate replies.
- With a connected provider, the content of each request goes straight from your browser to that provider, and its practices apply.
- Conversations, documents and preferences are saved in your browser on your device. The app has no account system and no analytics or tracking scripts.
- Files you create (exports, backups, settings files) and links you share can be read by whoever holds them, except where this page says a part is encrypted.
- The site is hosted on Cloudflare, which handles ordinary web-server request data under its own policy.
Text processing on your device
In on-device mode the selected model (Qwen3.5-2B or Qwen3.5-9B) runs in your browser, on your graphics card or, for the smaller model where no graphics card is usable, on your processor. The conversation, the instructions, your memory items and the text of attached documents are used there and are not uploaded to generate a reply. Attached documents are read, indexed and searched on the device. On-device mode never falls back to a connected provider by itself.
Connected providers
If you set Where replies run to Connected provider, each request is sent from your browser directly to the endpoint you entered. It contains the model name, the messages of the conversation, your standing instructions and other context the app adds (such as memory items, summaries of earlier messages and excerpts of attached documents) and, where the provider accepts them, attached pictures. Your API key is sent to that endpoint in an authorization header. The app also asks the endpoint for its list of models. The requests do not pass through Private Local Chat's servers. The provider's terms, retention and charges apply to those requests; read them before you send anything sensitive.
Speech services in your browser
Dictation and voice conversation use the speech recognition built into your browser, and read-aloud uses the voices your browser or device offers. Speech recognition may send audio to the browser's own speech service (for example Apple's on an iPhone, or the service of your browser's maker elsewhere), under that company's terms. Voices marked “online” in the voice list may also use a remote service. Private Local Chat does not record or store audio itself: recognised words are placed in your message. Where speech is processed is separate from where the reply is written, so voice with an on-device model does not mean that voice never leaves the device. The controls are hidden in browsers that do not offer speech recognition.
App and model downloads
Downloads are ordinary web requests. Like any web request they reveal your network address and browser details to the host. They carry no conversation content and need no account.
| What | From | Requested by the deployed app |
|---|---|---|
| The app, these pages, icons and the on-device model runtimes | privatelocal.chat (Cloudflare Pages) | Yes. The app also fetches a small version.json from the same site to learn whether a newer version exists. |
| Model files, model configuration and compiled model libraries, checked against pinned SHA-256 hashes | assets.privatelocal.chat (the project's own storage, on Cloudflare R2) | Yes, when you set up on-device chat. |
| Original model files (Hugging Face, huggingface.co) and the compiled WebLLM library (raw.githubusercontent.com, the MLC project's repository) | Hugging Face and GitHub | No. The open-source model catalogue lists them as the origin of the files, and the app's built-in defaults point there, but the deployed page is configured to use assets.privatelocal.chat instead. |
| The smaller model's original repackaged files (media.techofourown.com, the owner's media host) | media.techofourown.com | No. Same as above: a catalogue default that the deployed page replaces with assets.privatelocal.chat. |
| Your connected provider, if you choose one | The endpoint you entered | Only in connected-provider mode. See Connected providers. |
PDF reading, search, the QR code encoder and all fonts and icons are bundled with the app: no third-party fonts, scripts, images or stylesheets are loaded. Downloaded model files are stored in your browser; see What is stored in your browser.
What is stored in your browser
Everything below lives in your browser's storage on this device, for this site only. Each browser and device has its own copy, and clearing site data removes it. The app's code sets no cookies and has no account system.
| Data | Where | Notes |
|---|---|---|
| Conversations | Local storage: chatThreads; selected conversation plc.activeThread.v1; unsent drafts plc.drafts.v1 | Temporary chats are never written. |
| Preferences, memory, presets, projects | Local storage: plc.prefs.v1, plc.memory.v1, plc.presets.v1, plc.folders.v1 | Memory is explicit and editable. |
| Attached files and the document library | IndexedDB database plc-docs | A temporary chat's files stay in memory only. |
| API settings and keys | Session storage: chatConfig (endpoint, key, model, theme), chatEndpointTokens (keys by endpoint), chatModels | Kept for the browser session, not in the long-term storage used for conversations. Backups and chat exports do not contain them. |
| Model files | The browser's origin private file system and Cache Storage | Reused until you remove them (see model storage) or the browser clears them. |
| A copy of the app for offline use | Cache Storage (a service worker cache) | Includes these public pages. |
| App lock | Local storage: plc.lock.v1 | A salted check value, never the passphrase. See App lock. |
| Small settings | Local storage: plc.inferenceMode.v1 (where replies run), plc.downloadIntent.v1 (a download to resume), plc.speechInputUnusable (speech controls hidden) |
App lock
App lock puts a passphrase screen over the app and can lock it when idle or when you are away. It is a screen lock: it does not encrypt what the browser stores, so someone with access to the browser's files can still read saved conversations and documents. A forgotten passphrase cannot be recovered; the only way back in is to erase the app's data in this browser and restore a backup.
Encrypted backups
An encrypted backup is created on your device with the browser's own cryptography (a key derived from your passphrase with PBKDF2-SHA-256, then AES-256-GCM). The passphrase and the unencrypted data are not sent anywhere, and nobody, including the people who run Private Local Chat, can open the file without the passphrase. It includes conversations, projects, memory, presets and some preferences, and attached documents if you choose. It does not include API keys, provider settings or model files. You choose where the file is saved. A forgotten passphrase cannot be recovered.
Chat exports
An ordinary export of your conversations is a readable file. Anyone who can open the file can read what it includes, so choose where to save it and who to give it to. Answers, tables and code saved as files are plain files too. The app does not upload exports; what happens to a file afterwards depends on where you put it.
Product sharing
Share, Copy link and Show QR code always use the same fixed public information: the address https://privatelocal.chat/, the name Private Local Chat and one public sentence about the app. They are not built from the page you are on, your conversations, your settings, your keys or any imported transfer. The QR code is drawn on your device. With Share, your device's sharing screen receives that information and passes it to the app or contact you pick, under that service's own terms.
Transferring settings
Transfer settings creates a link, QR code or settings file that carries your endpoint address, model name and theme, and optionally your API key. The endpoint, model and theme are readable by anyone who has the link, QR code or file. If you include the API key, it is encrypted with a password you choose (PBKDF2-SHA-256 and AES-256-GCM), so give the recipient the password by a different route than the link. The password and the plain key are used on your device while the transfer is made and are not sent anywhere.
The link carries its data after the # in the address. Browsers do not include that part when they request the page, so it is not sent to the website's server by the page request. It is still in the link, so the apps and services you paste it into can see it, and the importing app removes it from the address bar after reading it. If the key cannot be unlocked at import, the encrypted key is kept for the browser session so you can try again, and you can discard it.
Older links
Links created by earlier versions of the app put the settings, including an API key that was only encoded and not encrypted, after a ? in the address. Browsers send that part to the web server when the link is opened. The app can still read such links. Avoid sharing them, and replace a key that was shared that way.
Support submissions
Bug reports and feature requests are made on GitHub Issues. They are public, need a GitHub account and are handled under GitHub's policies, so leave out API keys and private conversations. Copy device details in the app only copies a summary of your device, browser and model state to your clipboard; nothing is sent until you paste it somewhere. Where the Help page offers an email address, a message you send goes from your own email app to that address.
Hosting, logs and analytics
The site is served by Cloudflare Pages, and the model files by project storage on Cloudflare. When your browser asks for a page or a file, the host receives standard web-server request data, such as your network address, the address requested, your browser and device type, the time and the page you came from. The hosting provider handles that data under its own retention policy: Cloudflare's privacy policy. This page does not state log retention periods, because they are set by the provider and the hosting account rather than by the app.
The app itself contains no analytics, advertising or tracking scripts and sets no cookies. A review of the source for this release found its network requests to be only those listed above: its own files, version.json, model files from assets.privatelocal.chat and, in connected-provider mode, your chosen provider. Features that a hosting account can switch on at the provider's edge are outside the app's code. The separate development site includes developer diagnostics; they are excluded from this site's build, which an automated test checks.
Changes to this page
This page is updated when the app or its hosting changes. The date at the top says when it was last reviewed, and Updates records changes to the app. Questions: contact.