A secure, modern TypeScript library for generating unique, memorable names using WordNet dictionaries. Consolidates features from unique-names-generator and haikunatorjs.
- Secure by default: Uses Node.js
cryptomodule for cryptographically secure random generation - WordNet dictionaries: 85,000+ words extracted from WordNet 3.1 (adjectives, nouns, verbs, adverbs)
- Fully typed: Complete TypeScript support with strict type checking
- Deterministic mode: Seed-based generation for reproducible results
- Highly configurable: Custom dictionaries, separators, styles, and token suffixes
- Zero dependencies: No runtime dependencies, minimal bundle footprint
- Tree-shakeable: Export only what you need
- Memory-efficient: WordPools for reduced memory footprint in constrained environments
pnpm add @revivifai/unique-namesimport { generate, haikunate, adjectives, nouns } from "@revivifai/unique-names";
// Simple usage with dictionaries
const name = generate({ dictionaries: [adjectives, nouns] });
// e.g., "brave-tiger"
// Haiku-style name with 4-digit suffix
const haiku = haikunate({ dictionaries: [adjectives, nouns] });
// e.g., "winter-snow-4829"The bundled WordNet dictionaries are substantial:
| Dictionary | Words | Source Size |
|---|---|---|
adjectives |
17,879 | ~264KB |
nouns |
55,239 | ~776KB |
verbs |
8,431 | ~108KB |
adverbs |
3,642 | ~60KB |
| Total | 85,191 | ~1.2MB |
This package has "sideEffects": false and supports tree-shaking. Import only what you need:
// Import only the generator (no dictionaries loaded)
import { generate } from "@revivifai/unique-names/generator";
// Import only specific dictionaries
import { adjectives } from "@revivifai/unique-names/dictionaries/adjectives";
import { nouns } from "@revivifai/unique-names/dictionaries/nouns";| Path | Description |
|---|---|
@revivifai/unique-names |
Full package (all exports) |
@revivifai/unique-names/generator |
Generator functions only |
@revivifai/unique-names/word-pool |
WordPool class and factories |
@revivifai/unique-names/dictionaries |
All dictionaries |
@revivifai/unique-names/dictionaries/adjectives |
Adjectives only |
@revivifai/unique-names/dictionaries/nouns |
Nouns only |
@revivifai/unique-names/dictionaries/verbs |
Verbs only |
@revivifai/unique-names/dictionaries/adverbs |
Adverbs only |
@revivifai/unique-names/utils/random |
Random utilities |
For browser environments, serverless functions, or memory-constrained contexts, use WordPool to select a subset of words:
import { WordPool, adjectives, nouns, generate } from "@revivifai/unique-names";
// Create a pool with 500 words (default size)
const adjPool = new WordPool({
dictionary: adjectives,
poolSize: 500, // Only 500 words in memory instead of 17,879
seed: "session-123", // Optional: reproducible selection
});
// Use the pool with generate
const name = generate({
dictionaries: [adjPool.getPool(), nouns],
});
// Refresh the pool to get a different selection
adjPool.refresh();Memory savings with WordPool:
- Full dictionary: ~1.2MB in memory
- 500-word pool: ~15KB in memory (98.75% reduction)
For maximum efficiency, lazy-load dictionaries:
import { WordPool, generate } from "@revivifai/unique-names";
// Create a pool with lazy loading
const nounPool = new WordPool({
dictionary: () => import("@revivifai/unique-names/dictionaries/nouns").then(m => m.nouns),
poolSize: 300,
});
// Load the dictionary when needed
await nounPool.load();
const name = generate({ dictionaries: [nounPool.getPool()] });Convenience functions for creating pools:
import {
createAdjectivePool,
createNounPool,
createVerbPool,
createAdverbPool,
} from "@revivifai/unique-names";
// Create pools with default size (500 words)
const adjPool = await createAdjectivePool();
const nounPool = await createNounPool(300); // Custom size
const seededPool = await createAdjectivePool(500, "my-seed"); // With seedGenerate a unique name with customizable options.
import { generate, adjectives, nouns, verbs } from "@revivifai/unique-names";
// Default: adjective + noun
const name = generate({
dictionaries: [adjectives, nouns],
});
// e.g., "calm-river"
// Three words
const name3 = generate({
dictionaries: [adjectives, nouns, verbs],
length: 3,
});
// e.g., "bright-star-shine"
// Custom separator and style
const styled = generate({
dictionaries: [adjectives, nouns],
separator: "_",
style: "uppercase",
});
// e.g., "BRAVE_TIGER"
// With token suffix
const withToken = generate({
dictionaries: [adjectives, nouns],
token: { length: 6, type: "numeric" },
});
// e.g., "brave-tiger-482931"
// Deterministic (same seed = same result)
const deterministic = generate({
dictionaries: [adjectives, nouns],
seed: "my-seed",
});| Option | Type | Default | Description |
|---|---|---|---|
dictionaries |
readonly (readonly string[])[] |
Required | Arrays of words to pick from |
separator |
string |
"-" |
Separator between words |
length |
number |
2 |
Number of words (≤ dictionaries.length) |
style |
"lowercase" | "uppercase" | "capital" |
"lowercase" |
Text transformation |
seed |
string | number |
— | Seed for deterministic generation |
token |
TokenOptions |
— | Token suffix configuration |
| Option | Type | Default | Description |
|---|---|---|---|
length |
number |
0 |
Length of token (0 = no token) |
type |
"numeric" | "hex" | "custom" |
"numeric" |
Character set |
chars |
string |
— | Custom characters (type: "custom") |
Generate a haiku-style name (adjective-noun-number). Compatible with haikunatorjs API.
import { haikunate, adjectives, nouns } from "@revivifai/unique-names";
// Default: adjective-noun-XXXX (4-digit number)
const name = haikunate({
dictionaries: [adjectives, nouns],
});
// e.g., "winter-forest-4829"
// Custom configuration
const custom = haikunate({
dictionaries: [adjectives, nouns],
separator: ".",
style: "capital",
token: { length: 6, type: "hex" },
});
// e.g., "Silent.Moon.3f2a8b"
// Disable token
const noToken = haikunate({
dictionaries: [adjectives, nouns],
token: { length: 0 },
});
// e.g., "bright-sun"The library includes WordNet 3.1 dictionaries:
| Dictionary | Count | Description |
|---|---|---|
adjectives |
17,879 | Descriptive words |
nouns |
55,239 | Things, places, concepts |
verbs |
8,431 | Actions |
adverbs |
3,642 | Modifiers |
import { adjectives, nouns, verbs, adverbs } from "@revivifai/unique-names";
// Use specific dictionaries
const actionName = generate({
dictionaries: [adverbs, verbs],
length: 2,
});
// e.g., "quickly-run"
// Custom dictionary
const colors = ["red", "blue", "green", "yellow"];
const animals = ["fox", "bear", "owl", "wolf"];
const custom = generate({
dictionaries: [colors, animals],
});
// e.g., "red-fox"Create a memory-efficient word pool.
const pool = new WordPool({
dictionary: adjectives, // Source dictionary
poolSize: 500, // Number of words in pool (default: 500)
seed: "my-seed", // Optional: for reproducible selection
});| Method | Description |
|---|---|
getPool() |
Get the active word pool (readonly string[]) |
load() |
Load the dictionary (required for lazy-loaded dictionaries) |
isLoaded() |
Check if the dictionary is loaded |
refresh() |
Select a new random subset from the source dictionary |
randomWord(random?) |
Get a random word from the pool |
| Property | Description |
|---|---|
size |
Number of words in the active pool |
This library uses Node.js crypto.randomBytes() for secure random number generation, making it suitable for:
- API key generation
- Unique identifiers
- Session tokens
- Any context where unpredictability matters
For deterministic use cases (testing, reproducibility), use the seed option which uses a seeded PRNG (Mulberry32).
Advanced users can access the underlying random utilities:
import {
secureRandomInt,
secureRandomElement,
SeededRandom,
} from "@revivifai/unique-names";
// Cryptographically secure random integer
const dieRoll = secureRandomInt(1, 7); // 1-6
// Secure random element from array
const pick = secureRandomElement(["a", "b", "c"]);
// Seeded PRNG for deterministic sequences
const rng = new SeededRandom("my-seed");
const value = rng.next(); // 0-1
const int = rng.nextInt(0, 100); // 0-99
const element = rng.nextElement(myArray);- WordNet dictionaries: 85,000+ words vs ~2,000
- Secure random: Uses
cryptomodule by default - No dependencies: Zero runtime dependencies
- TypeScript native: Written in TypeScript with full type safety
- Memory efficient: WordPool for reduced memory footprint
- Larger dictionaries: WordNet adjectives/nouns vs small predefined lists
- More options: Style transformations, custom dictionaries, multiple token types
- Deterministic mode: Optional seed-based generation
- Modern ESM: Native ES modules with tree-shaking support
Apache-2.0
- WordNet 3.1 © 2011 Princeton University. All rights reserved.
- Inspired by unique-names-generator by andreasonny83
- Inspired by haikunatorjs by Atrox