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

garbados-crypt

v3.0.0-beta

Published

Easy password-based encryption, by garbados.

Readme

garbados-crypt

CI Coverage Status Stability NPM Version JS Standard Style

Easy password-based encryption, by garbados.

This library attempts to reflect informed opinions while respecting realities like resource constraints, tech debt, and so on. The idea is to provide some very simple methods that just do the hard thing for you.

For example:

const Crypt = require('garbados-crypt')

const crypt = new Crypt(password)
const encrypted = await crypt.encrypt('hello world')
console.log(encrypted)
> "O/z1zXHQ+..."
const decrypted = await crypt.decrypt(encrypted)
console.log(decrypted)
> "hello world"

Crypt only works with plaintext, so remember to use JSON.stringify() on objects before encryption and JSON.parse() after decryption. For classes and the like, you'll need to choose your own encoding / decoding approach.

Install

Use npm or whatever.

$ npm i -S garbados-crypt

Usage

First, require the library. Then get to encrypting!

const Crypt = require('garbados-crypt')

const crypt = new Crypt(password)

new Crypt(password, [salt, [opts]])

  • password: A string. Make sure it's good! Or not.
  • salt: A salt, either as a byte array or a string. If omitted or falsy, a random salt is generated. Rather than bother carrying this with you, use crypt.export() and Crypt.import() to transport your credentials!
  • opts: Options!
  • opts.iterations: The number of iterations to use to hash your password via Argon2. Defaults to 100.
  • opts.saltLength: The length of the salt to be generated, in bytes. Defaults to 16.
  • opts.memorySize: The number of kilobytes of RAM to use to generate a cryptographic key from a password. Defaults to 4096 KB. Must be a power of 2.
  • opts.parallelism: The number of threads to use when generating a cryptographic key. Defaults to 1, as Crypt assumes it operates in a single-threaded environment.

A note on modifying default settings

Crypt's defaults have been selected to afford a cryptographic strength that does not impose significant performance penalties to applications doing a lot of encrypted reads and writes, such as those using crypto-pouch. If you are facing an attacker with significant resources, such as state actors, consider increasing the iterations and memorySize options. This will impose notable performance penalties, but as a rule slower cryptography means slower cracking. You should only modify these settings if you know what you are doing!

async Crypt.new(password, [salt, [opts]])

An asynchronous version of Crypt's constructor. Unlike the synchronous constructor, using .new() awaits Crypt's setup phase, so that you can explicitly await any problems during setup rather than wait for them to surface during encryption.

async Crypt.import(password, exportString) => new Crypt

Instantiates a new Crypt instance using an encoded string generated by crypt.export(). Use this method to import credentials generated on another device!

  • password: A string, the same string password you used with the Crypt instance that generated the exportString!
  • exportString: A string generated by crypt.export().

async crypt.export() => string

Exports a string you can use to create a new Crypt instance with Crypt.import(). Rather than bother carrying around your password and salt, use this to transport credentials across devices!

async crypt.encrypt(plaintext) => ciphertext

  • plaintext: A string.
  • ciphertext: A different, encrypted string.

async crypt.decrypt(ciphertext) => plaintext

  • ciphertext: An encrypted string produced by crypt.encrypt().
  • plaintext: The decrypted message as a string.

If decryption fails, for example because your password is incorrect, an error will be thrown.

Development

First, get the source:

$ git clone [email protected]:garbados/crypt.git garbados-crypt
$ cd garbados-crypt
$ npm i

Use the test suite:

$ npm test

The test suite includes a small benchmarking test, which runs on the server and in the browser, in case you're curious about performance.

To see test coverage:

$ npm run cov

Regarding passwords

Passwords should be generally considered a form of vulnerability. An attacker that manages to solve your encryption, such as by exfiltrating encrypted values and then brute-forcing the decryption key, may gain access to the password you used to encrypt those values. As a result, I highly advise deriving a strong passcode from a memorable passphrase in a non-reversible way, such as by using Argon2 or another derivation function yourself. By using this passcode only for a specific app, you ensure that an attacker will not be able to discover your passphrase even if they crack the passcode.

You can even do this with Crypt itself:

const globalCrypt = await Crypt.new('your_passphrase')
const passcode = await globalCrypt.encrypt('some_context_phrase') // like the name of the associated app or service
const contextCrypt = await Crypt.new(passcode)
// now you can use contextCrypt to encrypt your data
// with strong guarantees that even if an attacker cracks your crypto,
// they will not obtain your passphrase.

How To Securely Store A Password

For a password-based encryption system, it makes sense to have a good reference on how to store passwords in a database. To this effect I have written this gist to demonstrate safe password obfuscation and verification. If you have any issue with the advice offered there, leave a comment!

Why TweetNaCl.js?

This library uses tweetnacl rather than native crypto. You might have feelings about this.

I chose it because it's fast on NodeJS, bundles conveniently (33kb!), uses top-shelf algorithms, and has undergone a reasonable audit.

That said, I'm open to PRs that replace it with native crypto while retaining Crypt's API.

License

Apache-2.0