Skip to content
HN On Hacker News ↗

I Dumped Apple's Fucking Word List

▲ 162 points • 98 comments • by speckx • 2d ago • HN discussion ↗

Pangram verdict · v3.3

We believe that this text is a mix of AI and human-written content.

76 %

AI likelihood · overall

Mixed
24% human-written 76% AI-generated
SEGMENTS · HUMAN 5 of 28
SEGMENTS · AI 23 of 28
WORD COUNT 790
PEAK AI % 100% · §2
Analyzed
Nov 3
backend: pangram/v3.3
Segments scanned
28 windows
avg 28 words each
Distribution
24 / 76%
human / AI fraction
Verdict
Mixed
Pangram v3.3

Article text · 790 words · 28 segments analyzed

Human AI-generated
§1 Human · 0%

I Dumped Apple's Fucking Word ListNovember 3, 2026TL;DR ~/Library/Keyboard/VulgarWordUsage.db is real.

§2 AI · 100%

It records which swear words you use, per app and per recipient, so autocorrect learns to stop "ducking" you. On my Mac it is empty, and typing swear words into a native app did not fill it.

§3 AI · 100%

The interesting part is upstream.

§4 AI · 100%

Apple's system dictionary flags every word with one of three tiers (vulgar, offensive, sensitive) and up to eleven topic flags (sex, drugs, religion, politics, violence, …). There is no public API for any of it. I read the flags with a few private C functions from Lexicon.framework.

§5 AI · 100%

Code below, in C and in Swift.

§6 AI · 100%

The full dumps for 15 languages are in this gist (uncensored, so mind the content warning).

§7 AI · 100%

Highlights: Oedipus is vulgar.

§8 AI · 98%

Tom and Mick are offensive. pee, poo, niggle and underling are sensitive.

§9 AI · 100%

And "Trump" is the only living politician in the English sensitive tier, next to Hitler, Mao, Osama bin Laden and the Taliban. Biden, Obama and Putin are clean.

§10 AI · 100%

Content note: this article prints the words uncensored, slurs included, because the whole point is to see what Apple flags. The one exception is the n-word: it is in the list in English and several other languages, and I'm not writing it out. It started with a tweet Nick posted this, I asked where it lives, and he answered. A database that tracks my profanity is not something I can leave alone, so I opened mine.

§11 Human · 0%

The database $ sqlite3 -readonly ~/Library/Keyboard/VulgarWordUsage.db .schema CREATE TABLE properties (ROWID INTEGER PRIMARY KEY, key, value, UNIQUE (key)); CREATE TABLE IF NOT EXISTS "vword_usage" ( ROWID INTEGER PRIMARY KEY AUTOINCREMENT, app TEXT, -- app identifier recipient TEXT, -- recipient identifier vword TEXT, -- vulgar word word_reading TEXT, -- the reading form of a word (relevant for Japanese) usage_count INTEGER DEFAULT 0, last_use_timestamp REAL DEFAULT 0, -- last use timestamp (seconds since the reference date) journaled ); CREATE UNIQUE INDEX app_recipient_vword_word_reading_idx ON vword_usage(app, recipient, vword, word_reading); So the keyboard can know that you say fuck in Messages to one particular friend, but not in Mail to your boss.

§12 AI · 100%

The unique index is on (app, recipient, word, reading), so that is the granularity. Mine has zero rows.

§13 AI · 100%

The properties table holds version = 2 and nothing else. The file was last written in April 2024. What it is for At WWDC in June 2023, Craig Federighi announced the iOS 17 autocorrect rewrite with this line: "In those moments where you just want to type a ducking word, well, the keyboard will learn it, too."

§14 AI · 100%

(TechCrunch, NPR) This database is how it learns.

§15 Human · 0%

The symbol names in the macOS shared library cache spell out the flow: TI::VulgarWordUsageDatabaseWrapper::set_current_app_id(CFString) TI::VulgarWordUsageDatabaseWrapper::set_current_recipient_ids(vector<string>) TI::VulgarWordUsageDatabaseWrapper::increment_usage_count(word, reading, recipients) TI::VulgarWordUsageDatabaseWrapper::decrement_usage_count(...) TI::VulgarWordUsageDatabaseWrapper::can_autocorrect(word, app, recipients) TI::VulgarWordUsageDatabaseWrapper::can_autocorrect_somewhere(word, reading) KB::FilterNonVulgarIfTopCandidateVulgar::filter_candidates(...) KB::Candidate::every_vulgar_word_is_allowlisted(VulgarWordUsageDatabaseWrapper*, ...)

§16 Human · 0%

Plus log strings like Passing recipient IDs to the vulgar word usage database wrapper; number of IDs: %lu.

§17 AI · 100%

In plain terms: When you start typing, the keyboard engine tells the wrapper which app you're in and who you're writing to. When you type a vulgar word and keep it, its count goes up for that app and those recipients. Undoing the word brings the count back down. When the engine ranks suggestions, it asks whether every vulgar word in a candidate is allowlisted for this context. If it isn't, the clean alternative wins: ducking.

§18 AI · 100%

A _KSUserWordsSynchroniser sharedAcrossLanguagesVulgarWordUsageValue symbol suggests it syncs between devices like your other learned words.

§19 AI · 100%

Mine is empty I tried to fill it.

§20 AI · 89%

Using agent-desktop, I opened a new TextEdit document and typed well fuck this shit, damn it., first as a text insert, then as individual key presses.

§21 AI · 100%

Nothing changed: no row, no log line, and the file's modification date stayed in 2024. I don't know why, and I couldn't work it out. Maybe the Mac never records anything here, or maybe it only does so in some apps or settings. If you've got rows in yours, tell me what you did.

§22 AI · 100%

That would be a short article. But the database only counts words that are already known to be vulgar.

§23 AI · 100%

So who decides that?

§24 Human · 0%

Where the word list lives Searching the dyld shared cache for "vulgar" turned up a C API with an LX prefix (LXVulgarWordUsageDatabaseCreate, LXVulgarWordUsageDatabaseCanAutocorrect, …) and, more usefully, two functions on dictionary entries: _LXEntryGetCategoryFlags _LXEntryGetMetaFlags LX is Lexicon.framework, a private framework that reads the per-language dictionaries under /System/Library/LinguisticData/.

§25 AI · 100%

Every word in those dictionaries is an LXEntry with two 32-bit flag fields.

§26 AI · 100%

If the vulgarity rating is anywhere, it's in those bits. There is no public API I looked.

§27 AI · 100%

NSSpellChecker, UITextChecker, NaturalLanguage and UILexicon don't expose vulgarity. SensitiveContentAnalysis covers images and video, not text. The only places "profanity" shows up on developer.apple.com are App Store age ratings and review guidelines.

§28 AI · 100%

So: private functions.