Unprofane
All comparisons

Unprofane vs bad-words, obscenity and the npm word lists

Even without the model, the rules catch several times what any npm word list catches, and Scunthorpe gets through.

bad-words, obscenity, leo-profanity and @2toad/profanity are open-source npm packages that match a word list, some with basic leetspeak handling, in your own process with no network call.

Toxic text caught, each as shipped
  1. Unprofane89.0%flagging 7.0% of clean text
  2. Unprofane, rules alone53.4%flagging 3.6% of clean text
  3. bad-words9.7%flagging 1.3% of clean text
  4. obscenity8.4%flagging 4.2% of clean text
  5. 2toad-profanity6.1%flagging 0.7% of clean text
  6. leo-profanity5.1%flagging 1.1% of clean text
Disguised spellings caught
86.0%vs2.5% to 7.2%
False positives on innocent words
0.0%vs8.7% to 21.2%

The private test set, 9,029 texts labelled blind, read once on 2026-09-28, engine 2026-09-29. Innocent words: the Scunthorpe Test, run of 2026-10-12. How it was measured

Side by side

The measured rows are the private test set, read once; the rest is what each returns.

WhatUnprofanebad-words and obscenity
Toxic text caught89.0%5.1% to 9.7%
Toxic text caught, rules alone53.4%5.1% to 9.7%
Disguised spellings caught86.0%2.5% to 7.2%
False positives on innocent words0.0%8.7% to 21.2%
Languages17English
Reads usernames: split into words, read backwardsYesNo
Names how each word was disguisedYesNo
Abuse in ordinary wordsYesNo

The private test set, 9,029 texts labelled blind, read once on 2026-09-28, engine 2026-09-29. Innocent words: the Scunthorpe Test, run of 2026-10-12. Every system, every row.

Try to fool it

The real engine, live. Type a disguised word and watch it read, named and judged; type an innocent one and watch it pass.

Every answer carries the same evidence through the API: the words, where they were, how they were disguised and a censored version.

Enter to check

Why Unprofane

  1. 01

    Scunthorpe gets through

    Innocent words that contain a profane string are part of the test, and a filter that blocks one is counted wrong.

    0.0%

    false positives on 1,447 innocent words and phrases, the Scunthorpe Test of 2026-10-12

    • Scunthorpeallow
    • Dickinsonallow
    • cockatooallow
    • Sussexallow
    • shiitakeallow
    • breast cancer screeningallow
  2. 02

    Every trick undone and named

    Not just leetspeak: reversal, look-alike letters, separators and zero-width characters, each named in the answer.

    username

    kcuffuck

    reversedreview · strong

    Shown as ****

  3. 03

    17 languages

    A curated list for each, and a model for abuse written in ordinary words, which no list holds.

    17languages

    • Arabic
    • Chinese
    • Dutch
    • English
    • French
    • German
    • Hebrew
    • Hindi
    • Indonesian
    • Italian
    • Japanese
    • Korean
    • Polish
    • Portuguese
    • Russian
    • Spanish
    • Turkish

When a wrong answer reaches a person, a word list is not enough.

The first call

A test key is free, with a plan or without one. One request, in the language you use, and the answer carries the evidence.

curl -X POST https://api.unprofane.com/v1/check \
  -H "Authorization: Bearer up_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"xXsh1tXx","context":"username","policy":"teen"}'
Open the quickstart

Try it on your own text

Free test keys, 100 checks a day, no card. Live from $9 a month. Every answer shows its evidence.

Other comparisons