{"id":16095,"library":"js-nacl","title":"js-nacl: High-level libsodium API","description":"js-nacl is a JavaScript library offering a high-level API for libsodium, a well-regarded cryptographic library based on NaCl. It operates by wrapping an Emscripten-compiled version of libsodium, providing robust cryptographic primitives for both Node.js and browser environments. The current stable version, 1.4.0, was released in late 2018 and is based on libsodium 1.0.18-stable. Key differentiators include its adherence to the security-focused libsodium API, cross-platform compatibility, and the use of WebAssembly (WASM) for performance since version 1.3.0. It aims to simplify complex cryptographic tasks, offering functions for encryption, decryption, hashing, and digital signatures. Browser usage requires support for the `window.crypto.getRandomValues` API. The project's release cadence historically followed libsodium updates, with a focus on stability and API consistency, though it has not seen recent updates since 2018.","status":"maintenance","version":"1.4.0","language":"javascript","source_language":"en","source_url":"https://github.com/tonyg/js-nacl","tags":["javascript","encryption","high-level","crypto","networking","nacl"],"install":[{"cmd":"npm install js-nacl","lang":"bash","label":"npm"},{"cmd":"yarn add js-nacl","lang":"bash","label":"yarn"},{"cmd":"pnpm add js-nacl","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"For Node.js, the module path must point directly to `lib/nacl_factory.js`. It exposes a factory, not the `nacl` instance directly.","wrong":"import { nacl_factory } from 'js-nacl';","symbol":"nacl_factory","correct":"const nacl_factory = require('js-nacl/lib/nacl_factory.js');"},{"note":"The core `nacl` API object is provided asynchronously via a callback to `nacl_factory.instantiate()` in both Node.js and browser environments. It's not a direct export or global.","wrong":"const nacl = require('js-nacl');","symbol":"nacl","correct":"nacl_factory.instantiate((nacl) => { /* use nacl API */ });"},{"note":"In a browser, the library creates a global `nacl_factory` object. ESM imports are not supported for this package.","wrong":"import * as nacl from 'js-nacl';","symbol":"Browser Global","correct":"<script src=\"node_modules/js-nacl/lib/nacl_factory.js\"></script>\n<script>\n  nacl_factory.instantiate((nacl) => { /* use nacl */ });\n</script>"}],"quickstart":{"code":"const nacl_factory = require('js-nacl/lib/nacl_factory.js');\n\nnacl_factory.instantiate((nacl) => {\n  if (!nacl) {\n    console.error('Failed to instantiate nacl library.');\n    return;\n  }\n\n  // Generate a random 32-byte key\n  const key = nacl.random_bytes(nacl.crypto_box_SECRETKEYBYTES);\n  console.log('Generated key (hex):', nacl.to_hex(key));\n\n  // Example: Generate a random nonce\n  const nonce = nacl.random_bytes(nacl.crypto_box_NONCEBYTES);\n  console.log('Generated nonce (hex):', nacl.to_hex(nonce));\n\n  // Example: Hash a message\n  const message = nacl.from_string('Hello, js-nacl!');\n  const hash = nacl.crypto_hash(message);\n  console.log('Hashed message (hex):', nacl.to_hex(hash));\n});\n","lang":"javascript","description":"This quickstart demonstrates how to instantiate the js-nacl library in Node.js, generate cryptographic keys, nonces, and compute a SHA512 hash using the libsodium API."},"warnings":[{"fix":"Update calls from `nacl_factory.instantiate()` returning a value to `nacl_factory.instantiate((nacl_instance) => { /* use nacl_instance */ })`.","message":"The `nacl_factory.instantiate` function's API changed to expect a callback as its first argument, which receives the `nacl` instance.","severity":"breaking","affected_versions":">=1.1.0"},{"fix":"Migrate code to use `nacl_factory.instantiate()` to obtain the functional `nacl` object instead of importing/accessing `nacl` directly.","message":"The library API was changed from directly providing a `nacl` module to providing `nacl_factory` with an `instantiate` function that returns the `nacl` instance.","severity":"breaking","affected_versions":">=0.5.0"},{"fix":"Update calls to the new names: `crypto_sign_seed_keypair` and `crypto_box_seed_keypair`. The old names are deprecated aliases and may be removed in future versions.","message":"Functions `crypto_sign_keypair_from_seed` and `crypto_box_keypair_from_seed` were renamed to `crypto_sign_seed_keypair` and `crypto_box_seed_keypair` respectively to align with libsodium naming conventions.","severity":"deprecated","affected_versions":">=1.2.0"},{"fix":"Upgrade to Safari 7.0 or a newer version. The library runs correctly on modern versions of Chrome, Firefox, and Safari.","message":"js-nacl is known to have issues and potential data corruption when running on Safari version 5.1.x, especially with Javascript debug mode disabled.","severity":"gotcha","affected_versions":"<7.0 (Safari)"},{"fix":"Ensure that the target browser environment supports `window.crypto.getRandomValues`. Most modern browsers provide this API.","message":"Browser usage of js-nacl requires support for the `window.crypto.getRandomValues` API for secure random number generation.","severity":"gotcha","affected_versions":"All"},{"fix":"Applications using `js-nacl` in Node.js should implement their own `uncaughtException` handling if required, as the library no longer provides this default behavior.","message":"As of version 1.3.2, the Emscripten-compiled code no longer adds a listener to the `uncaughtException` event in Node.js.","severity":"gotcha","affected_versions":">=1.3.2"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Always call `nacl_factory.instantiate((naclInstance) => { /* use naclInstance */ })` to get the `nacl` object. The instantiation is asynchronous.","cause":"Attempting to use the `nacl` API object directly without first instantiating it through `nacl_factory.instantiate()`.","error":"TypeError: nacl is not defined"},{"fix":"For Node.js, use `const nacl_factory = require('js-nacl/lib/nacl_factory.js');`. For browsers, ensure `<script src=\"lib/nacl_factory.js\">` is correctly placed before your script.","cause":"The `nacl_factory` object was not correctly loaded or required. In Node.js, often caused by an incorrect `require` path or trying to use ES Modules `import`.","error":"TypeError: nacl_factory.instantiate is not a function"},{"fix":"Ensure the browser is modern enough to support `window.crypto.getRandomValues` and that the script is running in a secure context (e.g., HTTPS) if the browser enforces it.","cause":"This error typically occurs in a browser environment when `window.crypto.getRandomValues` is not available or accessible, which is required by `js-nacl`.","error":"SecurityError: The operation is not supported."}],"ecosystem":"npm"}