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

@lacspace/commentguard

v1.3.0

Published

Comment moderation for English, romanized Nepali and Devanagari — scores spam, abuse, hate, doxxing and link-spam and returns an allow / review / flag / hide action, with PII detection (Nepali phone, email, URLs/shorteners) and FAQ auto-reply suggestions.

Readme

@lacspace/commentguard

Moderate comments in English, romanized Nepali and Devanagari — deterministically. Scores spam, abuse, hate, doxxing and link-spam, returns an allow / review / flag / hide action, detects PII (Nepali phone, email, URLs/shorteners), and suggests FAQ auto-replies. Rules + small, extendable lexicons; a borderline flag marks gray-zone comments where you may want an AI second opinion (AI is never called here).

npm i @lacspace/commentguard
import { moderate } from "@lacspace/commentguard";

moderate("Join telegram group bit.ly/x, subscribe my channel").action;   // "hide" (link-spam)
moderate("his number is 9812345678 call him").categories.doxxing;         // > 0.6, pii.phones
moderate("great report, thank you!").action;                              // "allow"

moderate("where can I read the full story?", {
  faqs: [{ match: ["where", "kaha", "कहाँ"], reply: { en: "Link in bio.", ne: "बायोको लिंकमा।" } }],
  lang: "en",
}).suggestedReply;  // "Link in bio."  (suggested only for clean comments)

Why

Hand-moderating a Nepali comment section — mixing Devanagari, romanized Nepali and English, plus phone-number doxxing and link-spam — doesn't scale, and sending every comment to an LLM is expensive. commentguard triages deterministically and only flags the genuinely ambiguous ones for review.

API

  • moderate(comment, options?) → { action, categories, score, reasons, borderline, suggestedReply?, pii }.
    • categories: 0–1 severity for spam | abuse | hate | doxxing | linkspam; score is the max.
    • action by thresholds (review 0.4 / flag 0.6 / hide 0.85 by default, overridable).
    • pii: { phones, emails, urls } (for redaction / doxxing handling).
    • borderline: in the gray zone → a good case to ask your AI.
    • suggestedReply: an FAQ reply, only when the comment is clean (spam/abuse is never rewarded with a reply).
  • options: lexicons (extra terms per category, merged with the starters), faqs ({ match, reply } rules), lang, thresholds.
  • describe() → machine-readable command schema for an AI "conductor".
  • LEXICONS / PATTERNS exported so you can inspect or build on them.

The bundled lexicons are compact starters — extend lexicons for your community; the engine, categories, PII detection and actions are the durable part. Normalization lowercases and collapses elongations ("sooo"→"soo") and matches Latin, romanized-Nepali and Devanagari.

1.3.0: finance-scam bait, Hindi abuse, Indian numbers

Built for trading communities (StockYatra's global chat). Both moderate() and check() now catch:

  • Finance-scam bait in English, romanised Nepali/Hindi and Devanagari: "guaranteed profit", "sure-shot calls", "100% accuracy", "paid group", "premium tips", "multibagger", "jackpot call", "insider news", "pakka munafa", "paisa double", "ग्यारेन्टी", "पक्का नाफा", "पैसा डबल", "श्योर शॉट", "नो लॉस"… plus number shapes such as "earn 50k monthly", "2 lakh per month" and "95% accurate". In moderate() these raise spam; in check() they are spam hits with severity high.
  • Hindi profanity, Devanagari and romanised (चूतिया, भोसड़ी, मादरचोद, गांडू, बकचोद, लौड़ा, कमीना/कमीने, नालायक, निकम्मा, and their Latin spellings with leet/masking), on top of the English and Nepali lists.
  • Indian mobiles (6–9 + 9 digits, with or without +91) and +977 / 00977 / +91 forms with any spacing. moderate().pii.phones is de-duplicated by digits, so "+977 9841…" and "9841…" count once.

The link allowlist and your own lexicons / extraAbuse still apply on top; 1.3.0 only widens the starters.

check(): strict filter for live comments (1.1.0, threats and more personal-data formats in 1.2.0)

moderate() triages into allow / review / flag / hide. check() is the strict, whole-word gate a news site runs before a comment goes live:

import { check } from "@lacspace/commentguard";

check({ text: "muji neta haru", lang: "ne" });
// { ok: false, code: "abuse", review: false, hits: [{ code: "abuse", term: "muji", severity: "high" }] }

check({ text: "call me 9841234567" });                     // { ok: false, code: "personal", … }
check({ text: "join https://t.me/freesignals" });           // { ok: false, code: "spam", … }
check({ text: "Government must resign now", userHistory }); // { ok: false, code: "repeat", … } if they said it already
check({ text: "these leaders are chor" });                  // { ok: true, review: true, … }  mild words only ask for review
  • abuse: profanity and slurs in English, Nepali Devanagari (with case endings: मुजीको, हरामीहरू) and romanised Nepali. Leetspeak and masked spellings are caught too (f*ck, sh!t, F U C K, m.u.j.i). Matching is on whole words, so "class", "Putin", "Kami Rita", "चोरी", "गेडागुडी", "मुला" and "dal bhat" pass.
    • Threats (1.2.0): a direct threat blocks, such as "I will kill you", "you are dead" or मारिदिन्छु / maridinchu. A call for punishment such as "he should be hanged" or फाँसी दिनुपर्छ only asks for review. News wording like "killed in the attack" passes.
  • personal: personal details:
    • Nepal mobiles (96x/97x/98x, with or without +977 and separators) and landlines (01-4XXXXXX), plus other +CC numbers;
    • emails;
    • citizenship numbers (27-01-71-12345, or "नागरिकता नं. …"), NID, passport and account numbers;
    • Devanagari digits are read too;
    • (1.2.0) a mobile number in any grouping (98-41-23-45-67, 9 8 4 1 …) and spelled-out emails ("ram at gmail dot com", "ram[at]yahoo[dot]com").
  • spam:
    • chat invites and shorteners (t.me, wa.me, bit.ly…), or more than maxLinks links (your ownDomains never count);
    • promo phrasing ("earn Rs 5000 daily", "DM me", "join telegram");
    • crypto or betting words, which only block next to a link, a contact or promo. "Is crypto betting legal in Nepal?" just asks for review.
  • repeat: the same comment again from userHistory (≥ 0.9 similar), or character, word or emoji floods. Since 1.2.0, syllable floods are caught too ("hahahahaha", "हाहाहाहा"): they block when they make up most of the comment and only ask for review inside a sentence.

Options:

  • strict: mild words block too.
  • extraAbuse / allow: your own word lists.
  • maxLinks, ownDomains and repeatSimilarity.

Licence

Lacspace Free Licence v1.0 — free for personal and commercial use.