Argon2 Hashing for Node.js
node-argon2 is a Node.js library providing native bindings to the reference Argon2 hashing algorithm, which is a key derivation function designed to be memory-hard and suitable for password hashing. The library is actively maintained with frequent minor and patch releases, currently stable at version 0.44.0. It aims to simplify the use of Argon2 in Node.js applications by offering prebuilt binaries for common platforms (since v0.26.0, expanded significantly in v0.40.0), reducing the need for local compilation. Key differentiators include robust TypeScript support, flexibility in configuring Argon2 parameters (e.g., time cost, memory cost, parallelism), and the ability to choose between Argon2i, Argon2d, or Argon2id variants, making it a secure choice for password storage. It requires Node.js >= 16.17.0, with Node 18 or 20 being recommended.
Common errors
-
Error: The module '\path\to\node_modules\argon2\lib\binding\napi-vX\argon2.node' was compiled against a different Node.js version. ... Module parse failed: Unexpected character '�' (1:0)
cause The prebuilt binary (or a locally compiled one) is incompatible with your current Node.js version or operating system/architecture.fixEnsure your Node.js version meets the package requirements (>=16.17.0, preferably 18/20). If using a non-standard environment or an older `argon2` version, try manually rebuilding: `npx @mapbox/node-pre-gyp rebuild -C ./node_modules/argon2`. -
Argument of type 'Buffer' is not assignable to parameter of type 'string'.
cause TypeScript 5.7 introduced changes to how `Buffer` types are handled, causing type mismatches with older `argon2` versions that weren't updated for this change.fixUpgrade to `argon2@0.43.1` or newer. This version specifically addresses compatibility issues with TypeScript 5.7's `Buffer` type changes. -
Error: Missing symbols, such as `_ZNSt ...` or `undefined symbol: ` (linker errors during compilation/runtime)
cause Link-Time Optimization (LTO) can sometimes cause symbol resolution issues in certain compilation environments.fixUpgrade to `argon2@0.41.0` or newer. This version disables LTO to prevent such symbol-related compilation errors. -
TS2345: Argument of type 'string | Buffer' is not assignable to parameter of type 'string'.
cause TypeScript definitions in `argon2` prior to v0.41.1 incorrectly typed byte inputs (e.g., `Buffer`) as `any` or had other inconsistencies.fixUpgrade to `argon2@0.41.1` or newer to get corrected TypeScript type declarations for inputs like passwords and salts.
Warnings
- breaking Node.js 16 is no longer supported after version 0.31.2 due to its End-of-Life. Users on Node.js 16 will experience build or runtime failures.
- breaking Older versions of `argon2` (<=0.30.3) had a security vulnerability in their dependency `@mapbox/node-pre-gyp`.
- gotcha Installing `argon2` on platforms without prebuilt binaries or specific environments requires a global `node-gyp` installation and a compatible C++ compiler (GCC >= 5 / Clang >= 3.3, or Visual Studio 2015+ on Windows).
- gotcha Before version 0.40.0, `argon2` did not ship prebuilt binaries for all platforms, leading to frequent compilation issues for users with diverse environments.
- gotcha TypeScript type definitions for byte inputs were incorrect (`any` instead of `Buffer`) in versions prior to 0.41.1, leading to type-checking issues.
Install
-
npm install argon2 -
yarn add argon2 -
pnpm add argon2
Imports
- hash
import argon2 from 'argon2'; argon2.hash(...);
import { hash } from 'argon2'; - verify
const argon2 = require('argon2'); argon2.verify(...);import { verify } from 'argon2'; - argon2 (all exports)
const { hash, verify } = require('argon2');import * as argon2 from 'argon2';
Quickstart
import { hash, verify } from 'argon2';
async function main() {
const password = process.env.USER_PASSWORD ?? 'mySecurePassword';
let hashedPassword: string;
try {
// Hash a password with default options (Argon2id)
hashedPassword = await hash(password);
console.log('Hashed password:', hashedPassword);
// Verify a password against a hash
if (await verify(hashedPassword, password)) {
console.log('Password matched!');
} else {
console.error('Password did not match.');
}
// Example of hashing with custom options (e.g., Argon2i, higher memory cost)
const customHashedPassword = await hash(password, {
type: 1, // argon2.ArgonType.Argon2i
memoryCost: 1024,
timeCost: 4,
parallelism: 2
});
console.log('Custom hashed password:', customHashedPassword);
} catch (err) {
console.error('An error occurred:', err);
}
}
main();