Mathematically Correct Random Number Generation
Random.js is a JavaScript library designed to provide mathematically correct and consistent random number generation, addressing the shortcomings of `Math.random()` and common biased implementations. It offers various 'engines' like `nativeMath` (using `Math.random`), `browserCrypto` (using `crypto.getRandomValues`), `nodeCrypto` (using `crypto.randomBytes`), and `MersenneTwister19937` for deterministic, repeatable sequences. The library focuses on providing 32 bits of randomness consistently and includes distributions to prevent common biases in integer generation. The current stable version is 2.1.0, and while a specific release cadence isn't stated, it generally follows semver for major breaking changes. Its key differentiators include platform-specific cryptographic engines and a robust, bias-free API for various distributions, making it suitable for simulations, games, and other applications where high-quality randomness is crucial.
Common errors
-
TypeError: (0, random_js_1.MersenneTwister19937) is not a constructor
cause Attempting to use `MersenneTwister19937` directly as a constructor without first calling its static `seed()` method, or incorrectly importing it with CommonJS `require`.fixEnsure `MersenneTwister19937` is imported via named ES module syntax and that you call `.seed()` on it to get an engine instance: `import { MersenneTwister19937 } from 'random-js'; const engine = MersenneTwister19937.seed(123);` -
TypeError: Cannot read properties of undefined (reading 'integer')
cause This usually happens when `new Random()` is called without providing a valid engine, or when the `Random` class itself was not correctly imported (e.g., trying to use `Random` as a default import instead of a named import).fixMake sure to import `Random` as a named export (`import { Random } from 'random-js';`) and instantiate it with a valid engine (`new Random(MersenneTwister19937.seed(123))`). -
ReferenceError: crypto is not defined
cause Attempting to use `browserCrypto` or `nodeCrypto` engines in an unsupported environment (e.g., `browserCrypto` in Node.js, or `nodeCrypto` in a browser) or in an older browser lacking the `crypto` API.fixUse the appropriate engine for your environment (`nodeCrypto` in Node.js, `browserCrypto` in modern browsers). For cross-platform or older browser compatibility, `MersenneTwister19937` is a better choice.
Warnings
- breaking Upgrading from random-js v1.0 to v2.0 constitutes a major breaking change. The export structure was refactored from static properties on a single class-like function to individual named exports for each binding, aligning with modern ECMAScript module standards.
- gotcha Commonly used `Math.random()` has inconsistencies across JavaScript engines (e.g., 32-bit vs 53-bit randomness in Chrome/Node.js vs. Firefox/IE) and is non-deterministic. Relying solely on `Math.random()` can lead to non-repeatable results and insufficient entropy for critical applications.
- gotcha Most naive implementations of generating random integers within a range (e.g., `Math.floor(Math.random() * (max - min)) + min`) introduce subtle biases, leading to non-uniform distributions where some numbers are more likely to appear than others. This can silently break simulations or games.
- gotcha The `MersenneTwister19937` engine, while excellent for deterministic and repeatable sequences, is NOT cryptographically secure. Do not use it for generating keys, tokens, or any security-sensitive data.
- gotcha The `nativeMath` engine, which wraps `Math.random()`, may have a shorter period than expected, meaning its sequence of random numbers might repeat sooner. It's also non-deterministic.
Install
-
npm install random-js -
yarn add random-js -
pnpm add random-js
Imports
- MersenneTwister19937
const MersenneTwister19937 = require('random-js').MersenneTwister19937;import { MersenneTwister19937 } from 'random-js'; - Random
import Random from 'random-js';
import { Random } from 'random-js'; - integer
import { int } from 'random-js';import { integer } from 'random-js';
Quickstart
import { Random, MersenneTwister19937, integer } from 'random-js';
// Initialize a deterministic engine with a seed
const engine = MersenneTwister19937.seed(123);
// Create a Random instance with the engine
const random = new Random(engine);
// Generate a random integer between 1 and 100 (inclusive)
const randomNumber = random.integer(1, 100);
console.log(`Deterministic random number: ${randomNumber}`);
// Demonstrate using a non-deterministic engine (e.g., nodeCrypto in Node.js)
// In a browser, you might use browserCrypto; nativeMath is also an option.
// Note: nodeCrypto and browserCrypto are only available in their respective environments.
// For cross-platform or tests, MersenneTwister19937 is often preferred.
// Example with nodeCrypto (only works in Node.js environment)
// import { nodeCrypto } from 'random-js';
// const cryptoEngine = nodeCrypto;
// const randomCrypto = new Random(cryptoEngine);
// const cryptoNumber = randomCrypto.integer(1, 100);
// console.log(`Cryptographically random number: ${cryptoNumber}`);
// Generate 5 more deterministic numbers
for (let i = 0; i < 5; i++) {
console.log(`Next deterministic number: ${random.integer(1, 100)}`);
}