unikeys

Privacy

What leaves your Mac

Your keybindings never do. unikeys reads and writes config files entirely on your own machine. It has no account, no server of its own, and no sync. The only thing it can send anywhere is a short list of counts about how the app itself is used — and only if you answered yes when it asked.

Last updated 22 October 2026

The app

unikeys is a macOS app that edits the keyboard-shortcut config files of editors and terminals you already have installed. Everything it touches stays in your own file system:

  • Config files are read from, and written to, the locations those apps already use. unikeys asks you to pick each folder it reads, through macOS's own folder picker, and in the App Store build macOS itself enforces that — it can reach nothing you have not handed it.
  • Backups of each file are copied, before the first write of a session, into ~/Library/Application Support/unikeys/backups.
  • Your settings — which apps are enabled, your chord choices, granted folders — live in a single JSON file at ~/Library/Application Support/unikeys/unikeys-store.json.

There is no sign-up, no login, and no payment. unikeys does not upload, index, or transmit the contents of any config file, any folder name, or any shortcut you type.

Deleting the app and the ~/Library/Application Support/unikeys folder removes everything unikeys has stored about you, including its backups and its analytics identifier.

Usage analytics in the app — opt-in

On first run, unikeys asks whether it may report anonymous usage. Until you answer, nothing is sent, and a declined or unanswered question both end in the same silence. You can change the answer at any time in Settings → Anonymous usage.

When it is on, events go to PostHog (PostHog Inc., United States), which we use as our analytics processor. Three things are true of every event:

  • The identifier is a random UUID minted on first run and stored only in your local settings file. It is not your hardware UUID, hostname, username, email, or anything else derived from you or your machine.
  • Your IP address is replaced before the event is sent. unikeys attaches a placeholder (0.0.0.0) so that PostHog's ingestion cannot fill in the address your request arrived from. No location is derived, coarse or otherwise.
  • The payload is a fixed allowlist. Each event may carry only the properties listed below; anything else is stripped in code before sending, not by policy.

Every event unikeys can send

Event What it carries
app_launched How many apps are enabled (a number).
onboarding_started Nothing.
onboarding_step_completed Which of the four setup steps finished.
onboarding_completed How many apps were selected, and how many were granted access.
onboarding_dismissed Which step it was abandoned at.
grant_outcome Which supported app a folder was requested for, and whether it was granted, cancelled, or failed. Never the path, and never the error text.
bindings_imported Counts only: apps read, apps failed, actions found, rows where apps disagree.
row_matched The catalogue id of the action you matched — an identifier unikeys itself ships, such as edit.format-document — and whether it needed you to pick a winner. Never the chord.
save_completed Counts only: apps written, apps failed, bindings written, skipped, and dropped.
save_reverted How many apps were restored from backup.
app_toggled Which supported app was switched on or off.
app_active_daily Nothing of its own. Sent at most once per calendar day while unikeys is running, so that active installs can be counted. It is not tied to your name, account or IP address.
analytics_opt_in / analytics_opt_out Nothing beyond the fact that you changed your mind.

Alongside those, each event carries the release channel (App Store or direct download), the unikeys version, your major macOS version (26, not 26.1.2), and whether the build is sandboxed.

What is never sent, under any circumstance

  • File paths of any kind, including config paths, backup paths, and anything from your home directory
  • The contents of a config file, or any fragment of one
  • Obsidian vault names, or any other folder name
  • Chords you authored, or any keystroke capture
  • Your machine name, username, macOS serial, or IP address
  • Error messages from the file layer — they name paths as a matter of course

This is enforced in the source, in src/shared/analytics.ts, which defines the closed list above and drops anything not on it. You are welcome to read it yourself.

The Mac App Store build behaves the same way. It sends the events above only if you opted in, and nothing at all otherwise.

Development builds are also excluded, so that working on unikeys does not pollute the data it is changed on the strength of.

This website

The unikeys site — including this page — is a set of static files served by GitHub Pages, and it uses the same PostHog project for visitor analytics. Web analytics is separate from the app's, and it is not opt-in. What runs here:

  • Page views and clicks. PostHog's autocapture records page views and interactions with the page's own elements, plus explicit events when you click a download or an outbound link. The DOM here contains nothing but public marketing copy.
  • Session replay. Sessions on this site are recorded so that layout and navigation problems can be diagnosed. All form inputs are masked, and recordings are deleted after 30 days.
  • Approximate location. Unlike the app, the site does not overwrite your IP address. PostHog records it on ingestion and derives a coarse country/region from it.
  • Console messages, performance timings, and heatmap data for the pages you visit.
  • Cookies and local storage. PostHog sets a first-party cookie to recognise a returning browser. No advertising or cross-site tracking cookies are set.

Site analytics events are retained for 12 months. Requests go directly to us.i.posthog.com; blocking that host — with a content blocker, or by disabling JavaScript — stops all of the above, and the site works fine without it.

Who else sees any of this

Two companies are involved, and neither of them because the data was sold to them:

  • PostHog Inc. (United States) processes the analytics described above on our behalf.
  • GitHub, Inc. serves this website and hosts the app downloads, and so handles the ordinary server logs any web host does.

Nothing is sold, rented, or shared for advertising. There is no ad network, no data broker, and no third-party tracker on this site beyond the two named above. Data may be disclosed if the law compels it.

Your choices

  • In the app: Settings → Anonymous usage turns reporting off. Reporting stops immediately, the client is torn down, and nothing further is queued or sent.
  • Delete everything the app stores: remove ~/Library/Application Support/unikeys. The analytics identifier lives in unikeys-store.json and goes with it.
  • On the site: block us.i.posthog.com, or browse with JavaScript disabled.

If you are in the EU, UK, or a comparable jurisdiction and want to exercise a right of access, correction, or erasure, email ronkamail@gmail.com. Please include the distinctId value from your unikeys-store.json — because the data is deliberately not linked to a person, that identifier is the only way to locate an installation's events, and without it there is nothing to search on.

Children

unikeys is a developer tool and is not directed at children under 13, and we do not knowingly collect anything from them.

Changes

If what unikeys collects changes, this page changes with it and the date at the top moves. Because the app's collection is defined by the allowlist in the source, the history of that file is a second, harder-to-fudge record of the same thing.

Contact

unikeys is built by ronka, an individual developer. Questions, corrections, and requests: ronkamail@gmail.com, or open an issue at github.com/ronka/unikeys/issues.