@hyperfrontend/random-generator-utils§

Two boards side by side under a createRandomGenerator(2026) chip; grains fall one at a time from the top into columns, and as hundreds land the uniform board settles into a flat plateau while the gaussian board rises into a bellTwo boards side by side under a createRandomGenerator(2026) chip; grains fall one at a time from the top into columns, and as hundreds land the uniform board settles into a flat plateau while the gaussian board rises into a bell

Statistical random distributions and UUID generation for simulations, testing, and procedural content.

What is @hyperfrontend/random-generator-utils?

@hyperfrontend/random-generator-utils provides random number generators beyond JavaScript's basic Math.random(), focusing on statistical distributions used in simulations, load testing, and procedural generation. It includes Gaussian (normal), exponential, power law, and logarithmic distributions, plus UUID v4 generation and a seeded generator that replays every one of them from a single number.

Unlike cryptographic random generators (like Web Crypto API), these utilities prioritize reproducibility and distribution shapes over security. createRandomGenerator(seed) turns one number into a deterministic stream of every distribution for tests and procedural scenes, while the same distributions model real-world phenomena like response times, user behavior, and natural variation.

Key Features

  • Statistical distributions

    Gaussian, exponential, power law, logarithmic, uniform

  • Seeded streams

    createRandomGenerator(seed) replays every distribution and UUID from one seed

  • Pluggable source

    every distribution accepts a () => number source, so any generator can drive it

  • UUID v4 generation

    with validation (uuidV4(), isUuidV4())

  • Stateless seeded hash

    (randomPseudo()) for one-off reproducible values

  • Time-based seeding

    for pseudo-random variations

  • No third-party dependencies

    at runtime it imports only JavaScript built-ins and @hyperfrontend utilities

  • Pure functions

    for functional composition

Why Use @hyperfrontend/random-generator-utils?

Realistic Load Testing and Simulations

Math.random() generates uniform distributions, but real-world events follow different patterns. User response times cluster around an average (Gaussian), server failures often show exponential decay, and popularity follows power law distributions (80/20 rule). These generators let you model realistic scenarios in load tests and simulations.

Reproducible Pseudo-Random Sequences for Testing

createRandomGenerator(seed) returns a stream whose every method (uniform, gaussian, exponential, powerLaw, logarithmic, uuidV4) replays exactly for the same seed. Log the seed when a property test fails and pass it back in to reproduce the input, or derive it from a record id so every visitor sees the same procedural scene. For a single reproducible value with no stream to carry, randomPseudo(seed) hashes a number straight to a result, and randomPseudoTimeBased() does the same for a date, which gives daily or hourly variations that stay stable within their window.

UUID Generation Without External Dependencies

Many projects pull in the uuid package (500KB+) just for v4 UUIDs. This library provides a lightweight alternative with both generation and validation. Ideal for test fixtures, trace IDs, or non-security-critical unique identifiers without bloating bundles.

Functional Composition for Data Pipelines

All generators are pure functions accepting parameters and returning numbers. This makes them composable in data generation pipelines, Array methods (Array.from({ length: 100 }, () => randomGaussian(0, 100))), or streaming data generators for charts and visualizations.

Installation

npm install @hyperfrontend/random-generator-utils

Quick Start

import {
  createRandomGenerator,
  randomGaussian,
  randomExponential,
  randomPowerLaw,
  randomUniform,
  randomPseudo,
  uuidV4,
  isUuidV4,
} from '@hyperfrontend/random-generator-utils'

// Gaussian (normal) distribution - ideal for modeling natural variation
const responseTime = randomGaussian(100, 300) // ms, centered around 200ms
const userHeight = randomGaussian(160, 180) // cm, most values near 170cm

// Exponential distribution - models time between independent events
const timeBetweenRequests = randomExponential(0.5) // λ=0.5, mean=2 seconds
const failureRate = randomExponential(0.1) // λ=0.1, mean=10 units

// Power law distribution - models "rich get richer" phenomena
const popularity = randomPowerLaw(2, 1, 1000) // Few items very popular
const citySize = randomPowerLaw(1.1, 100, 1000000) // Zipf's law for cities

// Uniform distribution - flat probability across range
const randomDelay = randomUniform(0, 1000) // Any value 0-1000ms equally likely

// Seeded stream - every distribution replays from one number
const stream = createRandomGenerator(2026)
const size = stream.gaussian(24, 96) // Same value on every run that seeds 2026
const gap = stream.exponential(0.5) // ...and the next draw, and the next
const fixtureId = stream.uuidV4() // Stable ids for snapshot fixtures

// Any distribution can draw from the stream directly
const angle = randomUniform(0, 360, stream.next)

// Stateless seeded hash for a one-off reproducible value
const seed = 42
const value1 = randomPseudo(seed) // Always same output for seed=42
const value2 = randomPseudo(seed) // Identical to value1

// UUID generation
const id = uuidV4() // "a3bb189e-8bf9-4558-9e3e-e7b9a9e7b8c1"
console.log(isUuidV4(id)) // true
console.log(isUuidV4('not-a-uuid')) // false

API Overview

Five distributions, one call shape: parameters that describe the shape go in, a single number comes out. randomGaussian(min, max) clusters draws around the midpoint of a bounded range and never leaves it, randomExponential(lambda) decays with a mean of 1 / lambda, and randomPowerLaw(alpha, min, max) piles most of its mass near min while keeping a long tail out to max; randomLogarithmic and randomUniform cover the skewed and the flat cases. Every one of them ends with an optional source: () => number that defaults to Math.random, and that last parameter is the seam the rest of the package plugs into.

createRandomGenerator(seed) fills the seam. It returns a frozen object carrying the seed it was opened with, a next() that draws the stream's unit values, and one method per distribution, so a whole procedural scene or fixture set becomes a function of one number and replays draw for draw on any machine. The methods share a single stream, which means the order of the calls is part of what the seed reproduces. next is a plain function and detaches cleanly, so randomUniform(0, 360, stream.next) puts a free-standing distribution on the same stream.

Two smaller pieces sit outside the stream. randomPseudo(seed) is a stateless hash rather than a generator: one seed maps to one value forever, which is what you want for a single reproducible number and not what you want for a sequence (randomPseudoTimeBased is the same hash over a Date, which is how you get a variation that holds steady for a day or an hour). And uuidV4() generates a version 4 id, drawing from a seeded source when you hand it one, with isUuidV4 to check a string coming back the other way.

Every parameter, bound and return type is in the API reference.

Use Cases

Load Testing

// Model realistic user behavior with varying response times
const users = Array.from({ length: 1000 }, () => ({
  thinkTime: randomExponential(0.5), // Time between actions
  responseTime: randomGaussian(50, 200), // Server response latency
  requestCount: Math.floor(randomPowerLaw(2, 1, 100)), // Request frequency
}))

Test Data Generation

// Generate reproducible test datasets: log stream.seed, replay the run
const stream = createRandomGenerator(Date.now())
const testData = Array.from({ length: 50 }, () => ({
  id: stream.uuidV4(),
  score: stream.gaussian(0, 100),
  timestamp: new Date(Date.now() + stream.uniform(0, 86400000)),
}))

Procedural Content

// Generate varied but natural-looking values
const terrain = {
  height: randomGaussian(0, 100), // Centered around 50
  vegetation: randomUniform(0, 1), // Uniform coverage
  populationDensity: randomPowerLaw(2, 1, 1000), // Power law distribution
}

Compatibility

Runs on

  • Node.js>=18.0.0supported
  • Browserssupported
  • Web Workerssupported

Ships as

  • ESMTree-shakeable
  • CJSNode and older bundlers
  • IIFEHyperfrontendRandomGenerator
  • UMDHyperfrontendRandomGenerator

CDN Usage

<!-- unpkg -->
<script src="https://unpkg.com/@hyperfrontend/random-generator-utils"></script>

<!-- jsDelivr -->
<script src="https://cdn.jsdelivr.net/npm/@hyperfrontend/random-generator-utils"></script>

<script>
  const { randomGaussian, randomUniform, uuid4 } = HyperfrontendRandomGenerator
</script>

Global variable: HyperfrontendRandomGenerator

Architecture Highlights§

Every distribution is a mathematical transform over a unit draw. The draw comes from a source that defaults to Math.random() and can be any () => number; createRandomGenerator supplies a mulberry32 stream, a 32-bit generator with a period of 2^32 draws. Gaussian uses the polar form of the Box-Muller transform, exponential uses inverse transform sampling, and randomPseudo is a stateless sine hash.

API Reference§

Filter:

ƒFunctions

§function

createRandomGenerator(seed: number): RandomGenerator

Creates a seeded stream that replays every distribution in this package from one seed.
The same seed gives the same values in the same order on every run and every machine, so a procedural scene, a fixture set, or a simulation becomes a function of one number. The methods share a single stream: interleave the calls differently and the values move, so keep the draw order stable wherever reproducibility matters.

Parameters

NameTypeDescription
§seed
number
Any finite number. Nearby, fractional, and negative seeds all open distinct streams.

Returns

RandomGenerator
A frozen generator whose next is a plain function, safe to hand to any distribution as its source.

Examples

The same scene on every load

const stream = createRandomGenerator(2026)
const trees = Array.from({ length: 40 }, () => ({
  x: stream.uniform(0, 800),
  height: stream.gaussian(60, 140),
}))
// => identical positions and heights on every run that seeds 2026

Replaying a failing property test

const stream = createRandomGenerator(Date.now())
const input = stream.powerLaw(2, 1, 10000)
// Log stream.seed when the assertion fails, then pass it back in to reproduce the exact input.

Seeding a free-standing distribution

const { next } = createRandomGenerator(7)
const wait = randomExponential(0.5, next)
§function

isUuidV4(str: string): boolean

Validate if a string is a version 4 UUID.

Parameters

NameTypeDescription
§str
string
the string to be validated.

Returns

boolean
true if the string is a version 4 UUID, otherwise false.

Example

Validating user input as UUID

isUuidV4('a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d')
// => true

isUuidV4('not-a-uuid')
// => false

// Version 1 UUID (has '1' in third segment, not '4')
isUuidV4('550e8400-e29b-11d4-a716-446655440000')
// => false
§function

randomExponential(lambda: number, source: RandomSource): number

Generates a random number following an exponential distribution.

Parameters

NameTypeDescription
§lambda
number
The rate parameter (λ) controlling the distribution shape; must be a positive finite number
§source
RandomSource
Where the unit draw comes from; defaults to the built-in Math.random
(default: random)

Returns

number
A random number from the exponential distribution

Examples

Modeling time between events (e.g., customer arrivals)

// Higher lambda = shorter average wait time
const averageWaitMinutes = 5
const lambda = 1 / averageWaitMinutes
const waitTime = randomExponential(lambda)
// => 3.7 (varies each call, most values clustered near 0-10)

Replaying the same arrival gaps from a seed

const { next } = createRandomGenerator(7)
const gapSeconds = randomExponential(0.5, next)
// => the same gap on every run that seeds 7
§function

randomGaussian(min: number, max: number, source: RandomSource): number

Generates a random number following a Gaussian (normal) distribution within a specified range.

Parameters

NameTypeDescription
§min
number
The minimum value of the range
§max
number
The maximum value of the range
§source
RandomSource
Where the unit draws come from; defaults to the built-in Math.random
(default: random)

Returns

number
A random number from the Gaussian distribution bounded by min and max

Examples

Simulating human heights in centimeters

const heightCm = randomGaussian(150, 200)
// => 174.3 (most values cluster around the midpoint 175)

Generating test scores with realistic distribution

const testScore = randomGaussian(0, 100)
// => 52.8 (bell curve centered at 50, rarely hits extremes)

Drawing from a seeded stream instead of `Math.random`

const { next } = createRandomGenerator(7)
const size = randomGaussian(24, 96, next)
// => the same size on every run that seeds 7
§function

randomLogarithmic(scale: number, source: RandomSource): number

Generates a random number following a logarithmic distribution.

Parameters

NameTypeDescription
§scale
number
The scale parameter controlling the distribution spread
§source
RandomSource
Where the unit draw comes from; defaults to the built-in Math.random
(default: random)

Returns

number
A random number from the logarithmic distribution

Examples

Generating values with exponential growth characteristics

// scale=1 produces values from 1 to e (~2.718)
const smallScale = randomLogarithmic(1)
// => 1.8 (values between 1 and ~2.7)

// scale=5 produces values from 1 to e^5 (~148)
const largeScale = randomLogarithmic(5)
// => 42.3 (wider range, skewed toward lower values)

Drawing from a seeded stream instead of `Math.random`

const { next } = createRandomGenerator(7)
const growth = randomLogarithmic(5, next)
// => the same value on every run that seeds 7
§function

randomPowerLaw(alpha: number, min: number, max: number, source: RandomSource): number

Generates a random number following a power law distribution within a specified range.

Parameters

NameTypeDescription
§alpha
number
The standard Pareto/Zipf exponent: higher values concentrate more mass near min. Values between 1 and 3 are typical, alpha of 1 gives a log-uniform draw, and alpha of 0 gives a uniform draw.
§min
number
The minimum value of the range; must be a finite number greater than zero
§max
number
The maximum value of the range; must be a finite number greater than zero
§source
RandomSource
Where the unit draw comes from; defaults to the built-in Math.random
(default: random)

Returns

number
A random number from the power law distribution bounded by min and max

Examples

Simulating social network follower counts (few have many, many have few)

// alpha above 1 creates a long tail, so most values sit near min
const followerCount = randomPowerLaw(2.5, 1, 1000000)
// => 1.6 (typically low, occasionally very large)

Modeling file sizes in a system

const fileSizeKb = randomPowerLaw(2.0, 1, 10000)
// => 2 (many small files, rare large files)

Drawing from a seeded stream instead of `Math.random`

const { next } = createRandomGenerator(7)
const citySize = randomPowerLaw(1.1, 100, 1000000, next)
// => the same size on every run that seeds 7
§function

randomPseudo(seed: number): number

Hashes a seed to a pseudo-random number at or above 0 and below 1.
This is a stateless hash, not a stream: one seed maps to one value, and calling it twice with the same seed returns that value twice. To draw a reproducible sequence, or to seed the distributions, use createRandomGenerator instead. When deriving several values from one base seed here, give every property its own offset and keep one item's seeds clear of the next item's, because two draws from the same number are the same number.

Parameters

NameTypeDescription
§seed
number
The seed for the hash.

Returns

number
A pseudo-random number between 0 and 1.

Example

Reproducible random values for testing

// Same seed always yields the same result
randomPseudo(42)
// => 0.7845... (deterministic)

randomPseudo(42)
// => 0.7845... (identical)

randomPseudo(43)
// => 0.2525... (different seed, different result)
§function

randomPseudoTimeBased(seedTime: Date): number

Generates a deterministic pseudo-random variation based solely on the seed time.

Parameters

NameTypeDescription
§seedTime
Date
The seed time for the variation.

Returns

number
The pseudo-random variation as a number.

Example

Reproducible randomness for a specific timestamp

const releaseDate = new Date('2024-03-15T10:30:00Z')

// Same date always produces the same result
const value1 = randomPseudoTimeBased(releaseDate)
const value2 = randomPseudoTimeBased(releaseDate)
// value1 === value2 (deterministic)
§function

randomUniform(min: number, max: number, source: RandomSource): number

Generates a random number uniformly distributed within a specified range.

Parameters

NameTypeDescription
§min
number
The minimum value of the range (inclusive)
§max
number
The maximum value of the range (exclusive)
§source
RandomSource
Where the unit draw comes from; defaults to the built-in Math.random
(default: random)

Returns

number
A random number between min (inclusive) and max (exclusive)

Examples

Generating a random price within a budget range

const priceUsd = randomUniform(10, 50)
// => 27.34 (any value equally likely within range)

Random coordinates for game object placement

const xPosition = randomUniform(0, 800)
const yPosition = randomUniform(0, 600)
// => x: 342.7, y: 198.2

Drawing from a seeded stream instead of `Math.random`

const { next } = createRandomGenerator(7)
const startAngle = randomUniform(0, 360, next)
// => the same angle on every run that seeds 7
§function

uuidV4(source: RandomSource): string

Generates a version 4 UUID.

Parameters

NameTypeDescription
§source
RandomSource
Where the unit draws come from; defaults to the built-in Math.random
(default: random)

Returns

string
a version 4 UUID.

Examples

Creating unique identifiers for entities

const userId = uuidV4()
// => 'a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d'

const sessionId = uuidV4()
// => '9f8e7d6c-5b4a-4321-8765-4321fedcba98'

Stable ids for snapshot fixtures

const { next } = createRandomGenerator(7)
const fixtureId = uuidV4(next)
// => the same id on every run that seeds 7

Interfaces

§interface

RandomGenerator

A seeded stream of random values.
Two generators created from the same seed return the same values in the same order, for every method, on every machine. All methods draw from the one stream, so the order of the calls is part of what the seed reproduces.

Properties

§readonly next:RandomSource
Draws the next unit value: at or above 0 and below 1. Safe to pass around detached.
§readonly seed:number
The seed the stream was created from, kept so a run can be logged and replayed.

Types

§type

RandomSource

A source of unit draws: every call returns a number at or above 0 and below 1.
Every distribution in this package takes one as its last parameter and defaults to the built-in Math.random. Pass a seeded source, such as the next of a RandomGenerator, and the draw becomes reproducible.
type RandomSource = () => number

Browse guides filtered to this packageSuggest a guide