{"id":15539,"library":"bcrypt-ts","title":"bcrypt-ts","description":"bcrypt-ts is a TypeScript-first, pure JavaScript implementation of the bcrypt password-hashing function, designed for both Node.js and browser environments. It provides cryptographic hashing for passwords, focusing on security features like salting and an adaptive iteration count to resist brute-force attacks. The current stable version is 8.0.1. The project appears to have a relatively active release cadence, with major versions (v6, v7, v8) released over time, often driven by Node.js version support or build system changes. Key differentiators from `bcrypt.js` include being fully written in TypeScript, providing separate ESM modules optimized for Node.js and browsers, offering better tree-shaking, and having a minified output. While compatible with the C++ `bcrypt` binding, it's inherently slower due to being a pure JavaScript implementation (approximately 30% slower according to the README, referencing `bcrypt.js` benchmarks), which means fewer iterations can be performed in the same timeframe, requiring careful consideration of the work factor.","status":"active","version":"8.0.1","language":"javascript","source_language":"en","source_url":"git://github.com/Mister-Hope/bcrypt-ts","tags":["javascript","bcrypt","bcryptjs","typescript"],"install":[{"cmd":"npm install bcrypt-ts","lang":"bash","label":"npm"},{"cmd":"yarn add bcrypt-ts","lang":"bash","label":"yarn"},{"cmd":"pnpm add bcrypt-ts","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"CommonJS `require` is not supported since v8.0.0. Use named ESM imports for synchronous functions.","wrong":"const { genSaltSync } = require('bcrypt-ts')","symbol":"genSaltSync","correct":"import { genSaltSync } from 'bcrypt-ts'"},{"note":"CommonJS `require` is not supported since v8.0.0. Use named ESM imports for asynchronous functions. `hash` is an async function.","wrong":"const { hash } = require('bcrypt-ts')","symbol":"hash","correct":"import { hash } from 'bcrypt-ts'"},{"note":"This library uses named exports exclusively; there is no default export. Ensure you import specific functions by name.","wrong":"import bcrypt from 'bcrypt-ts'; bcrypt.compareSync(...)","symbol":"compareSync","correct":"import { compareSync } from 'bcrypt-ts'"},{"note":"For specific Node.js bundle usage (e.g., if bundlers incorrectly pick the browser version), explicitly import from `bcrypt-ts/node`.","wrong":"import { hash } from 'bcrypt-ts'","symbol":"hash","correct":"import { hash } from 'bcrypt-ts/node'"}],"quickstart":{"code":"import { genSalt, hash, compare } from 'bcrypt-ts';\n\nasync function main() {\n  // Generate a salt with a work factor of 10\n  // A higher work factor increases security but also computation time\n  const saltRounds = 10;\n  console.log(`Generating salt with ${saltRounds} rounds...`);\n  const salt = await genSalt(saltRounds);\n  console.log('Salt generated:', salt);\n\n  // Hash a password using the generated salt\n  const password = process.env.USER_PASSWORD ?? 'mySecurePassword123!';\n  console.log('Hashing password...');\n  const hashedPassword = await hash(password, salt);\n  console.log('Hashed password:', hashedPassword);\n\n  // To store in your database, ensure the column can hold 60 characters\n\n  // Verify a password against the stored hash\n  const candidatePassword = process.env.LOGIN_PASSWORD ?? 'mySecurePassword123!';\n  console.log(`Comparing '${candidatePassword}' with hash...`);\n  const isMatch = await compare(candidatePassword, hashedPassword);\n  console.log('Password matches:', isMatch);\n\n  const wrongPassword = 'notThePassword';\n  console.log(`Comparing '${wrongPassword}' with hash...`);\n  const isWrongMatch = await compare(wrongPassword, hashedPassword);\n  console.log('Wrong password matches:', isWrongMatch);\n}\n\nmain().catch(console.error);","lang":"typescript","description":"This quickstart demonstrates how to asynchronously generate a salt, hash a password, and then compare a candidate password against the stored hash using `bcrypt-ts`."},"warnings":[{"fix":"Migrate your codebase to use ES module `import` syntax instead of `require()`. Ensure your `package.json` specifies `\"type\": \"module\"` or uses `.mjs` file extensions for ESM files. Update your build tools to handle ESM.","message":"Version 8.0.0 and above drop support for CommonJS (cjs) and UMD builds. The package is now exclusively ESM. This requires projects to use `import` statements and have their environment configured for ESM.","severity":"breaking","affected_versions":">=8.0.0"},{"fix":"Update your Node.js runtime environment to version 20 or newer. Check your `engines` field in `package.json` to ensure compatibility and consider using a Node.js version manager like `nvm`.","message":"Version 7.0.0 introduced a breaking change by dropping support for Node.js 18. Subsequent versions, including 8.x, require Node.js 20 or higher.","severity":"breaking","affected_versions":">=7.0.0"},{"fix":"No direct fix is typically needed as bcrypt is designed to be backward compatible with different hash versions. However, be aware of this change if you are doing any low-level hash manipulation or validation against specific patterns.","message":"Version 6.0.0 changed the default hash generation to '2b' hashes. While bcrypt generally handles different versions, this indicates a change in the internal format used.","severity":"breaking","affected_versions":">=6.0.0"},{"fix":"When choosing the work factor (salt rounds), benchmark the hashing time on your production hardware and adjust the rounds downward to achieve your desired target time (e.g., 200-500ms). Do not blindly port work factors from C++ `bcrypt` implementations.","message":"bcrypt-ts is a pure JavaScript implementation and is approximately 30% slower than the native C++ bcrypt binding. This performance difference means that for the same security level (target time for hashing), you must use a lower 'salt rounds' (work factor) with `bcrypt-ts`.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Implement explicit length checks for user passwords *before* passing them to `bcrypt-ts`. Use `Buffer.byteLength(password, 'utf8')` to get the byte length and ensure it's `<= 72`. The library provides a `truncates(password)` utility for this.","message":"The maximum input password length for bcrypt is 72 bytes. Passwords longer than this will be truncated without explicit warning by the library itself for compatibility with the C++ binding. Note that UTF-8 characters can be up to 4 bytes.","severity":"gotcha","affected_versions":">=3.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Update your project to use ES module `import` syntax: `import { func } from 'bcrypt-ts';`. Ensure your `package.json` has `\"type\": \"module\"` or that the file importing `bcrypt-ts` has a `.mjs` extension.","cause":"`bcrypt-ts` v8.0.0 and later are pure ESM, but your project or file is attempting to import it using CommonJS `require()` syntax.","error":"Error [ERR_REQUIRE_ESM]: require() of ES Module .../bcrypt-ts/dist/index.mjs from .../your-app.js not supported. Instead change the require of index.mjs to a dynamic import() which is available in all CommonJS modules."},{"fix":"Upgrade your Node.js environment to version 20 or newer. You can use a Node.js version manager like `nvm` to switch versions (e.g., `nvm install 20 && nvm use 20`).","cause":"Your Node.js runtime version does not meet the minimum requirement specified by `bcrypt-ts` (Node.js >=20 for v8.x).","error":"ERR_PNPM_OUTDATED_ENGINE The current Node.js version is v18.x.x which is not supported by the package bcrypt-ts@8.0.1. Its engine is compatible with \"node\": \">=20\"."},{"fix":"Ensure your bundler (webpack, Vite, Rollup) is correctly configured to use the browser-specific bundle of `bcrypt-ts`. If issues persist, manually import from the browser bundle: `import { hash } from 'bcrypt-ts/browser'`.","cause":"The Node.js bundle is being used in a browser environment, and it expects the Node.js `crypto` module to be available for secure randomness.","error":"ReferenceError: crypto is not defined (when running in browser or bundler)"}],"ecosystem":"npm"}