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 inunikeys-store.jsonand 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.