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

sequelize-bcrypt

v2.0.0

Published

Sequelize helper plugin to hash/compare fields

Readme

sequelize-bcrypt

Automatic bcrypt hashing and password comparison for Sequelize 6 models.

Requirements

  • Node.js 24 or newer
  • Sequelize 6
  • bcryptjs 3

Installation

npm install sequelize-bcrypt bcryptjs sequelize

sequelize is a peer dependency because the application must use the same Sequelize instance and version as the model. bcryptjs is installed as a runtime dependency.

Usage

import { DataTypes, Sequelize } from "sequelize";
import useBcrypt from "sequelize-bcrypt";

const sequelize = new Sequelize("sqlite::memory:");
const User = sequelize.define("User", {
  email: { type: DataTypes.STRING, allowNull: false },
  password: { type: DataTypes.STRING, allowNull: false },
});

useBcrypt(User);

const user = await User.create({
  email: "[email protected]",
  password: "correct horse battery staple",
});

user.authenticate("correct horse battery staple"); // true
user.authenticate("wrong password"); // false

CommonJS

const { DataTypes, Sequelize } = require("sequelize");
const { useBcrypt } = require("sequelize-bcrypt");

const sequelize = new Sequelize("sqlite::memory:");
const User = sequelize.define("User", {
  password: { type: DataTypes.STRING, allowNull: false },
});

useBcrypt(User);

Configuration

useBcrypt(User, {
  field: "password",
  rounds: 12,
  compare: "authenticate",
});
  • field: model attribute to hash. Defaults to password.
  • rounds: bcrypt cost factor from 4 to 31. Defaults to 12.
  • compare: instance method name. Defaults to authenticate.

Multiple fields are supported. Calling useBcrypt repeatedly for the same model and field is idempotent; registering the same field with a different cost factor throws an error.

useBcrypt(User, {
  field: "recoveryPassword",
  compare: "authenticateRecoveryPassword",
  rounds: 12,
});

How It Works

useBcrypt validates the configured field and adds a Sequelize beforeSave hook. The hook:

  1. Runs for both new records and updates.
  2. Hashes only when the configured field has changed.
  3. Leaves null and undefined values untouched.
  4. Rejects non-string values before persistence.
  5. Stores the hash only after bcrypt completes successfully.

The comparison method reads the current field value and calls bcrypt.compareSync. It returns false when the record has no valid hash or the plain value is not a string.

The plugin does not validate password strength, enforce a required field, or choose a password policy. Use Sequelize validators or application-level validation for those concerns.

Error Handling

Invalid configuration throws synchronously:

  • TypeError for a missing model, empty names, or an undefined model field.
  • RangeError when rounds is not an integer between 4 and 31.
  • Error when a comparison method already exists or a field is registered with a different cost factor.

Hashing failures are reported as BcryptError. The original bcrypt error is available through its cause property.

import useBcrypt, { BcryptError } from "sequelize-bcrypt";

try {
  useBcrypt(User, { rounds: 12 });
  await User.create({ password: "secret" });
} catch (error) {
  if (error instanceof BcryptError) {
    console.error("Password hashing failed", error.cause);
  }
}

API

interface BcryptOptions {
  field?: string;
  rounds?: number;
  compare?: string;
}

type BcryptCompareMethod = (plainValue: string) => boolean;

type BcryptModelStatic<T extends Model = Model> = ModelStatic<T> & {
  prototype: T & Record<string, BcryptCompareMethod>;
};

class BcryptError extends Error {}

function useBcrypt(model: ModelStatic<Model>, options?: BcryptOptions): void;

Migration Notes

Existing users can keep calling useBcrypt(Model, options) with the same options. The current implementation registers one idempotent beforeSave hook instead of separate create/save hooks, preventing double hashing during creation. It also compares against the current hash after a password update.

When upgrading, check that:

  • the configured field exists on the model;
  • the comparison method name is not already defined;
  • password fields contain strings before saving;
  • tests do not rely on comparing against a previous password hash.

Development

npm install
npm run check
npm run test:coverage
npm run build

The package publishes ESM, CommonJS, source maps, and TypeScript declarations from dist/. prepublishOnly runs checks, coverage, and build.

License

MIT © Mattia Malonni

Automatic bcrypt hashing and password comparison for Sequelize 6 models.

Requirements

  • Node.js 24 or newer
  • Sequelize 6
  • bcryptjs 3

Installation

npm install sequelize-bcrypt bcryptjs sequelize

Usage

import { DataTypes, Sequelize } from "sequelize";
import useBcrypt from "sequelize-bcrypt";

const sequelize = new Sequelize("sqlite::memory:");
const User = sequelize.define("User", {
  email: { type: DataTypes.STRING, allowNull: false },
  password: { type: DataTypes.STRING, allowNull: false },
});

useBcrypt(User);

const user = await User.create({
  email: "[email protected]",
  password: "correct horse battery staple",
});

user.authenticate("correct horse battery staple"); // true
user.authenticate("wrong password"); // false

useBcrypt registers one beforeSave hook. A password is hashed only when its field changes, so creation and updates are both covered without double hashing. Comparisons always use the current field value.

Configuration

useBcrypt(User, {
  field: "password",
  rounds: 12,
  compare: "authenticate",
});
  • field: model attribute to hash. Defaults to password.
  • rounds: bcrypt cost factor from 4 to 31. Defaults to 12.
  • compare: instance method name. Defaults to authenticate.

Multiple fields are supported. Calling useBcrypt repeatedly for the same model and field is idempotent; registering the same field with a different cost factor throws an error.

useBcrypt(User, {
  field: "recoveryPassword",
  compare: "authenticateRecoveryPassword",
  rounds: 12,
});

Nullish values are left untouched. Non-string values fail before persistence. Password strength and required-field validation should be enforced by the application or another Sequelize validation layer.

API

interface BcryptOptions {
  field?: string;
  rounds?: number;
  compare?: string;
}

type BcryptCompareMethod = (plainValue: string) => boolean;

type BcryptModelStatic<T extends Model = Model> = ModelStatic<T> & {
  prototype: T & Record<string, BcryptCompareMethod>;
};

class BcryptError extends Error {}

function useBcrypt(model: ModelStatic<Model>, options?: BcryptOptions): void;

Hash failures are reported as BcryptError with the original error available as cause.

Development

npm install
npm run check
npm run test:coverage
npm run build

The package publishes ESM, CommonJS, source maps, and TypeScript declarations from dist/. prepublishOnly runs checks, coverage, and build.

License

MIT © Mattia Malonni