Skip to main content

bcryptjs

PropertyValue
Packagebcryptjs
Versions Covered>=2.0.0
Contract Version1.0.0
Statusproduction
Last Verified2026-02-26
Maintainercorpus-team

Installation​

npm install bcryptjs

Covered Functions​

This contract covers 3 function(s):

hash()​

Hashes a password using bcrypt algorithm with specified salt rounds

Import:

import { hash } from 'bcryptjs';

Postconditions​

What happens after calling this function:

🔴 ERROR - hash-type-error

Condition: password is not a string or Buffer, or salt is invalid type

Throws: Error: Illegal arguments: [actual_type], [actual_type]

Required Handling:

Caller MUST wrap bcrypt.hash() in try-catch block or use .catch() handler. Type errors occur when forgetting await on Promise or passing wrong types. Validate input types before calling hash() to provide better error messages.

📖 Source

🔴 ERROR - hash-invalid-salt

Condition: salt parameter is not a string, number, or valid salt format

Throws: Error: Invalid salt version or Illegal arguments

Required Handling:

Caller MUST handle errors from invalid salt parameter. Use genSalt() to generate valid salts, or pass numeric salt rounds (recommended: 12).

📖 Source

🔴 ERROR - hash-rounds-out-of-range

Condition: salt rounds 4 or 31

Throws: Error: Rounds out of range (4-31)

Required Handling:

Caller MUST validate salt rounds are between 4 and 31. Production systems should use rounds = 12 for adequate security.

📖 Source

🔴 ERROR - hash-internal-failure

Condition: internal hashing operation fails

Throws: Error

Required Handling:

Caller MUST handle unexpected errors from hash() operation. While rare, internal failures can occur and should not crash the application.

📖 Source

Edge Cases​

Known gotchas and sharp edges:

âš ī¸ WARNING - password-truncation

Passwords longer than 72 bytes (UTF-8 encoded) are silently truncated. This is a bcrypt algorithm limitation, not a bug. Applications should validate password length before hashing to prevent user confusion.

📖 Source

âš ī¸ WARNING - low-salt-rounds

Using salt rounds 12 provides inadequate protection against modern hardware attacks. Recommended minimum is 12 for 2026 (increases over time).

📖 Source


compare()​

Compares a plaintext password with a bcrypt hash to verify match

Import:

import { compare } from 'bcryptjs';

Postconditions​

What happens after calling this function:

🔴 ERROR - compare-type-error

Condition: password or hash parameter is not a string

Throws: Error: Illegal arguments: [actual_type], [actual_type]

Required Handling:

Caller MUST wrap bcrypt.compare() in try-catch or use .catch() handler. Type errors commonly occur when retrieving hash from database as Buffer instead of string, or when password input is undefined/null.

📖 Source

🔴 ERROR - compare-invalid-hash

Condition: hash parameter is not a valid bcrypt hash format

Throws: Error: Invalid hash provided or hash is not a valid bcrypt hash

Required Handling:

Caller MUST handle errors from malformed hash values. Database corruption, string truncation (VARCHAR 60), or encoding issues can cause invalid hashes. This is the #1 production authentication bug.

📖 Source

🔴 ERROR - compare-internal-failure

Condition: internal comparison operation fails

Throws: Error

Required Handling:

Caller MUST handle unexpected errors from compare() operation. Errors should not be silently swallowed as they may indicate security issues or data corruption.

📖 Source

Edge Cases​

Known gotchas and sharp edges:

â„šī¸ INFO - hash-version-compatibility

bcrypt.js supports $2a$ and $2b$ hash versions. Some hashes generated by other bcrypt libraries (like $2y$ from PHP) may not verify correctly. Use bcrypt.getRounds() to check hash version compatibility if needed.

📖 Source

âš ī¸ WARNING - timing-attack-safe

bcrypt.compare() uses constant-time comparison to prevent timing attacks. Never use === or == to compare hashes directly - always use bcrypt.compare().

📖 Source


genSalt()​

Generates a random salt for use with hash() function

Import:

import { genSalt } from 'bcryptjs';

Postconditions​

What happens after calling this function:

🔴 ERROR - gensalt-invalid-rounds

Condition: rounds parameter 4 or 31

Throws: Error: Rounds out of range (4-31)

Required Handling:

Caller MUST wrap genSalt() in try-catch or use .catch() handler when rounds parameter could be invalid. Validate rounds before calling.

📖 Source

🔴 ERROR - gensalt-type-error

Condition: rounds parameter is not a number

Throws: Error: Illegal arguments: [actual_type]

Required Handling:

Caller MUST validate rounds is a number. Common error when reading from environment variables or config files without parsing to integer.

📖 Source

🔴 ERROR - gensalt-rng-failure

Condition: random number generator fails (browser context without setRandomFallback)

Throws: Error: Secure random number generator not available

Required Handling:

Caller MUST handle RNG failures. In browser environments, call bcrypt.setRandomFallback() to provide a CSPRNG fallback.

📖 Source

Edge Cases​

Known gotchas and sharp edges:

âš ī¸ WARNING - browser-rng-requirement

In browser environments, a cryptographically secure random number generator must be provided via setRandomFallback() or genSalt() will fail. Node.js environments use crypto.randomBytes() automatically.

📖 Source


Example: Proper Error Handling​

import bcryptjs from 'bcryptjs';

async function example() {
try {
const result = await hash(/* args */);
// Handle success
return result;
} catch (error) {
// Handle error according to contract postconditions
console.error('Error:', error);
throw error;
}
}

See Also​