New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

dropid

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dropid

Human-readable, prefixed unique identifiers for database models

latest
Source
npmnpm
Version
1.0.0
Version published
Maintainers
1
Created
Source

DropID

npm version npm downloads License: MIT GitHub stars https://github.com/golddick/dropid.git Human-readable, prefixed unique identifiers for your database models.

dropid('user')        // → user_a3f2b9c1d4e5
dropid('post', 'app') // → app_post_x7k9m2n4p1q8

Why DropID?

Before (UUIDs):

550e8400-e29b-41d4-a916-446655440000

Good luck debugging that in your logs.

After (DropID):

user_a3f2b9c1d4e5

Instantly know what you're looking at.

Features

  • 🎯 Human-readable - Know what type of object an ID represents at a glance
  • 🔒 Collision-resistant - Uses nanoid under the hood (cryptographically secure)
  • 🚀 ORM-agnostic - Works with Drizzle, Prisma, TypeORM, or plain JavaScript
  • Lightweight - Single dependency (nanoid), ~2KB bundle
  • 🎨 Customizable - Configure length, alphabet, and separators
  • 🏢 Multi-tenant ready - Built-in prefix support for organization-scoped IDs
  • 📦 TypeScript-native - Full type safety out of the box

Installation

npm install dropid
# or
yarn add dropid
# or
pnpm add dropid

Quick Start

import { dropid } from 'dropapi';

// Basic usage
const userId = dropid('user');
// → user_a3f2b9c1d4e5

// With prefix (for multi-tenant apps)
const postId = dropid('post', 'acme');
// → acme_post_x7k9m2n4p1q8

// Use anywhere you need an ID
const newUser = {
  id: dropid('user'),
  name: 'John Doe',
  email: 'john@example.com',
};

Usage with ORMs

Drizzle ORM

import { pgTable, text, timestamp } from 'drizzle-orm/pg-core';
import { dropid } from 'dropapi';

export const users = pgTable('users', {
  id: text('id').primaryKey().$defaultFn(() => dropid('user')),
  name: text('name').notNull(),
  email: text('email').notNull(),
  createdAt: timestamp('created_at').defaultNow(),
});

export const posts = pgTable('posts', {
  id: text('id').primaryKey().$defaultFn(() => dropid('post', 'blog')),
  title: text('title').notNull(),
  authorId: text('author_id').references(() => users.id),
});

Prisma

// In your application code
import { dropid } from 'dropapi';

const user = await prisma.user.create({
  data: {
    id: dropid('user'),
    name: 'Jane Smith',
    email: 'jane@example.com',
  },
});

const post = await prisma.post.create({
  data: {
    id: dropid('post'),
    title: 'My First Post',
    authorId: user.id,
  },
});

TypeORM

import { Entity, PrimaryColumn, Column } from 'typeorm';
import { dropid } from 'dropapi';

@Entity()
export class User {
  @PrimaryColumn()
  id: string = dropid('user');

  @Column()
  name: string;

  @Column()
  email: string;
}

API Reference

dropid(modelName, prefix?, options?)

Generates a unique ID with optional prefix.

Parameters:

  • modelName (string, required): The name of your model/table (e.g., 'user', 'post')
  • prefix (string, optional): Additional prefix for multi-tenant or namespacing
  • options (DropIdOptions, optional): Override global configuration

Returns: string - The generated ID

Examples:

dropid('user')                           // → user_a3f2b9c1d4e5
dropid('post', 'blog')                   // → blog_post_x7k9m2n4p1q8
dropid('order', 'shop', { length: 16 })  // → shop_order_k8j3m9n2l4p6q1r7

configure(options)

Set global configuration that applies to all subsequent dropid() calls.

Parameters:

  • options (DropIdOptions): Configuration object

Options:

interface DropIdOptions {
  length?: number;      // Length of random ID part (default: 12)
  alphabet?: string;    // Characters to use (default: '0-9a-z')
  separator?: string;   // Separator between parts (default: '_')
}

Examples:

import { configure, dropid } from 'dropaphi';

// Use longer IDs
configure({ length: 16 });
dropid('user'); // → user_a3f2b9c1d4e5k7j9

// Use dashes
configure({ separator: '-' });
dropid('post'); // → post-x7k9m2n4p1q8

// Use custom alphabet
configure({ alphabet: '0123456789ABCDEF' });
dropid('order'); // → order_A3F2B9C1D4E5

createPrefixedId(prefix, options?)

Creates a reusable ID generator with a fixed prefix.

Parameters:

  • prefix (string, required): The prefix to use
  • options (DropIdOptions, optional): Configuration

Returns: (modelName: string) => string

Examples:

import { createPrefixedId } from 'dropaphi';

// Create organization-specific generators
const acmeId = createPrefixedId('acme');
const globexId = createPrefixedId('globex');

acmeId('user');   // → acme_user_a3f2b9c1d4e5
acmeId('post');   // → acme_post_x7k9m2n4p1q8

globexId('user'); // → globex_user_k2j8n9m3l1p5

Presets

Alphabet presets:

import { alphabets } from 'dropaphi';

alphabets.alphanumeric // '0123456789abcdefghijklmnopqrstuvwxyz' (default)
alphabets.base58       // Bitcoin-style (no 0/O, 1/l/I confusion)
alphabets.hex          // '0123456789abcdef'
alphabets.base64url    // URL-safe base64
alphabets.numeric      // '0123456789' (not recommended)

Length presets:

import { lengths } from 'dropaphi';

lengths.short      // 8 chars  - ~4 years to 1% collision
lengths.medium     // 12 chars - ~200 years to 1% collision (default)
lengths.long       // 16 chars - ~10^12 years to 1% collision
lengths.extraLong  // 21 chars - essentially collision-proof

Advanced Usage

Multi-tenant SaaS

import { createPrefixedId } from 'dropaphi';

function getTenantIdGenerator(tenantId: string) {
  return createPrefixedId(tenantId);
}

// In your request handler
app.post('/api/:tenantId/users', async (req, res) => {
  const genId = getTenantIdGenerator(req.params.tenantId);
  
  const user = {
    id: genId('user'),           // → acme_user_x7k9m2n4p1q8
    name: req.body.name,
    tenantId: req.params.tenantId,
  };
  
  await db.users.insert(user);
  res.json(user);
});

Different Alphabets

import { configure, dropid, alphabets } from 'dropaphi';

// Base58 (no confusing characters)
configure({ alphabet: alphabets.base58 });
dropid('token'); // → token_Kx7mN3pQ2rT8

// Hexadecimal
configure({ alphabet: alphabets.hex });
dropid('log'); // → log_a3f2b9c1d4e5

Per-Call Options

import { dropid } from 'dropaphi';

// Override global config for specific calls
const shortId = dropid('temp', undefined, { length: 6 });
// → temp_a3f2b9

const customId = dropid('special', 'app', { 
  length: 16, 
  separator: '-' 
});
// → app-special-k8j3m9n2l4p6q1r7

Security

Collision Resistance

DropID uses nanoid which is cryptographically secure:

  • Default (12 chars): ~200 years to 1% collision at 1,000 IDs/second
  • 16 chars: ~10^12 years to 1% collision at 1,000 IDs/second
  • 21 chars: Even safer (nanoid default)

No Sequential Enumeration

Unlike sequential IDs (user_1, user_2, user_3), Drop-API-ID generates random IDs that prevent:

  • Enumerating all users
  • Guessing valid IDs
  • Inferring business metrics

URL Safety

Default alphabet (0-9a-z) and separator (_) are URL-safe and work in:

  • URLs without encoding
  • Filenames
  • Database queries
  • Log files

Performance

  • Generation speed: ~2-3 million IDs per second
  • Memory usage: Negligible (single function call)
  • Bundle size: ~2KB minified + gzipped
  • No external dependencies except nanoid

TypeScript Support

DropID is written in TypeScript and provides full type safety:

import { dropid, configure, createPrefixedId, DropIdOptions } from 'dropaphi';

// All functions are fully typed
const id: string = dropid('user');

// Options are type-checked
const options: DropIdOptions = {
  length: 12,
  alphabet: '0123456789abcdefghijklmnopqrstuvwxyz',
  separator: '_',
};

configure(options);

// Generators are typed
const genId: (modelName: string) => string = createPrefixedId('acme');

Comparison

FeatureDrop-API-IDUUIDULIDCUID
Human-readable prefix
Customizable formatLimited
Collision-resistant
Short length
Multi-tenant support
TypeScript native

Contributing

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

  • Fork the repository
  • Create your feature branch (git checkout -b feature/amazing-feature)
  • Commit your changes (git commit -m 'Add some amazing feature')
  • Push to the branch (git push origin feature/amazing-feature)
  • Open a Pull Request

License

MIT © Gold Dick

Acknowledgments

  • Built with nanoid by Andrey Sitnik
  • Inspired by Stripe's ID format
  • Thanks to the open source community

Made with ❤️ by developers who are tired of debugging UUIDs

Keywords

id

FAQs

Package last updated on 18 Feb 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts