@nzrm/text-shield
| Install | |
|---|---|
npm install @nzrm/text-shield |
|
| Latest Version: | 1.0.1 |
| License: | MIT |
| Last Updated: | Dec 29, 2025 |
| Links: | npm |
🛡️ Text Shield
A powerful, lightweight, and framework-agnostic profanity filter library with built-in multilingual support for English and Arabic. Perfect for content moderation in Node.js, NestJS, React, Angular, Vue, and browser applications.
✨ Features
- 🌍 Multilingual Support - Built-in English and Arabic profanity detection
- ⚡ High Performance - O(1) lookup time with Set-based architecture
- 🎯 Flexible Matching - Whole word or partial matching modes
- 🔧 Framework Agnostic - Works with Node.js, React, Angular, Vue, NestJS, Express, and more
- 📦 Zero Dependencies - Lightweight with no external dependencies
- 💪 TypeScript First - Written in TypeScript with full type definitions
- 🎨 Customizable - Add custom words, change placeholders, configure sensitivity
- 📝 Easy Integration - Simple API that works everywhere
- 🔒 Privacy Focused - All processing done locally, no external API calls
📦 Installation
npm install @nzrm/text-shield
yarn add @nzrm/text-shield
pnpm add @nzrm/text-shield
🚀 Quick Start
import { ProfanityFilter } from "@nzrm/text-shield";
// Initialize with English
const filter = new ProfanityFilter({ languages: ["en"] });
// Check if text contains profanity
if (filter.containsProfanity("This is a damn shame")) {
console.log("Profanity detected!");
}
// Clean the text
const cleaned = filter.clean("What the hell is this?");
console.log(cleaned); // "What the *** is this?"
// Get specific profane words
const words = filter.getProfaneWords("This shit is bad");
console.log(words); // ['shit', 'bad']
🌐 Multilingual Support
English Only
const filter = new ProfanityFilter({ languages: ["en"] });
filter.isProfane("damn"); // true
Arabic Only
const filter = new ProfanityFilter({ languages: ["ar"] });
filter.isProfane("كس"); // true
Both Languages
const filter = new ProfanityFilter({ languages: ["en", "ar"] });
filter.clean("This is shit وهذا كس أيضا"); // "This is *** وهذا *** أيضا"
📖 API Documentation
Constructor
new ProfanityFilter(options?: ProfanityFilterOptions)
Options
interface ProfanityFilterOptions {
languages?: ("en" | "ar")[]; // Default: ['en']
customWords?: string[]; // Additional words to filter
caseSensitive?: boolean; // Default: false
wholeWord?: boolean; // Default: true
placeholder?: string; // Default: '***'
}
Methods
isProfane(word: string): boolean
Check if a single word is profane.
filter.isProfane("damn"); // true
filter.isProfane("hello"); // false
containsProfanity(text: string): boolean
Check if text contains any profanity.
filter.containsProfanity("This is bad"); // true
filter.containsProfanity("This is good"); // false
getProfaneWords(text: string): string[]
Get an array of all profane words found in the text.
filter.getProfaneWords("damn this shit"); // ['damn', 'shit']
clean(text: string): string
Replace profane words with the placeholder.
filter.clean("What the hell"); // 'What the ***'
addWords(words: string[]): void
Add custom words to the filter dynamically.
filter.addWords(["spam", "junk"]);
removeWords(words: string[]): void
Remove words from the filter.
filter.removeWords(["damn", "hell"]);
getWordCount(): number
Get the total number of words in the filter.
console.log(filter.getWordCount()); // 150
exportWords(): string[]
Export all filtered words as an array.
const allWords = filter.exportWords();
Static Methods
ProfanityFilter.fromFile(filePath: string, options?: ProfanityFilterOptions): Promise<ProfanityFilter>
Load custom word list from a JSON file.
const filter = await ProfanityFilter.fromFile("./custom-words.json", {
languages: ["en"],
placeholder: "[CENSORED]",
});
🔧 Framework Integration Examples
Node.js / Express
const express = require("express");
const { ProfanityFilter } = require("text-shield");
const app = express();
app.use(express.json());
const filter = new ProfanityFilter({ languages: ["en", "ar"] });
app.post("/api/comment", (req, res) => {
if (filter.containsProfanity(req.body.text)) {
return res.status(400).json({
error: "Comment contains inappropriate content",
profaneWords: filter.getProfaneWords(req.body.text),
});
}
res.json({ message: "Comment posted successfully" });
});
app.listen(3000);
NestJS
// profanity.service.ts
import { Injectable } from "@nestjs/common";
import { ProfanityFilter } from "@nzrm/text-shield";
@Injectable()
export class ProfanityService {
private filter: ProfanityFilter;
constructor() {
this.filter = new ProfanityFilter({
languages: ["en", "ar"],
});
}
validate(text: string): boolean {
return !this.filter.containsProfanity(text);
}
clean(text: string): string {
return this.filter.clean(text);
}
}
React
import { useState, useEffect } from "react";
import { ProfanityFilter } from "@nzrm/text-shield";
function CommentForm() {
const [filter, setFilter] = useState(null);
const [comment, setComment] = useState("");
const [error, setError] = useState("");
useEffect(() => {
const profanityFilter = new ProfanityFilter({
languages: ["en", "ar"],
});
setFilter(profanityFilter);
}, []);
const handleSubmit = (e) => {
e.preventDefault();
if (filter?.containsProfanity(comment)) {
setError("Comment contains inappropriate content");
return;
}
console.log("Comment approved");
};
return (
<form onSubmit={handleSubmit}>
<textarea value={comment} onChange={(e) => setComment(e.target.value)} />
{error && <p style={{ color: "red" }}>{error}</p>}
<button type="submit">Submit</button>
</form>
);
}
Angular
// profanity.service.ts
import { Injectable } from "@angular/core";
import { ProfanityFilter } from "@nzrm/text-shield";
@Injectable({
providedIn: "root",
})
export class ProfanityService {
private filter: ProfanityFilter;
constructor() {
this.filter = new ProfanityFilter({
languages: ["en", "ar"],
});
}
isProfane(text: string): boolean {
return this.filter.containsProfanity(text);
}
clean(text: string): string {
return this.filter.clean(text);
}
}
Vue
<template>
<div>
<textarea v-model="comment" @input="validateComment"></textarea>
<p v-if="error" class="error">{{ error }}</p>
<button @click="submitComment">Submit</button>
</div>
</template>
<script>
import { ref } from "vue";
import { ProfanityFilter } from "@nzrm/text-shield";
export default {
setup() {
const filter = new ProfanityFilter({ languages: ["en", "ar"] });
const comment = ref("");
const error = ref("");
const validateComment = () => {
if (filter.containsProfanity(comment.value)) {
error.value = "Contains inappropriate content";
} else {
error.value = "";
}
};
const submitComment = () => {
if (filter.containsProfanity(comment.value)) {
error.value = "Cannot submit inappropriate content";
return;
}
console.log("Comment submitted");
};
return { comment, error, validateComment, submitComment };
},
};
</script>
⚙️ Advanced Usage
Custom Word Lists
// Add custom words
const filter = new ProfanityFilter({
languages: ["en"],
customWords: ["spam", "junk", "troll"],
});
// Or add them later
filter.addWords(["scam", "fake"]);
Load from External File
// words.json: ["word1", "word2", "word3"]
const filter = await ProfanityFilter.fromFile("./words.json", {
languages: ["en"],
placeholder: "[REMOVED]",
});
Partial Word Matching
const filter = new ProfanityFilter({
languages: ["en"],
wholeWord: false, // Will match 'bad' in 'badass'
});
Case Sensitive Mode
const filter = new ProfanityFilter({
languages: ["en"],
caseSensitive: true, // 'DAMN' and 'damn' treated differently
});
Custom Placeholder
const filter = new ProfanityFilter({
languages: ["en"],
placeholder: "[CENSORED]",
});
filter.clean("This is bad"); // 'This is [CENSORED]'
🔒 Privacy & Security
- No External API Calls - All processing is done locally
- No Data Collection - Your text never leaves your application
- Open Source - Fully transparent and auditable code
- No Analytics - We don't track usage or collect statistics
🌟 Use Cases
- Social media platforms
- Comment systems
- Chat applications
- Content moderation tools
- Form validation
- User-generated content filtering
- Forum moderation
- Review systems
- Gaming chat filters
- Educational platforms
📊 Performance
- Lookup Time: O(1) - Constant time for word checking
- Memory: Efficient Set-based storage
- Bundle Size: ~15KB minified
- Zero Dependencies: No external packages required
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
📝 Changelog
See CHANGELOG.md for a list of changes.
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- Built with TypeScript
- Bundled with Rollup
- Inspired by the need for better multilingual content moderation
🐛 Bug Reports
Found a bug? Please open an issue
💬 Support
- 📧 Email: me@nizar.io
- 💬 GitHub Issues: Create an issue
- 📖 Documentation: Full docs
⭐ Show Your Support
Give a ⭐️ if this project helped you!
Made with ❤️ by Nizar Masadeh
Related Packages
An Iraqi dialect profanity filter for React, React Native Expo, Vue, and Node.js
TypeScript profanity filter that returns text segments for UI rendering. English...
TypeScript GraphQL client for Propeller eCommerce V2 Platform - works with React...
Version History
| Version | Released | License |
|---|---|---|
| 1.0.1 | MIT | |
| 1.0.0 | MIT |