
Security News
GitHub Actions Checkout Now Blocks Risky pull_request_target Checkouts
GitHub Actions checkout now blocks risky pull_request_target checkouts by default to help prevent pwn request supply chain attacks.
@sentinel-password/core
Advanced tools
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).
Modern TypeScript password validation library with zero dependencies, comprehensive validation rules, and rich feedback.
Documentation | Interactive Playground | API Reference
npm install @sentinel-password/core
pnpm add @sentinel-password/core
yarn add @sentinel-password/core
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}`)
})
}
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
}
}
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', 'john.doe@example.com'],
})
// result.valid === true, result.strength === 'very-strong'
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'
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.
import { validatePassword } from '@sentinel-password/core'
const result = validatePassword('alice2024', {
personalInfo: ['alice', 'alice@example.com']
})
console.log(result.valid) // false
console.log(result.checks.personalInfo) // false
console.log(result.feedback.warning)
// 'Password contains personal information'
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
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
}
}
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)
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
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' | ...
minLength and maxLengthrequireUppercase, requireLowercase, requireDigit, requireSymbolmaxRepeatedCharscharCodeAt 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)checkSequentialqwerty, asdfgh, zxcvbn), AZERTY (azerty, qsdfg), QWERTZ (qwertz, yxcvb), Dvorak (aoeu, htns), Colemak (arst, dhne), and Cyrillic (йцукен, фывап)1234567890), reverse (0987654321), and numeric-keypad rows/columns (789, 456, 123, 741, 852, 963)!@#$%…) — only unshifted runscheckKeyboardPatternscheckCommonPasswordspersonalInfo arrayThe published package is plain ES2022 with no Node or browser-specific APIs, so it runs anywhere those features are available:
Building this monorepo requires Node.js 20+ (
engines.nodeat the repo root). The 18+ minimum above applies to running the published@sentinel-password/corepackage, not to developing it.
Contributions are welcome! Please see CONTRIBUTING.md for details.
MIT - see LICENSE for details.
@sentinel-password/react - React hook for password validation with debouncing@sentinel-password/react-components - Accessible, headless React componentsInspired by zxcvbn and modern password validation best practices from OWASP.
FAQs
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).
The npm package @sentinel-password/core receives a total of 5,072 weekly downloads. As such, @sentinel-password/core popularity was classified as popular.
We found that @sentinel-password/core demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
GitHub Actions checkout now blocks risky pull_request_target checkouts by default to help prevent pwn request supply chain attacks.

Product
Socket now supports Custom Roles and Repository Access Permissions so organizations can control who can access specific repositories and actions.

Product
Socket MCP now lets AI assistants review org alerts, investigate threats using the Socket threat feed, and inspect package files in addition to dependency scoring.