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 🙏

© 2025 – Pkg Stats / Ryan Hefner

legid

v0.1.4

Published

A library for generating safe, legit and random URL-safe IDs

Downloads

69,489

Readme

legid

A library for generating safe, legit and random URL-compat IDs.

Unlike other random ID libs, Legid is to solve the client-side manipulation problem. Read the example below.

Why use Legid?

In a modern web application, you often need to generate short and unique IDs on the client side:

<button onClick={async () => {
  // Some function to generate a random ID
  const id = generateId()

  // Optimistically update the URL so the user will see the page immediately
  router.push(`/tweet/${id}`)

  // Send the actual request to post the tweet
  await createTweet(id, content)
}}>
  Submit Tweet
</button>

Usually, you would use a random string generator or just a UUID. However, the main problem with these approaches is client-side manipulation and man-in-the-middle attacks.

For example, if a malicious user overrides the client generateId implementation via browser developer tools to return an ID of their choice, such as "admin", the server would accept it without any verification. And suddenly, the user successfully created a tweet with the special URL /tweet/admin, which is not what we want to happen.

Usually, this can be solved by generating the ID on the server side, or by using both an ID and a verification token/nonce. But we want to avoid:

  • Extra network request before knowing the ID
  • Storing pre-generated IDs on the server
  • Sending one-off tokens or nonces between client and server
  • Using a wordlist on the server to filter out not-allowed IDs

Legid is here to solve this problem.

Features

The legid library provides a simple and secure way to generate and verify IDs that only consist of URL-safe characters (A-Z, a-z, 0-9). It is designed to be:

  • Safe to use on the client side
    • Avoids manipulation
    • Prevents malicious tampering
  • Easy to verify on the server side
    • No nounce or shared secret necessary between client and server
    • No extra token or verification step required

Usage

pnpm install legid

Client side

Create a random ID string:

import { createId } from 'legid'

const id = await createId()

// Example: 'e3N4BRJW2d'

Specify the custom ID length (approximate) and hash salt (see below) if needed:

import { createId } from 'legid'

const id = await createId({
  approximateLength: 20,  // Custom length, default is 10
  salt: 'my-custom-salt', // Custom salt, default is 'legid:'
})

// Example: 'gnzJb1TCJobhuG4PrIZz'

It’s safe to expose the salt on the client side, as it is not a secret. Make sure the verification on the server side uses the same salt.

Server side

Use the verify function to check if an ID is valid:

import { verifyId } from 'legid'

// Server Side
const isValid = await verifyId(id)

When isValid is false, the ID is either malformed or not generated by legid.

The verifyId function can also accept a custom salt just like createId:

import { verifyId } from 'legid'

const isValid = await verifyId(id, {
  salt: 'my-custom-salt', // Custom salt, default is 'legid:'
})

How it works

The generated ID consists of a random data buffer with its SHA-1 hash. These 2 parts are mixed together at odd and even positions, respectively, and then converted to a custom alphabet (A-Z, a-z, 0-9). The SHA-1 hash is salted with a prefix to prevent rainbow table attacks.

The reversed process is used to verify the ID.

This means that if a malicious user tries to generate an ID with a specific value, let’s say "admin", conceptually they need to ensure that SHA1(salt + "di") starts with "amn" so the mixed ID would be "admin". This is very unlikely to happen, at least not with a reasonable amount of effort.

Note

While this is not a cryptographic solution, it is designed to make it difficult to manipulate the ID with lowest effort. It is not intended for use in cryptographic applications or where high security is required.

Collisions are still possible. The format Legid uses will decrease the possible generation space. For a given length L, there will be approximately 62^(L/2) IDs available. You should always check collision and ID length on the server side before proceeding.

Possible adjustments can be made to this lib by changing RHRHRH (R for random data position, H for hash positions) to other representations like HRRHRR to reduce the collision rate with a compromise of security.

Author

Created by Shu Ding @vercel.

License

The MIT License.