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

input-sense

v0.13.0

Published

Detects low-quality, fake, or placeholder user inputs beyond regex validation

Downloads

221

Readme

npm version npm downloads coverage CI license


input-sense

A lightweight JavaScript utility that detects low-quality, fake, or placeholder user inputs that pass traditional regex validation.

It adds a human-intent layer on top of normal validation.


Why input-sense

Most validation libraries focus on syntax, not intent.

Inputs like:

  • aaaa
  • test
  • 123456
  • qwerty
  • asdf

often pass validation even though they are meaningless.

input-sense helps detect such inputs early and improve overall data quality.


Features

  • Detects repeated characters
  • Flags placeholder words (38 built-in + custom words support)
  • Detects sequential patterns
  • Detects reverse sequences
  • Identifies keyboard patterns
  • Detects all-caps inputs
  • Detects unicode/emoji-only inputs
  • Detects leet speak placeholder variants (e.g. 4dmin, t3st)
  • Input type presets — smart rule configuration for email and fullName fields
  • Supports returning all detected issues (mode: "all")
  • Supports structured output with rule names (mode: "detailed")
  • Supports quality scoring (mode: "score")
  • Allows enabling/disabling specific rules
  • Supports custom rule execution order via priority option
  • Supports per-rule configuration for fine-grained tuning
  • Batch validation for multiple form fields (senseInputBatch)
  • Runtime rule discovery (listRules)
  • Ships as both ESM and CommonJS
  • Lightweight and dependency-free
  • Frontend-friendly
  • Full TypeScript support with per-mode return type inference
  • Includes automated tests for core validation logic
  • Detects symbol-only or whitespace inputs
  • Detects numeric-only inputs
  • Detects repeated word patterns
  • Detects low vowel ratio (non-human-like input)

Installation

Using npm:

npm install input-sense

Using yarn:

yarn add input-sense

Using pnpm:

pnpm add input-sense

Usage

import { senseInput } from "input-sense";

const result = senseInput("qwerty");

if (result) {
  console.log(result);
} else {
  console.log("Input looks valid");
}

CommonJS is also supported:

const { senseInput } = require("input-sense");

Input Type Presets

Use the type option to automatically apply the right rules for a specific form field. No need to manually configure disable, rules, or priority — the preset handles it.

type: "email"

Validates email inputs with comprehensive real-world checks:

senseInput("[email protected]", { type: "email" })
// null — valid email

senseInput("[email protected]", { type: "email" })
// "Email local part looks like a placeholder"

senseInput("[email protected]", { type: "email" })
// "Email domain looks disposable or fake"

senseInput("[email protected]", { type: "email" })
// "Email local part looks like a system address"

senseInput("notanemail", { type: "email" })
// "Input does not look like a valid email address"

senseInput("[email protected]", { type: "email" })
// "Input does not look like a valid email address"

senseInput("[email protected]", { type: "email" })
// "Input does not look like a valid email address"

senseInput("[email protected]", { type: "email" })
// "Email local part looks like a placeholder"

senseInput("[email protected]", { type: "email" })
// null — legitimate plus tag

Email config options:

// Only allow specific domains
senseInput("[email protected]", {
  type: "email",
  rules: {
    validEmailFormat: {
      allowedDomains: ["company.com", "company.co.in"]
    }
  }
})
// "Email domain is not accepted"

// Block additional domains
senseInput("[email protected]", {
  type: "email",
  rules: {
    validEmailFormat: {
      blockedDomains: ["competitor.com"]
    }
  }
})
// "Email domain looks disposable or fake"

What email validation covers:

  • Format: @ count, local part 2–64 chars, total max 254 chars
  • No all-numeric local parts, no consecutive dots, no leading/trailing dots
  • Domain name cannot contain digits (catches gmai1.com, g00gle.com)
  • Domain cannot start or end with hyphens
  • 33 built-in blocked disposable domains
  • Blocked system addresses: noreply, postmaster, support, admin, info and more
  • Placeholder detection in local part segments (test.user@, demo_app@)
  • Plus-tag placeholder detection

type: "fullName"

Validates full name inputs requiring first and last name:

senseInput("Harshit Patle", { type: "fullName" })
// null — valid full name

senseInput("Harshit", { type: "fullName" })
// "Please enter your full name (first and last name)"

senseInput("HARSHIT PATLE", { type: "fullName" })
// "Input contains only uppercase letters and looks non-meaningful"

senseInput("J Smith", { type: "fullName" })
// "Each part of your name must be at least 2 characters"

senseInput("John 123", { type: "fullName" })
// "Name parts must contain only letters"

senseInput("Mary-Jane Watson", { type: "fullName" })
// null — hyphenated names supported

senseInput("O'Brien Connor", { type: "fullName" })
// null — apostrophe names supported

senseInput("María García", { type: "fullName" })
// null — accented characters supported

senseInput("St. John Smith", { type: "fullName" })
// null — dotted prefixes supported

senseInput("john smith", { type: "fullName" })
// null — casing is not enforced

What fullName validation covers:

  • Must contain a space (first and last name required)
  • Each name part minimum 2 characters
  • No digits in any name part
  • Supports hyphens, apostrophes, dots in names
  • Supports Unicode/accented characters
  • Normalizes multiple spaces automatically
  • Maximum 100 characters total
  • Catches placeholder words, repeated chars, all-caps, keyboard patterns

Disable space requirement for mononyms:

senseInput("Beyonce", {
  type: "fullName",
  disable: ["spaceRequired"]
})
// null

Advanced Usage

Get all detected issues

By default, input-sense returns only the first detected issue. To get all detected issues, use mode: "all".

senseInput("aa", { mode: "all" });

Get structured output with rule names

Use mode: "detailed" to get back an array of { rule, message } objects. This is useful when you want to show different UI feedback per rule.

senseInput("aaaa", { mode: "detailed" });
// [{ rule: "repeatedChar", message: "Input looks like repeated characters" }]

Get a quality score

Use mode: "score" to get a 0–100 quality score instead of pass/fail. 100 means fully clean, 0 means completely unusable.

senseInput("Harshit", { mode: "score" });
// 100

senseInput("aaaa", { mode: "score" });
// 0

Validate multiple fields at once

Use senseInputBatch to validate an entire form object in one call.

import { senseInputBatch } from "input-sense";

senseInputBatch({
  email: "[email protected]",
  fullName: "Harshit Patle"
}, { type: "email" });

Or validate different field types separately:

const emailResult = senseInput(emailValue, { type: "email" });
const nameResult = senseInput(nameValue, { type: "fullName" });

Control rule execution order

senseInput("aaaa", {
  priority: ["minLength", "repeatedChar"],
  rules: { minLength: { minLength: 5 } }
});
// "Input is too short to be meaningful (minimum 5 characters)"

Discover available rules at runtime

import { listRules } from "input-sense";

listRules();
// ["spaceRequired", "repeatedChar", "allCaps", "unicodeOnly", "symbolOnly",
//  "numericOnly", "placeholderWord", "leetSpeak", "repeatedWord", "minLength",
//  "sequential", "reverseSequential", "keyboardPattern", "entropy",
//  "lowVowelRatio", "validEmailFormat", "namePartsRule"]

Disable specific rules

senseInput("aa", {
  mode: "all",
  disable: ["repeatedChar"]
});

Rule Configuration Examples

repeatedChar — custom repetition threshold

senseInput("aaa", {
  rules: { repeatedChar: { threshold: 4 } }
});
// null — only flags when 5+ repetitions

placeholderWord — add custom words

senseInput("mycustomword", {
  rules: { placeholderWord: { customWords: ["mycustomword"] } }
});
// "Input looks like a placeholder word"

keyboardPattern — custom minimum length

senseInput("qw", {
  rules: { keyboardPattern: { minLength: 5 } }
});
// null — input is too short to check

repeatedWord — allow some duplication

senseInput("hey hey there", {
  rules: { repeatedWord: { maxAllowedRatio: 0.6 } }
});
// null

minLength — custom minimum length

senseInput("hello", {
  rules: { minLength: { minLength: 6 } }
});
// "Input is too short to be meaningful (minimum 6 characters)"

When to use each mode

| Mode | Returns | Use when | |------|---------|----------| | "first" (default) | string \| null | You only need the first blocking issue | | "all" | string[] \| null | You want to show all issues at once | | "detailed" | { rule, message }[] \| null | You need to know which rule fired | | "score" | number | You want a 0–100 quality score |


Rule Configuration Reference

| Rule | Config option | Type | Default | Description | |------|--------------|------|---------|-------------| | repeatedChar | threshold | number | 0 | Min repetitions before flagging | | allCaps | minLength | number | 4 | Min length before checking | | unicodeOnly | minLength | number | 1 | Min length before checking | | placeholderWord | customWords | string[] | [] | Extra words to flag | | leetSpeak | customWords | string[] | [] | Extra decoded words to flag | | keyboardPattern | minLength | number | 3 | Min length before checking | | repeatedWord | maxAllowedRatio | number | 0 | Max allowed duplication ratio | | lowVowelRatio | minLength | number | 5 | Min length before checking | | lowVowelRatio | minRatio | number | 0.2 | Min vowel ratio required | | minLength | minLength | number | 4 | Min required input length | | entropy | minLength | number | 6 | Min length before checking | | entropy | minRatio | number | 0.6 | Min character diversity ratio | | validEmailFormat | allowedDomains | string[] | [] | Whitelist specific domains | | validEmailFormat | blockedDomains | string[] | [] | Extra domains to block |

All rules have safe defaults. Unknown rule names in rules config are safely ignored.


Example Outputs

senseInput("aaaa");
// "Input looks like repeated characters"

senseInput("HELLO");
// "Input contains only uppercase letters and looks non-meaningful"

senseInput("🔥🔥🔥");
// "Input contains no standard characters and looks non-meaningful"

senseInput("4dmin");
// "Input looks like a leet speak placeholder word"

senseInput("test");
// "Input looks like a placeholder word"

senseInput("1234");
// "Input looks like a sequential pattern"

senseInput("9876");
// "Input looks like a reverse sequential pattern"

senseInput("qwerty");
// "Input looks like a keyboard pattern"

senseInput("123456");
// "Input contains only numbers and looks non-meaningful"

senseInput("test test test");
// "Input contains repeated words and looks non-meaningful"

senseInput("bcdfgh");
// "Input has very low vowel presence and looks non-meaningful"

senseInput("Harshit");
// null

Test Coverage

This project uses automated test coverage to ensure reliability. Coverage is collected and reported on every commit via CI. All rule files maintain 100% coverage across statements, branches, functions, and lines.


Mental Model

Think of input-sense as an intent checker, not a validator.

It runs a series of small, focused rules to answer one question:

"Does this input look meaningful for a human?"

  • Each rule checks a specific pattern
  • Rules run in a configurable order
  • Type presets automatically apply the right rules for each field
  • By default, the first issue is returned
  • You can opt into collecting all issues, structured output, or a quality score

How it works

Validation flow

User Input
↓
Regex / Required Validation
↓
input-sense (intent detection — with optional type preset)
↓
Backend Validation

What input-sense does NOT do

  • Does not replace backend validation
  • Does not replace regex validation
  • Does not block submissions automatically
  • Does not use AI
  • Does not store user data

Limitations

  • This library does not guarantee semantic correctness
  • It does not understand language meaning
  • It should be used alongside traditional validation

Use Cases

  • Signup and login forms
  • Admin dashboards
  • Hackathon projects
  • Educational platforms
  • Frontend UX improvement
  • Pre-API input sanity checks

Project Status

This project is actively maintained. All core validation rules are covered by automated tests and enforced via CI.


Quick Guide

| Use case | Recommendation | |----------|----------------| | Email field | type: "email" | | Full name field | type: "fullName" | | Simple forms | Default mode | | Rich UX | mode: "all" | | Rule-specific UX | mode: "detailed" | | Live quality indicator | mode: "score" | | Full form validation | senseInputBatch | | Custom rule order | priority option | | Strict apps | Enable entropy tuning | | JS projects | ESM or CommonJS | | TS projects | Enjoy full type safety |


Author

Harshit Patle


License

This project is licensed under the MIT License. See the LICENSE file for details.