A multi-language profanity filter with full TypeScript support
Install the package
npm i @2toad/profanity
If you're using Node 11.x or older, you'll need to install Profanity 1.x
import { profanity, CensorType } from '@2toad/profanity';
// or
const { profanity, CensorType } = require('@2toad/profanity');
profanity.exists('I like big butts and I cannot lie');
// true
profanity.exists('I like big glutes and I cannot lie');
// false
profanity.censor('I like big butts (aka arses) and I cannot lie');
// I like big @#$%&! (aka @#$%&!) and I cannot lie
profanity.censor('I like big butts (aka arses) and I cannot lie', CensorType.FirstChar);
// I like big *utts (aka *rses) and I cannot lie
Create an instance of the Profanity class to change the default options:
import { Profanity } from '@2toad/profanity';
const profanity = new Profanity({
languages: ['de'],
wholeWord: false,
grawlix: '*****',
grawlixChar: '$',
});
By default, this is set to ['en']
(English). You can change the default to any supported language, including multiple languages:
const profanity = new Profanity({
languages: ['en', 'de'],
});
You can override this option by specifying the languages in exists
or censor
:
profanity.exists('Je suis un connard', ['fr']);
// true
profanity.censor('I like big butts and je suis un connard', CensorType.Word, ['en', 'de', 'fr']);
// I like big @#$%&! and je suis un @#$%&!
If no languages are specified in the method call, it will use the languages specified in the options.
By default, this is set to true
so profanity only matches on whole words:
profanity.exists('Arsenic is poisonous but not profane');
// false
Setting this to false
, results in partial word matches:
profanity.exists('Arsenic is poisonous but not profane');
// true (matched on arse)
Profanity detection works on parts of compound words, rather than treating hyphenated or underscore-separated words as indivisible.
When wholeWord
is true
, each portion of a compound word is analyzed for a match:
profanity.exists("Don't be an arsenic-monster");
// false
profanity.exists("Don't be an arse-monster");
// true (matched on arse)
Setting wholeWord
to false
, results in partial word matches on each portion of a compound word:
profanity.exists("Don't be an arsenic-monster");
// true (matched on arse)
When wholeWord
is true
, this controls whether word boundaries are Unicode-aware. By default this is set to false
due to the performance impact.
- When
false
(default), whole-word matching uses ASCII-style boundaries (similar to\b
) plus underscore_
as a separator. This is fastest and ideal for ASCII inputs. - When
true
, whole-word matching uses Unicode-aware boundaries so words with diacritics (e.g.,vehículo
,horário
) and compound separators are handled correctly.
const profanity = new Profanity({ unicodeWordBoundaries: true });
profanity.exists('vehículo horario');
// false (does not match on "culo" inside "vehículo")
By default this is set to @#$%&!
:
profanity.censor('I like big butts and I cannot lie');
// I like big @#$%&! and I cannot lie
Setting this to ****
, results in:
profanity.censor('I like big butts and I cannot lie');
// I like big **** and I cannot lie
When specifying a CensorType
other than CensorType.Word
, this is the character used by the censor
function.
By default this is set to *
:
profanity.censor('I like big butts and I cannot lie', CensorType.AllVowels);
// I like big b*tts and I cannot lie
Setting this to $
, results in:
profanity.censor('I like big butts and I cannot lie', CensorType.AllVowels);
// I like big b$tts and I cannot lie
Add words:
profanity.addWords(['aardvark', 'zebra']);
Remove words:
profanity.removeWords(['butt', 'arse']);
The whitelist allows you to specify words that are always ignored by the profanity filter.
This can be useful if you want to enable partial word matching (
wholeWord = false
), so combined words are caught (e.g., arselicker), while specific words you add to the whitelist are ignored (e.g., arsenic).
Add words to the whitelist:
profanity.whitelist.addWords(['arsenic', 'buttress']);
Remove words from the whitelist:
profanity.whitelist.removeWords(['arsenic', 'buttress']);
To see how Profanity performs, check out our benchmark results.
So you want to contribute to the Profanity project? Fantastic! Please read the Contribute doc to get started.