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

ridgen

v0.1.0

Published

A lightweight, high-performance Rust library for generating secure, URL-friendly unique string IDs, with WASM support.

Downloads

11

Readme

ridgen

日本語 | English

A lightweight, high-performance Rust library for generating secure, URL-friendly unique string IDs.

Comparison with JavaScript Libraries

All tests performed with 1,000,000 iterations:

| Library | Language | Time (ms) | Throughput (million IDs/sec) | Notes | | ---------- | ---------- | --------- | ---------------------------- | ------------------------------ | | ridgen | Rust | ~340 | ~3.0 | This implementation ⚡ | | uuid (v4) | JavaScript | 375 | ~2.7 | Standard UUID v4 | | nanoid | JavaScript | 431 | ~2.3 | Widely used original      | | shortid | JavaScript | 3,220 | ~0.3 | Deprecated, slower | | cuid2 | JavaScript | 34,274 | ~0.03 | Collision-resistant |

Key Takeaways

  • ridgen achieves ~3.0 million IDs/sec throughput
  • ~11% faster than uuid v4 while providing URL-friendly IDs
  • ~30% faster than nanoid
  • 9.5x faster than shortid
  • 88x faster than cuid2
  • Achieves maximum performance through batch random number generation

Note: The comparison is against JavaScript implementations running on Node.js. Rust implementations of UUID are not included in this benchmark.

Features

  • 🚀 Fast: ~3.0 million IDs/sec
  • 🔒 Secure: Uses cryptographically strong random number generation
  • 📦 Lightweight: Minimal dependencies
  • Simple API: Easy to use with error handling
  • Optimized: Batch random number generation for maximum performance

Installation

For Rust

Add this to your Cargo.toml:

[dependencies]
ridgen = "0.1.0"

For JavaScript/TypeScript (WASM)

npm install ridgen

Usage

Rust

use ridgen::generate;

fn main() {
    // Generate a 16-character ID
    match generate(16) {
        Ok(id) => println!("Generated ID: {}", id),
        Err(e) => eprintln!("Error: {:?}", e),
    }
}

JavaScript/TypeScript

This package is built with WASM and supports modern environments.

import { generate } from "ridgen";

const id = generate(16);
console.log(`Generated ID: ${id}`);

Supported Environments

  • Node.js: (ESM) v14.16.0 or later
  • Bun: Native support
  • Deno: Supported
  • Modern bundlers: Vite, Webpack, Rollup

[!IMPORTANT]

  • ESM Only: This package only supports ECMAScript Modules (ESM). CommonJS (require) is not supported.
  • WASM Initialization: In environments that support top-level WASM (like Bun or Webpack), it works immediately. For other environments, ensure your bundler is configured to handle .wasm files.

Benchmarks

Environment

  • Date: 2026-01-20
  • CPU: x86_64
  • Rust: 1.92.0
  • Build: release
  • Node.js: v24.12.0

Rust (ridgen)

Performance test with 1,000,000 iterations generating 16-character IDs:

- Total time: ~340ms (average)
- Throughput: ~2.9-3.0 million IDs/sec

Note: Uses thread_rng (Default) for random number generation. Why no SmallRng?: Although SmallRng is faster, it is not cryptographically secure. ridgen prioritizes security by using thread_rng to ensure IDs are unpredictable, while maintaining high performance through batch generation. Optimization: Uses batch random number generation (RngCore::fill_bytes) instead of calling gen_range() for each character, reducing CPU instruction count and improving performance by ~20-25%.

Character Set

The library uses a URL-safe character set:

  • Lowercase letters: a-z
  • Uppercase letters: A-Z
  • Numbers: 0-9

Total: 62 characters

Error Handling

The generate function returns a Result<String, RidgenError>:

  • Ok(String): Successfully generated ID
  • Err(RidgenError::InvalidLength): If length is 0

Safety and unsafe Usage

This library uses a small amount of unsafe code for performance reasons.

Specifically, String::from_utf8_unchecked is used when constructing the final ID string.

Why is this safe?

  • The character set consists only of ASCII characters (a-zA-Z0-9)
  • Each byte pushed into the buffer is guaranteed to be valid UTF-8
  • No user input or external data is involved

Because these invariants are strictly controlled, skipping UTF-8 validation is safe and avoids unnecessary runtime checks.

Trade-off

  • ✅ Improved performance (avoids an extra UTF-8 validation pass)
  • ⚠️ Requires careful maintenance if the character set changes

If the character set is ever modified to include non-ASCII characters, this unsafe usage must be revisited.

Distribution Characteristics

This implementation uses a simple modulo operation to map random bytes to the character set:

index = random_byte % 62

Modulo Bias

Since 256 is not evenly divisible by 62, this introduces a small distribution bias:

  • The first 8 characters in the charset have a slightly higher probability
  • The bias is approximately 1/256 per character

Why this is acceptable here

  • The bias is extremely small and negligible for most ID generation use cases
  • This approach avoids additional branching and rejection sampling, improving performance
  • Many real-world ID systems accept this trade-off for speed

Security Note

This library prioritizes performance and simplicity over perfect uniform distribution. If strict cryptographic uniformity is required, consider using rejection sampling or other methods.

Running Benchmarks

Rust Benchmark

cargo run --release

JavaScript Benchmark

cd ../js-nanoid-bench
npm install
node benchmark.js

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.