ainosha-badwords
v1.0.6
Published
Simple bad word filter for ReactJS and React Native
Downloads
65
Maintainers
Readme
badword-filter
A lightweight bad word filter supporting English, Vietnamese, and Finnish.
Works seamlessly in both ReactJS (Web), React Native (Mobile), and NodeJS.
✨ Features
- 🚫 Advanced Detection: Detect bad words with leetspeak, obfuscation, and partial matching
- 🔒 Smart Sanitization: Sanitize text with configurable masking and severity-based filtering
- 🌍 Multi-language Support: English, Vietnamese, and Finnish word lists
- 🎯 Severity Levels: Categorize words by severity (low, medium, high, extreme)
- ⚪ Whitelist Support: Allow specific words in context
- 📊 Statistics & Analytics: Track usage patterns and most common words
- ⚙️ Flexible Configuration: Customize detection modes and thresholds
- 🔧 Word Management: Add, remove, import, and export word lists
- ➕ Dynamic Updates: Modify filter behavior at runtime
- ⚡ Framework-agnostic: Works with React, React Native, or plain NodeJS
📦 Installation
npm install badword-filter
or yarn add badword-filter
text
🚀 Usage
NodeJS Example
import { BadWordFilter } from "badword-filter";
// Basic English filter
const enFilter = new BadWordFilter(["en"]);
console.log(enFilter.containsBadWord("This is shit!"));
// true
console.log(enFilter.sanitize("This is shit!"));
// This is ****!
// Advanced configuration
const advancedFilter = new BadWordFilter(["en"], ["customword"], {
mode: "strict",
detectLeetspeak: true,
detectObfuscation: true,
severityThreshold: "medium",
customMask: "█",
whitelist: ["assassin"], // Allow "ass" in "assassin"
});
console.log(advancedFilter.containsBadWord("f*ck this sh!t"));
// true (detects leetspeak)
console.log(advancedFilter.sanitize("f*ck this sh!t"));
// ████ this ████
// Get detailed results
const results = advancedFilter.getBadWordResults("This is fucking terrible!");
console.log(results);
// [
// {
// word: "fuck",
// index: 8,
// severity: "high",
// originalText: "fucking"
// }
// ]
// View statistics
console.log(advancedFilter.getStats());
// {
// totalChecks: 3,
// badWordsDetected: 2,
// wordsBySeverity: { low: 0, medium: 0, high: 2, extreme: 0 },
// mostCommonWords: [{ word: "fuck", count: 2 }]
// }text
ReactJS Example
import React, { useState } from "react";
import { BadWordFilter } from "badword-filter";
const filter = new BadWordFilter(["en"], [], {
detectLeetspeak: true,
severityThreshold: "medium",
});
export default function CommentInput() {
const [text, setText] = useState("");
const [sanitizedText, setSanitizedText] = useState("");
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
if (filter.containsBadWord(value)) {
const results = filter.getBadWordResults(value);
const highSeverityWords = results.filter(
(r) => r.severity === "high" || r.severity === "extreme"
);
if (highSeverityWords.length > 0) {
alert("Inappropriate content detected!");
setSanitizedText(filter.sanitize(value, "█"));
} else {
setSanitizedText(filter.sanitize(value));
}
} else {
setSanitizedText(value);
}
setText(value);
};
return (
<div>
<input
type="text"
value={text}
onChange={handleChange}
placeholder="Type a comment..."
/>
{sanitizedText !== text && <p>Sanitized: {sanitizedText}</p>}
</div>
);
}text
React Native Example
import React, { useState } from "react";
import { TextInput, Alert, View, Text } from "react-native";
import { BadWordFilter } from "badword-filter";
const filter = new BadWordFilter(["en"], [], {
detectLeetspeak: true,
severityThreshold: "low",
});
export default function CommentBox() {
const [text, setText] = useState("");
const [stats, setStats] = useState(null);
const handleChange = (value: string) => {
if (filter.containsBadWord(value)) {
const results = filter.getBadWordResults(value);
const severityCounts = results.reduce((acc, result) => {
acc[result.severity] = (acc[result.severity] || 0) + 1;
return acc;
}, {});
Alert.alert(
"Warning",
`Content contains ${results.length} inappropriate words!`,
[
{ text: "Continue", onPress: () => setText(value) },
{ text: "Cancel", style: "cancel" },
]
);
} else {
setText(value);
}
setStats(filter.getStats());
};
return (
<View>
<TextInput
value={text}
onChangeText={handleChange}
placeholder="Enter your comment..."
style={{ borderWidth: 1, padding: 8 }}
/>
{stats && <Text>Total checks: {stats.totalChecks}</Text>}
</View>
);
}text
Advanced Features Examples
// Custom words with whitelist
const filter = new BadWordFilter(["en"], ["noob", "lame"], {
whitelist: ["assassin", "classic", "passion"],
});
console.log(filter.containsBadWord("You are such a noob!"));
// true
console.log(filter.containsBadWord("He's a classic assassin"));
// false (assassin is whitelisted)
// Dynamic word management
filter.addWords(["stupid", "dumb"]);
filter.addToWhitelist(["dumbfounded"]);
// Update configuration
filter.updateConfig({
severityThreshold: "high",
customMask: "█",
detectLeetspeak: false,
});
// Export/Import functionality
const exportedWords = filter.exportWords();
const exportedWhitelist = filter.exportWhitelist();
// Create new filter with imported data
const newFilter = new BadWordFilter(["en"]);
newFilter.importWords(exportedWords);
newFilter.importWhitelist(exportedWhitelist);
// Statistics tracking
console.log(filter.getStats());
// {
// totalChecks: 15,
// badWordsDetected: 8,
// wordsBySeverity: { low: 2, medium: 3, high: 2, extreme: 1 },
// mostCommonWords: [
// { word: "shit", count: 3 },
// { word: "damn", count: 2 }
// ]
// }
// Reset statistics
filter.resetStats();text
📂 Default Wordlists
en.json→ Englishvi.json→ Vietnamesefi.json→ Finnish
You can extend word lists or load them dynamically from server.
🛠 API Reference
Constructor
new BadWordFilter(
languages?: Language[],
customWords?: string[],
config?: FilterConfig
)Create a filter instance with configurable options.
Parameters:
languages: Array of language codes ("en","vi","fi")customWords: Additional words to filterconfig: Configuration object (see FilterConfig interface)
Core Methods
.containsBadWord(text: string): boolean
Check if the text contains bad words above the severity threshold.
.getBadWords(text: string): string[]
Get list of bad words found in text.
.getBadWordResults(text: string): BadWordResult[]
Get detailed results with positions, severity, and original text.
.sanitize(text: string, mask?: string): string
Replace bad words with masking characters.
Word Management
.addWords(words: string[]): void
Add custom bad words to the filter.
.removeWords(words: string[]): void
Remove words from the filter.
.isWordInFilter(word: string): boolean
Check if a word is in the filter.
Whitelist Management
.addToWhitelist(words: string[]): void
Add words to the whitelist (allowed in context).
.removeFromWhitelist(words: string[]): void
Remove words from the whitelist.
.isWordWhitelisted(word: string): boolean
Check if a word is whitelisted.
Configuration
.updateConfig(newConfig: Partial<FilterConfig>): void
Update filter configuration at runtime.
.getConfig(): FilterConfig
Get current configuration.
Statistics & Analytics
.getStats(): FilterStats
Get usage statistics and analytics.
.resetStats(): void
Reset all statistics.
Import/Export
.exportWords(): string[]
Export all words in the filter.
.exportWhitelist(): string[]
Export all whitelisted words.
.importWords(words: string[]): void
Import words into the filter.
.importWhitelist(words: string[]): void
Import words into the whitelist.
Utility Methods
.getWordCount(): number
Get total number of words in the filter.
.getWhitelistCount(): number
Get total number of whitelisted words.
📋 Types & Interfaces
FilterConfig
interface FilterConfig {
mode?: FilterMode; // "strict" | "moderate" | "lenient"
detectLeetspeak?: boolean; // Detect leetspeak (f*ck, sh!t)
detectObfuscation?: boolean; // Remove obfuscation characters
partialMatch?: boolean; // Allow partial word matches
caseSensitive?: boolean; // Case-sensitive detection
customMask?: string; // Custom masking character
whitelist?: string[]; // Initial whitelist
severityThreshold?: SeverityLevel; // Minimum severity to detect
}BadWordResult
interface BadWordResult {
word: string; // The detected bad word
index: number; // Position in the text
severity: SeverityLevel; // Severity level
originalText: string; // Original text at that position
}FilterStats
interface FilterStats {
totalChecks: number; // Total number of checks
badWordsDetected: number; // Total bad words found
wordsBySeverity: Record<SeverityLevel, number>; // Count by severity
mostCommonWords: Array<{ word: string; count: number }>; // Top words
}🤝 Contributing
Contributions, issues, and feature requests are welcome!
Feel free to check issues page.
📜 License
MIT © 2025 hault2003
