DEV Community

GDS K S
GDS K S

Posted on

Glin Profanity: A Practical Toolkit for Content Moderation

What is Glin-Profanity?

Glin-Profanity is an open-source content moderation library for JavaScript/TypeScript and Python. Unlike basic word-list filters, it handles the evasion techniques users actually try, leetspeak substitutions (f4ck, 5h1t), Unicode homoglyphs (Cyrillic characters that look like Latin), and character separation tricks.

Key capabilities:

  • Leetspeak & Unicode normalization (catches @$$, fսck, sh!t)
  • 23 language dictionaries built-in
  • Optional ML toxicity detection via TensorFlow.js
  • 21M+ operations/sec with LRU caching
  • Works in Node.js, browsers, and Python

Try It Live

Test the filter directly in your browser — no installation required.

Glin-Profanity Live Demo

Open Interactive Demo


Quick Reference

Feature JavaScript Python
Install npm install glin-profanity pip install glin-profanity
Languages 23 supported 23 supported
Performance 21M ops/sec Native C extension
ML Support TensorFlow.js TensorFlow
Bundle Size ~45KB (tree-shakeable) N/A

Installation

# JavaScript/TypeScript
npm install glin-profanity

# Python
pip install glin-profanity

# With ML toxicity support (optional)
npm install glin-profanity @tensorflow/tfjs
Enter fullscreen mode Exit fullscreen mode

Code Templates

Template 1: Basic Profanity Check

JavaScript:

import { checkProfanity } from 'glin-profanity';

const result = checkProfanity("user input here", {
  languages: ['english']
});

if (result.containsProfanity) {
  console.log('Blocked words:', result.profaneWords);
}
Enter fullscreen mode Exit fullscreen mode

Python:

from glin_profanity import Filter

filter = Filter({"languages": ["english"]})
result = filter.check_profanity("user input here")

if result.contains_profanity:
    print(f"Blocked words: {result.profane_words}")
Enter fullscreen mode Exit fullscreen mode

Template 2: Leetspeak & Unicode Evasion Detection

Catches: f4ck, 5h1t, @$$, fսck (Cyrillic), s.h" "i.t

import { Filter } from 'glin-profanity';

const filter = new Filter({
  detectLeetspeak: true,
  leetspeakLevel: 'aggressive', // 'basic' | 'moderate' | 'aggressive'
  normalizeUnicode: true
});

filter.isProfane('f4ck');   // true
filter.isProfane('5h1t');   // true
filter.isProfane('@$$');    // true
filter.isProfane('fսck');   // true (Cyrillic 'ս')
Enter fullscreen mode Exit fullscreen mode

Leetspeak Levels:

  • basic: Common substitutions (4→a, 3→e, 1→i, 0→o)
  • moderate: + Extended symbols (@→a, $→s, !→i)
  • aggressive: + Separated characters, mixed patterns

Template 3: Multi-Language Detection

const filter = new Filter({
  languages: ['english', 'spanish', 'french', 'german']
});

// Or check all 23 languages:
const filterAll = new Filter({ allLanguages: true });
Enter fullscreen mode Exit fullscreen mode

Supported Languages:
arabic chinese czech danish dutch english esperanto finnish french german hindi hungarian italian japanese korean norwegian persian polish portuguese russian spanish swedish thai turkish


Template 4: Auto-Replace Profanity

const filter = new Filter({
  replaceWith: '***',
  detectLeetspeak: true
});

const result = filter.checkProfanity("What the f4ck");
console.log(result.processedText); // "What the ***"
Enter fullscreen mode Exit fullscreen mode

Custom replacement patterns:

// Asterisks matching word length
{ replaceWith: '*' }        // "f**k" → "****"

// Fixed replacement
{ replaceWith: '[FILTERED]' } // "f**k" → "[FILTERED]"

// Character-based
{ replaceWith: '#' }        // "f**k" → "####"
Enter fullscreen mode Exit fullscreen mode

Template 5: Severity-Based Moderation

import { Filter, SeverityLevel } from 'glin-profanity';

const filter = new Filter({ detectLeetspeak: true });
const result = filter.checkProfanity(userInput);

switch (result.maxSeverity) {
  case SeverityLevel.HIGH:
    // Block message, notify moderators
    blockMessage(result);
    notifyModerators(result);
    break;
  case SeverityLevel.MEDIUM:
    // Auto-replace, flag for review
    sendFiltered(result.processedText);
    flagForReview(result);
    break;
  case SeverityLevel.LOW:
    // Just replace and continue
    sendFiltered(result.processedText);
    break;
  default:
    // Clean message
    send(userInput);
}
Enter fullscreen mode Exit fullscreen mode

Template 6: React Hook for Real-Time Input

import { useProfanityChecker } from 'glin-profanity';

function ChatInput() {
  const { result, checkText, isChecking } = useProfanityChecker({
    detectLeetspeak: true,
    languages: ['english']
  });

  return (
    <div>
      <textarea
        onChange={(e) => checkText(e.target.value)}
        placeholder="Type a message..."
      />
      {result?.containsProfanity && (
        <span className="text-red-500">
          Please remove inappropriate language.
        </span>
      )}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Template 7: ML Toxicity Detection (v3+)

Catches toxic content without explicit profanity:

  • "You're the worst player ever"
  • "Nobody wants you here"
  • "Just quit already"
import { loadToxicityModel, checkToxicity } from 'glin-profanity/ml';

// Load once on app startup
await loadToxicityModel({ threshold: 0.9 });

// Check any text
const result = await checkToxicity("You're terrible at this");

console.log(result);
// {
//   toxic: true,
//   categories: {
//     toxicity: 0.92,
//     insult: 0.87,
//     threat: 0.12,
//     identity_attack: 0.08,
//     obscene: 0.45
//   }
// }
Enter fullscreen mode Exit fullscreen mode

Note: ML model runs 100% locally. No API calls, no data leaves your server.


Template 8: Full Chat Moderation Pipeline

import { Filter, SeverityLevel } from 'glin-profanity';
import { loadToxicityModel, checkToxicity } from 'glin-profanity/ml';

// Setup
const filter = new Filter({
  languages: ['english', 'spanish'],
  detectLeetspeak: true,
  leetspeakLevel: 'moderate',
  normalizeUnicode: true,
  replaceWith: '***'
});

await loadToxicityModel({ threshold: 0.85 });

// Moderation function
async function moderateMessage(text) {
  // Fast rule-based check
  const profanity = filter.checkProfanity(text);

  // ML toxicity check
  const toxicity = await checkToxicity(text);

  // Decision logic
  if (profanity.maxSeverity === SeverityLevel.HIGH) {
    return { action: 'block', reason: 'severe_profanity' };
  }

  if (toxicity.toxic) {
    return {
      action: 'flag',
      text: profanity.processedText,
      reason: 'toxic_content'
    };
  }

  if (profanity.containsProfanity) {
    return { action: 'filter', text: profanity.processedText };
  }

  return { action: 'allow', text };
}

// Usage
const result = await moderateMessage("User message here");
Enter fullscreen mode Exit fullscreen mode

Template 9: Express.js Middleware

import { Filter } from 'glin-profanity';

const filter = new Filter({
  detectLeetspeak: true,
  languages: ['english']
});

function profanityMiddleware(req, res, next) {
  const fieldsToCheck = ['body.message', 'body.comment', 'body.bio'];

  for (const field of fieldsToCheck) {
    const value = getNestedValue(req, field);
    if (value && filter.isProfane(value)) {
      return res.status(400).json({
        error: 'Content contains inappropriate language'
      });
    }
  }

  next();
}

app.post('/api/comments', profanityMiddleware, commentHandler);
Enter fullscreen mode Exit fullscreen mode

Template 10: Custom Whitelist/Blacklist

const filter = new Filter({
  languages: ['english'],
  ignoreWords: ['hell', 'damn'],     // Allow these words
  customWords: ['badword', 'toxic']  // Add custom blocked words
});
Enter fullscreen mode Exit fullscreen mode

Architecture

Glin Profanity Processing Flow


Performance Benchmarks

Operation Speed
Simple check 21M ops/sec
With leetspeak (moderate) 8.5M ops/sec
Multi-language (3 langs) 18M ops/sec
Unicode normalization 15M ops/sec

Results are cached using LRU strategy.


API Quick Reference

Filter Options

interface FilterOptions {
  languages?: string[];           // ['english', 'spanish', ...]
  allLanguages?: boolean;         // Check all 23 languages
  detectLeetspeak?: boolean;      // Enable leetspeak detection
  leetspeakLevel?: 'basic' | 'moderate' | 'aggressive';
  normalizeUnicode?: boolean;     // Handle Unicode homoglyphs
  replaceWith?: string;           // Replacement character/string
  ignoreWords?: string[];         // Whitelist
  customWords?: string[];         // Additional blocked words
}
Enter fullscreen mode Exit fullscreen mode

Result Object

interface CheckResult {
  containsProfanity: boolean;
  profaneWords: string[];
  processedText: string;          // With replacements applied
  maxSeverity: SeverityLevel;
  matches: MatchDetail[];
}
Enter fullscreen mode Exit fullscreen mode

Resources


Tags: #javascript #typescript #python #react #opensource #webdev #contentmoderation #npm #profanityfilter

Top comments (0)