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

normaals-uuid

v1.0.0

Published

Generate human-readable IDs in Latvian with cryptographic randomness and configurable uniqueness

Readme

normaals-uuid

npm version npm downloads

Generate human-readable, unique identifiers using Latvian words with cryptographic security.

Instead of hard-to-remember UUIDs like 550e8400-e29b-41d4-a716-446655440000, get friendly IDs like Zaļš-Gurķis-a3b5c7 or Liela-Sarkana-Māja-1a2b3c4d.

Features

  • Human-readable: Uses real Latvian words instead of random characters
  • Grammatically correct: Adjectives automatically match noun gender (masculine/feminine)
  • Cryptographically secure: Uses Node.js crypto module for uniqueness
  • Highly configurable: Multiple formats, separators, and code lengths
  • Comprehensive dictionaries: 100+ nouns, 100+ adjectives, 30+ colors
  • UUID v4-level uniqueness: Low collision probability
  • Zero dependencies: Uses only Node.js built-in modules
  • Lightweight: Small footprint, fast generation
  • Full validation and parsing: Built-in tools to work with IDs

Installation

npm install normaals-uuid

Quick Start

const lvUuid = require('normaals-uuid');

// Generate a friendly UUID (with Latvian letters)
const id = lvUuid.generate();
console.log(id); // "Zaļš-Gurķis-a3b5c7"

// Generate URL-friendly UUID (without special letters)
const urlId = lvUuid.generate({ urlFriendly: true });
console.log(urlId); // "Zals-Gurkis-b4c6d8"

// Validate it
console.log(lvUuid.validate(id)); // true

// Parse it
console.log(lvUuid.parse(id));
// {
//   full: 'Zaļš-Gurķis-a3b5c7',
//   adjective: 'Zaļš',
//   noun: 'Gurķis',
//   code: 'a3b5c7',
//   words: ['Zaļš', 'Gurķis']
// }

API Reference

generate(options)

Generate a new human-readable UUID.

Options:

  • format (string): Format template. Default: 'adjective-noun-code'
    • 'noun-code' - e.g., "Gurķis-a3b5c7"
    • 'adjective-noun-code' - e.g., "Zaļš-Gurķis-a3b5c7"
    • 'color-noun-code' - e.g., "Sarkana-Māja-x9y2z1"
    • 'adjective-color-noun-code' - e.g., "Liels-Zils-Koks-m4n8p2"
  • separator (string): Character to separate parts. Default: '-'
  • codeLength (number): Length of the random code (4-32). Default: 6
  • urlFriendly (boolean): Convert Latvian special letters to ASCII. Default: false
  • includeTimestamp (boolean): Include timestamp for guaranteed uniqueness. Default: false

Returns: string - The generated UUID

Examples:

// Default format
lvUuid.generate();
// "Zaļš-Gurķis-a3b5c7"

// Color-noun format
lvUuid.generate({ format: 'color-noun-code' });
// "Sarkana-Māja-1b2c3d"

// Long format with custom separator
lvUuid.generate({
  format: 'adjective-color-noun-code',
  separator: '_',
  codeLength: 8
});
// "Liels_Zils_Koks_1a2b3c4d"

// Minimal format
lvUuid.generate({ format: 'noun-code' });
// "Kaķis-9f8e7d"

// URL-friendly (no special characters)
lvUuid.generate({ urlFriendly: true });
// "Zals-Gurkis-a3b5c7"

// URL-friendly with custom options
lvUuid.generate({
  format: 'color-noun-code',
  urlFriendly: true,
  separator: '_'
});
// "Sarkana_Maja_1b2c3d" (ā → a)

// Timestamp for guaranteed uniqueness
lvUuid.generate({ includeTimestamp: true });
// "Zaļš-Gurķis-mgyxcnk86733b8"

// Maximum safety (timestamp + longer code)
lvUuid.generate({
  includeTimestamp: true,
  codeLength: 12
});
// "Zaļš-Gurķis-mgyxcnk86733b8e9f0a1"

validate(id, options)

Validate if a string is a valid UUID in the expected format.

Parameters:

  • id (string): The ID to validate
  • options (object, optional): Same options used to generate the ID

Returns: boolean - true if valid, false otherwise

Examples:

lvUuid.validate('Zaļš-Gurķis-a3b5c7'); // true
lvUuid.validate('Invalid-ID'); // false
lvUuid.validate(''); // false

// Validate with specific format
const customId = lvUuid.generate({ format: 'adjective-color-noun-code' });
lvUuid.validate(customId, { format: 'adjective-color-noun-code' }); // true

parse(id, options)

Parse a UUID into its component parts.

Parameters:

  • id (string): The ID to parse
  • options (object, optional): Same options used to generate the ID

Returns: object|null - Parsed components or null if invalid

Examples:

lvUuid.parse('Zaļš-Gurķis-a3b5c7');
// {
//   full: 'Zaļš-Gurķis-a3b5c7',
//   adjective: 'Zaļš',
//   noun: 'Gurķis',
//   code: 'a3b5c7',
//   words: ['Zaļš', 'Gurķis']
// }

lvUuid.parse('Sarkana-Māja-1b2c3d', { format: 'color-noun-code' });
// {
//   full: 'Sarkana-Māja-1b2c3d',
//   color: 'Sarkana',
//   noun: 'Māja',
//   code: '1b2c3d',
//   words: ['Sarkana', 'Māja']
// }

lvUuid.parse('invalid-id'); // null

getDefaultConfig()

Get the default configuration object.

Returns: object - Default configuration

lvUuid.getDefaultConfig();
// {
//   format: 'adjective-noun-code',
//   separator: '-',
//   codeLength: 6,
//   wordCount: 2
// }

URL-Friendly Option

Latvian has special letters that may not work well in URLs, databases, or APIs. Use urlFriendly: true to convert them to ASCII equivalents:

| Latvian | ASCII | |---------|-------| | ņ, Ņ | n, N | | ķ, Ķ | k, K | | ļ, Ļ | l, L | | ū, Ū | u, U | | ā, Ā | a, A | | ē, Ē | e, E | | č, Č | c, C | | ģ, Ģ | g, G | | ī, Ī | i, I | | š, Š | s, S | | ž, Ž | z, Z |

Examples:

// With special letters (default)
lvUuid.generate();
// "Zaļš-Gurķis-a3b5c7"

// URL-friendly
lvUuid.generate({ urlFriendly: true });
// "Zals-Gurkis-a3b5c7"

// Both are valid and unique

When to use URL-friendly:

  • ✅ URLs and routes (/lobby/Zals-Gurkis-a3b5c7)
  • ✅ Database keys without UTF-8 support
  • ✅ API endpoints
  • ✅ File names
  • ✅ DNS-safe identifiers
  • ✅ Legacy systems

When to use regular (with special letters):

  • ✅ Display in UI (more authentic Latvian)
  • ✅ Modern databases with UTF-8 support
  • ✅ Internal identifiers
  • ✅ User-facing reference codes

Formats

1. noun-code (Minimal)

Just a noun and code.

Gurķis-a3b5c7
Māja-1b2c3d
Kaķis-9f8e7d

2. adjective-noun-code (Default)

An adjective that matches the noun's gender.

Zaļš-Gurķis-a3b5c7
Sarkana-Māja-1b2c3d
Mazs-Kaķis-9f8e7d

3. color-noun-code

A color that matches the noun's gender.

Zaļa-Māja-a3b5c7
Sarkans-Gurķis-1b2c3d
Zils-Kaķis-9f8e7d

4. adjective-color-noun-code (Extended)

Both adjective and color, both matching the noun's gender.

Liela-Sarkana-Māja-a3b5c7
Mazs-Zaļš-Gurķis-1b2c3d
Ātrs-Melns-Kaķis-9f8e7d

Grammatical Gender

Latvian nouns have gender (masculine or feminine), and adjectives must agree with the noun's gender. This library handles this automatically:

Masculine examples:

  • Zaļš-Gurķis-a3b5c7 (Green cucumber) - masculine adjective + masculine noun
  • Liels-Koks-1b2c3d (Big tree) - masculine adjective + masculine noun

Feminine examples:

  • Zaļa-Māja-9f8e7d (Green house) - feminine adjective + feminine noun
  • Liela-Zvaigzne-4c5d6e (Big star) - feminine adjective + feminine noun

Multi-word colors/adjectives: Some colors and adjectives consist of multiple words (e.g., "gaiši zaļš" = light green). These are properly formatted with each word capitalized and separated by dashes:

  • Gaiši-Zaļš-Koks-a3b5c7 (Light green tree)
  • Tumši-Zils-Ezers-1b2c3d (Dark blue lake)

The library contains:

  • 100+ nouns (both masculine and feminine)
  • 100+ adjectives (with both gender forms)
  • 30+ colors (with both gender forms, including compound colors)

Uniqueness Guarantees

The library uses Node.js crypto.randomBytes() to generate the alphanumeric suffix, providing cryptographically secure randomness similar to UUID v4.

Entropy calculation:

  • 6 hex characters = 24 bits = 16.7 million combinations
  • 8 hex characters = 32 bits = 4.3 billion combinations
  • Combined with word randomness = billions of unique combinations

Collision probability is extremely low for practical applications. The default 6-character code provides sufficient uniqueness for most use cases.

Use Cases

With Latvian Letters (Default)

  • Display in UI: Zaļš-Kaķis-a3b5c7
  • Customer support: Easy-to-communicate reference numbers
  • User-facing codes: More authentic and memorable
  • Internal identifiers: When UTF-8 is fully supported

URL-Friendly (urlFriendly: true)

  • URLs: /game/Zals-Kakis-a3b5c7
  • API endpoints: /api/lobby/Sarkana-Maja-1b2c3d
  • Database keys: Compatible with ASCII-only systems
  • File names: upload-Maza-Zvaigzne-5c6d7e.pdf
  • Email identifiers: Works in all email clients
  • QR codes: Better compatibility

General Use Cases

  • User session IDs
  • Order numbers
  • Transaction IDs
  • Game lobby IDs
  • Temporary passwords
  • Test data identifiers

Examples

See examples/usage.js for comprehensive examples:

node examples/usage.js

Testing

Run the test suite:

npm test

The tests include:

  • Basic generation
  • All format variations
  • Custom separators and code lengths
  • Validation and parsing
  • Uniqueness testing (10,000+ IDs)
  • Entropy verification
  • Error handling
  • Capitalization checks

Security Considerations

✅ What's Secure

  • Cryptographically Secure Random Generation: Uses Node.js crypto.randomBytes() for the code suffix
  • No Dependencies: Zero external dependencies = no supply chain vulnerabilities
  • Input Validation: All user inputs are validated
  • No Secrets: No hardcoded credentials or sensitive data

⚠️ Important Security Notes

NOT suitable for:

  • Cryptographic keys or secrets
  • Authentication tokens (JWT, API keys, etc.)
  • Password reset tokens
  • Any security-critical application where compromise would be severe

SUITABLE for:

  • Human-readable order numbers
  • Customer reference IDs
  • Non-security-critical session identifiers (with proper session management)
  • Tracking numbers
  • Test data identifiers
  • User-facing reference codes

Entropy Information

The default configuration provides:

  • 6 hex characters = 24 bits = ~16.7 million combinations
  • 8 hex characters = 32 bits = ~4.3 billion combinations
  • 12 hex characters = 48 bits = ~281 trillion combinations

For higher security requirements, increase the codeLength:

lvUuid.generate({ codeLength: 12 }); // 48 bits of entropy

Note: The word portion is predictable and contributes minimal entropy. Uniqueness and security come primarily from the cryptographically secure code suffix.

Requirements

  • Node.js >= 12.0.0
  • No external dependencies

License

MIT

Contributing

Contributions welcome! Feel free to:

  • Add more Latvian words to the dictionaries
  • Improve grammatical accuracy
  • Add new features
  • Report bugs
  • Submit pull requests

Author

Created for developers who want human-friendly identifiers in Latvian language.


Priecīgu kodēšanu! (Happy coding!)