npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ainosha-badwords

v1.0.6

Published

Simple bad word filter for ReactJS and React Native

Downloads

65

Readme

badword-filter

npm version downloads license

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 → English
  • vi.json → Vietnamese
  • fi.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 filter
  • config: 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