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

@sentinel-password/core

v1.3.1

Published

Modern, zero-dependency TypeScript password validation with bloom filter-based common password detection. 100% test coverage (enforced); ~6.3 KB gzipped (10 KB CI limit).

Readme

@sentinel-password/core

npm version Bundle Size TypeScript License: MIT

Modern TypeScript password validation library with zero dependencies, comprehensive validation rules, and rich feedback.

Documentation | Interactive Playground | API Reference

Features

  • Zero Dependencies - No external dependencies, tree-shakeable, ~5.5KB gzipped
  • TypeScript-First - Full type safety with strict mode enabled
  • Rich Feedback - Actionable suggestions for password improvement
  • Comprehensive Validation - 7 built-in validators covering OWASP best practices
  • Flexible API - Zero-config defaults with full customization options
  • Framework Agnostic - Works in Node.js, browsers, and any JavaScript environment

Installation

npm install @sentinel-password/core
pnpm add @sentinel-password/core
yarn add @sentinel-password/core

Quick Start

import { validatePassword } from '@sentinel-password/core'

const result = validatePassword('MySecure!Pass_w0rd')

if (result.valid) {
  console.log('Password is valid!')
  console.log(`Strength: ${result.strength}`) // 'very-strong'
  console.log(`Score: ${result.score}`) // 4
} else {
  // `feedback.warning` is always equal to `feedback.suggestions[0]` — the
  // first failure, surfaced for prominent display. Iterate `suggestions`
  // for the full list; the first entry is the warning.
  console.log('Password is invalid')
  result.feedback.suggestions.forEach(suggestion => {
    console.log(`- ${suggestion}`)
  })
}

Validation Result

The validatePassword function returns a comprehensive validation result:

interface ValidationResult {
  // Overall validation status
  valid: boolean
  
  // Strength scoring
  score: 0 | 1 | 2 | 3 | 4
  strength: 'very-weak' | 'weak' | 'medium' | 'strong' | 'very-strong'
  
  // User feedback
  feedback: {
    warning?: string              // Primary warning message
    suggestions: readonly string[] // All improvement suggestions
  }
  
  // Individual check results
  checks: {
    length: boolean             // Meets length requirements
    characterTypes: boolean     // Meets character type requirements
    repetition: boolean         // No excessive repeated characters
    sequential: boolean         // No three characters with consecutive charCodeAt values (abc, 123, xyz, plus runs like '!"#' or '9:;')
    keyboardPattern: boolean    // No keyboard patterns (qwerty, asdf)
    commonPassword: boolean     // Not in top 1K common passwords (Bloom filter, ~0.84% false-positive rate)
    personalInfo: boolean       // Doesn't contain personal information
  }
}

Configuration Options

Customize validation rules to match your requirements:

const result = validatePassword('Tr0ub4dor&3-isLong!', {
  // Length constraints
  minLength: 12,              // default: 8
  maxLength: 128,             // default: 128

  // Character requirements
  requireUppercase: true,     // default: false
  requireLowercase: true,     // default: false
  requireDigit: true,         // default: false
  requireSymbol: true,        // default: false

  // Pattern detection
  maxRepeatedChars: 3,        // default: 3
  checkSequential: true,      // default: true
  checkKeyboardPatterns: true, // default: true
  checkCommonPasswords: true, // default: true

  // Personal information exclusion
  personalInfo: ['johndoe', '[email protected]'],
})
// result.valid === true, result.strength === 'very-strong'

Usage Examples

Basic Validation

import { validatePassword } from '@sentinel-password/core'

// Valid password
const result1 = validatePassword('Tr0ub4dor&3')
console.log(result1.valid) // true
console.log(result1.strength) // 'very-strong'

// Invalid password (too short)
const result2 = validatePassword('pass')
console.log(result2.valid) // false
console.log(result2.feedback.warning) // 'Password must be at least 8 characters'

Custom Requirements

import { validatePassword } from '@sentinel-password/core'

// Require strong passwords with all character types
const result = validatePassword('password', {
  minLength: 12,
  requireUppercase: true,
  requireLowercase: true,
  requireDigit: true,
  requireSymbol: true
})

console.log(result.valid) // false
console.log(result.checks.length) // false
console.log(result.checks.characterTypes) // false
console.log(result.checks.commonPassword) // false — 'password' is in the common-password list
console.log(result.feedback.suggestions)
// [
//   'Password must be at least 12 characters',
//   'Password must contain at least one uppercase letter, digit, symbol',
//   'Password is too common. Please choose a more unique password.'
// ]

The character-type validator returns a single combined message listing every missing type — not one suggestion per missing type. Note that 'password' also trips the common-password check, so a third suggestion always appears regardless of length and character-type settings.

Blocking Personal Information

import { validatePassword } from '@sentinel-password/core'

const result = validatePassword('alice2024', {
  personalInfo: ['alice', '[email protected]']
})

console.log(result.valid) // false
console.log(result.checks.personalInfo) // false
console.log(result.feedback.warning)
// 'Password contains personal information'

Detecting Common Patterns

import { validatePassword } from '@sentinel-password/core'

// Sequential patterns
const result1 = validatePassword('password123')
console.log(result1.checks.sequential) // false

// Keyboard patterns
const result2 = validatePassword('qwerty2024')
console.log(result2.checks.keyboardPattern) // false

// Common passwords
const result3 = validatePassword('password')
console.log(result3.checks.commonPassword) // false

// Excessive repetition
const result4 = validatePassword('passssword')
console.log(result4.checks.repetition) // false

Signup Form Example

import { validatePassword } from '@sentinel-password/core'

function handleSignup(formData: {
  email: string
  username: string
  password: string
}) {
  const result = validatePassword(formData.password, {
    minLength: 10,
    requireUppercase: true,
    requireLowercase: true,
    requireDigit: true,
    personalInfo: [formData.email, formData.username]
  })
  
  if (!result.valid) {
    return {
      success: false,
      errors: result.feedback.suggestions
    }
  }
  
  return {
    success: true,
    passwordStrength: result.strength
  }
}

Advanced Usage

Individual Validators

For fine-grained control, import and use individual validators:

import {
  validateLength,
  validateCharacterTypes,
  validateRepetition,
  validateSequential,
  validateKeyboardPattern,
  validateCommonPassword,
  validatePersonalInfo
} from '@sentinel-password/core'

const password = 'MyPassword123'

// Check individual constraints
const lengthCheck = validateLength(password, { minLength: 12 })
console.log(lengthCheck.passed) // false
console.log(lengthCheck.message) // 'Password must be at least 12 characters'

const charTypeCheck = validateCharacterTypes(password, {
  requireUppercase: true,
  requireLowercase: true,
  requireDigit: true,
  requireSymbol: true,
})
console.log(charTypeCheck.passed) // false
console.log(charTypeCheck.message) // 'Password must contain at least one symbol'
// (one combined message listing every missing type — not one message per type)

Character Type Helpers

import {
  hasUppercase,
  hasLowercase,
  hasDigit,
  hasSymbol
} from '@sentinel-password/core'

const password = 'MyPassword123!'

console.log(hasUppercase(password)) // true
console.log(hasLowercase(password)) // true
console.log(hasDigit(password))     // true
console.log(hasSymbol(password))    // true

TypeScript

The library is written in TypeScript with full type definitions included:

import type {
  ValidationResult,
  ValidatorOptions,
  ValidatorCheck,
  StrengthScore,
  StrengthLabel,
  CheckId
} from '@sentinel-password/core'

const options: ValidatorOptions = {
  minLength: 10,
  requireUppercase: true
}

const result: ValidationResult = validatePassword('test', options)
const score: StrengthScore = result.score // 0 | 1 | 2 | 3 | 4
const strength: StrengthLabel = result.strength // 'very-weak' | 'weak' | ...

Validation Rules

1. Length Validation

  • Default: 8-128 characters
  • Configurable via minLength and maxLength

2. Character Types

  • Optional requirements for uppercase, lowercase, digits, and symbols
  • Configurable via requireUppercase, requireLowercase, requireDigit, requireSymbol

3. Repetition Detection

  • Blocks excessive repeated characters (e.g., "aaaa")
  • Default: max 3 repeated characters
  • Configurable via maxRepeatedChars

4. Sequential Pattern Detection

  • Blocks any three characters whose charCodeAt values are consecutive ascending or descending — abc, 123, xyz plus less-obvious runs like !"#, ,-., 9:; (equivalent to consecutive Unicode code points for the BMP, which covers every character a typical password uses)
  • Works forward and backward
  • Configurable via checkSequential

5. Keyboard Pattern Detection

  • Blocks runs along common keyboard layouts: QWERTY (qwerty, asdfgh, zxcvbn), AZERTY (azerty, qsdfg), QWERTZ (qwertz, yxcvb), Dvorak (aoeu, htns), Colemak (arst, dhne), and Cyrillic (йцукен, фывап)
  • Catches numeric runs: full top row (1234567890), reverse (0987654321), and numeric-keypad rows/columns (789, 456, 123, 741, 852, 963)
  • Does not match the shifted symbol row (!@#$%…) — only unshifted runs
  • Configurable via checkKeyboardPatterns

6. Common Password Detection

  • Blocks the top 1,000 most common passwords
  • Uses a Bloom filter for efficient memory usage (~1.5 KB vs ~8 KB for the raw list)
  • No false negatives (every password in the list is rejected) and a ~0.84% false-positive rate — uncommon passwords are very rarely flagged as "common"
  • Configurable via checkCommonPasswords

7. Personal Information Detection

  • Blocks passwords containing personal info (username, email, etc.)
  • Extracts username from email addresses
  • Configurable via personalInfo array

Bundle Size

  • ESM: ~16KB uncompressed, ~5.5KB gzipped
  • CJS: ~17KB uncompressed, ~6KB gzipped
  • Zero dependencies - no additional packages needed
  • Tree-shakeable - only import what you use

Runtime Support

The published package is plain ES2022 with no Node or browser-specific APIs, so it runs anywhere those features are available:

  • Chrome/Edge 88+
  • Firefox 78+
  • Safari 14+
  • Node.js 18+ (and Deno, Bun, Cloudflare Workers, Vercel Edge — see the Server-Side Usage guide)

Building this monorepo requires Node.js 20+ (engines.node at the repo root). The 18+ minimum above applies to running the published @sentinel-password/core package, not to developing it.

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for details.

License

MIT - see LICENSE for details.

Related Packages

Acknowledgments

Inspired by zxcvbn and modern password validation best practices from OWASP.