Privacy

What Kingfisher collects — and what it does not.

Kingfisher is local-first. Studies, repertoire, training, notes, recent work and preferences are stored in the browser profile or in the desktop application's local profile directory. Nothing about you or your work is sent to a Kingfisher server, because there is no Kingfisher server.

Short version

  • No account. You do not sign in. There is no sign-in to sign in with. The application does not know who you are.
  • No telemetry. No analytics, no error reporting service, no session replay, no “is the user still here?” pings. The web build does not load any third-party script.
  • Feedback is user-initiated. The in-app Feedback button is a deliberate channel you open yourself. Nothing leaves the browser until you click Send. SeeFeedback for what the submission carries and where it goes.
  • No cookies. The web build does not set any cookie. Application state lives in localStorage and IndexedDB, scoped to the origin.
  • No advertising. Nothing on the page or in the application is, was, or will be an advertisement.
  • No client-side fingerprinting. No canvas fingerprint, no font enumeration, no hardware concurrency probes, no timezone sniff, no IP-to-country map, no “we know its you because of your machine.”

Local storage

User-authored data — your studies, chapters, repertoire moves, training items, model games, recent positions, notes and preferences — is stored in the browser or in the desktop profile. It is held under the application's own storage key and never read by another origin. The structure is documented in AGENTS.md and the schema is versioned.

A localStorage entry holds the small key/value preferences (theme, piece set, board theme, sound level, last-active route). The contents are visible in the browsers developer tools and are an inert JSON object with no PII beyond what you yourself typed (a study name, a repertoire name).

The bulk of your work is in IndexedDB. IndexedDB is origin-scoped, so a profile on kingfisherchess.app is not the same database as one on kingfisher-roan.vercel.app (the address the application had before 2026-09-13, which keeps serving so that work stays reachable) or one on localhost. If you move between them, the work does not move with you — the supported way to move work between machines, profiles and addresses is the Settings → Database → Export backup / Import backup flow, which produces and consumes a versioned JSON file under your control.

Reference cache

When you use the Explorer or a pack query, the application caches the response bytes in IndexedDB so a second query of the same shard does not redownload. The cache is byte-budgeted and is cleared on a fixed schedule. The cached bytes are not attributed, are not exported with your work and are not considered user data. They are technical infrastructure for the product.

The cache is the same origin-scoped database as everything else; it does not sync.

Network requests

The web and desktop builds do not phone home. The only outbound network calls the application makes are the ones the product needs:

  • Lichess (when you sign in or query Lichess-hosted resources):lichess.org, api.chess.com, tablebase.lichess.ovh,explorer.lichess.ovh. Each call is made because the user asked for the answer. Sign-in uses OAuth with PKCE and no scopes beyond “read your games”; the token is stored in IndexedDB and never leaves the device.
  • The public data mirror atmardakurt.github.io/kingfisher-data for reference-pack manifests and chunks. Every chunk is verified against the manifests SHA-256 before it is used. A failed verification is reported and the bytes are discarded.
  • The application's own origin for the static assets (Stockfish WASM, piece art, the marketing/landing assets, the app code itself).

The Content-Security-Policy in vercel.json is the enforced allow-list. Any other host is refused at the browser layer, and the desktop companions loopback server is a separate trust boundary with its own authentication.

Cookies and trackers

The web build sets no cookies in the strict sense: noSet-Cookie response header, no document.cookie writes, nohttpOnly session. The application uses localStorage and IndexedDB instead. The browser may still hold its own state (service worker cache, IndexedDB) which is required for the product to work across reloads.

No third-party tracker, analytics or advertising tag is loaded. A network panel open during a normal session will show Lichess (if you have signed in or queried Lichess), the data mirror (if you have used a reference source) and the application's own origin. Nothing else.

Hosting

The web build is hosted on Vercel. Vercel sees every request the way any hosting provider does, and the request log will contain the IP address you connected from, the URL you requested and the user agent your browser sent. Vercel's own data-handling is described in their privacy policy; the Kingfisher project does not put anything additional in those logs. There is no Kingfisher-side server processing them.

Account status

There is no Kingfisher account, no sign-in, no profile, no email capture, no mailing list. If a Kingfisher-controlled account is ever added, this page will be updated before any data is collected.

Sync status

Cross-device Sync is not currently available. Your work lives on the machine you created it on. To move work between machines:Settings → Database → Export backup on the source machine;Settings → Database → Import backup on the destination machine. The backup file is portable JSON and is under your control at all times.

Feedback

The in-app Feedback dialog sends a single submission only when you press theSend feedback button. Nothing is uploaded automatically, and the form does not open a connection on its own.

The submission carries:

  • The category you picked (one of five).
  • The message you typed, up to 4000 characters.
  • The current board position (FEN) — only when you tickInclude current position. The default is off.
  • A short technical-information block (app version, surface, browser, viewport, storage state) — only when you tick Include technical information and preview it before sending.

The submission never carries your games, studies, chapters, repertoire, training items, notes, preferences, Lichess or companion credentials, or filesystem paths.

Where it goes: when the operator has configured the secure sink (a fine-grained GitHub token scoped to a single feedback repository), the submission is forwarded there server-side, never from the browser. When no sink is configured, the submission is validated, acknowledged with a reference handle, and the operator sees it in the server log; the dialog also offers an “Open GitHub feedback” button that opens a pre-filled issue in a new tab.

The endpoint enforces same-origin requests, a 64 KB body ceiling, a per-IP rate limit, a minimum form-fill time, and a honeypot field the dialog never fills. The renderer never sees the GitHub token. The fallback link is the user's explicit choice, not an automatic redirect.

Children

Kingfisher is not directed at children. The application does not knowingly collect information from children, because it does not collect information from anyone.

Changes

If a future Kingfisher change affects this policy, the change will be listed inCHANGELOG.md and this page will be updated before the change ships.

Contact

There is no Kingfisher-controlled inbox for privacy requests. For a security issue, seeSecurity. For a non-security question, open an issue onGitHub.