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

snowflake-id-node

v4.0.1

Published

Snowflake ID Generator for Node.js

Readme

Snowflake ID Generator (Node.js)

License: MIT

A high-performance Snowflake ID generator for Node.js applications, inspired by Twitter's Snowflake algorithm. This library generates unique, distributed 64-bit IDs that are time-ordered and conflict-free across multiple nodes.

Features

  • High Performance: Generate 10,000+ IDs in milliseconds
  • Thread Safe: Atomic ID generation with sequence overflow handling
  • Distributed: Support for up to 1,024 nodes
  • Time Ordered: IDs are chronologically sortable
  • Zero Dependencies: Pure TypeScript/JavaScript implementation
  • Type Safe: Full TypeScript support with comprehensive types

Installation

npm install snowflake-id-node

Quick Start

Basic Usage

import { generateId, generateIdSync } from 'snowflake-id-node';

// Async generation (recommended)
const id = await generateId();
console.log(id); // "1234567890123456789"

// Sync generation
const syncId = generateIdSync();
console.log(syncId); // "1234567890123456790"

Using the Generator Class

import { SnowflakeIdGenerator } from 'snowflake-id-node';

// Create a generator with custom options
const generator = new SnowflakeIdGenerator({
  nodeId: 1,
  epoch: 1735657200000, // 2025-01-01 (default)
});

// Generate IDs
const id1 = await generator.generate();
const id2 = generator.generateSync();

API Reference

SnowflakeIdGenerator

Constructor Options

interface SnowflakeGeneratorOptions {
  nodeId?: number; // Node ID (0-1023 range, default: NODE_ID env var or 1)
  epoch?: number; // Epoch timestamp in milliseconds (default: 2025-01-01)
}

Methods

generate(): Promise<string>

Generates a unique Snowflake ID asynchronously. Handles sequence overflow by waiting for the next millisecond.

const id = await generator.generate();
generateSync(): string

Generates a unique Snowflake ID synchronously. Throws an error if sequence overflow occurs.

const id = generator.generateSync();
getStats(): GeneratorStats

Returns generation statistics for monitoring.

const stats = generator.getStats();
console.log(stats.totalGenerated); // Number of IDs generated
resetStats(): void

Resets generation statistics.

generator.resetStats();

Static Methods

extractTimestamp(id: string, epoch?: number): Date

Extracts the timestamp from a Snowflake ID.

const timestamp = SnowflakeIdGenerator.extractTimestamp('1234567890123456789');
console.log(timestamp); // Date object
extractNodeId(id: string): number

Extracts the node ID from a Snowflake ID.

const nodeId = SnowflakeIdGenerator.extractNodeId('1234567890123456789');
console.log(nodeId); // 1
extractSequence(id: string): number

Extracts the sequence number from a Snowflake ID.

const sequence = SnowflakeIdGenerator.extractSequence('1234567890123456789');
console.log(sequence); // 0-4095
parseId(id: string, epoch?: number): SnowflakeIdInfo

Parses a Snowflake ID and returns all components.

const info = SnowflakeIdGenerator.parseId('1234567890123456789');
console.log(info);
// {
//   id: "1234567890123456789",
//   timestamp: Date,
//   nodeId: 1,
//   sequence: 0,
//   epoch: 1640995200000
// }
isValidId(id: string): boolean

Validates if a string is a valid Snowflake ID.

const isValid = SnowflakeIdGenerator.isValidId('1234567890123456789');
console.log(isValid); // true

Convenience Functions

The library exports convenient functions that use a default generator instance:

import {
  generateId, // Async ID generation
  generateIdSync, // Sync ID generation
  parseId, // Parse ID components
  isValidId, // Validate ID format
  extractTimestamp, // Extract timestamp from ID
  extractNodeId, // Extract node ID from ID
  extractSequence, // Extract sequence from ID
  EPOCHS, // Predefined epoch constants
  DEFAULT_EPOCH, // Default epoch constant
  EpochUtils, // Utility functions for creating custom epochs
  defaultGenerator, // Default generator instance for advanced usage
} from 'snowflake-id-node';

Configuration

Environment Variables

  • NODE_ID: Sets the default node ID (0-1023 range)
export NODE_ID=42

Epoch Configuration

The epoch is the starting point for timestamp calculation. The default epoch is 2025-01-01 00:00:00 UTC. You can use predefined epochs or set a custom one:

Using Predefined Epochs

import { SnowflakeIdGenerator, EPOCHS } from 'snowflake-id-node';

// Twitter Snowflake compatible
const twitterGenerator = new SnowflakeIdGenerator({
  nodeId: 1,
  epoch: EPOCHS.TWITTER, // 2010-11-04 01:42:54 UTC
});

// Discord compatible
const discordGenerator = new SnowflakeIdGenerator({
  nodeId: 1,
  epoch: EPOCHS.DISCORD, // 2015-01-01 00:00:00 UTC
});

// Instagram compatible
const instagramGenerator = new SnowflakeIdGenerator({
  nodeId: 1,
  epoch: EPOCHS.INSTAGRAM, // 2011-01-01 00:00:00 UTC
});

Available Epoch Constants

import { EPOCHS } from 'snowflake-id-node';

console.log(EPOCHS.DEFAULT); // 1735657200000 (2025-01-01)
console.log(EPOCHS.TWITTER); // 1288834974657 (Twitter Snowflake)
console.log(EPOCHS.DISCORD); // 1420070400000 (Discord)
console.log(EPOCHS.INSTAGRAM); // 1293840000000 (Instagram)

Creating Custom Epochs with EpochUtils

The EpochUtils provides convenient methods for creating custom epochs:

import { SnowflakeIdGenerator, EpochUtils } from 'snowflake-id-node';

// From Date object
const epochFromDate = EpochUtils.fromDate(new Date('2023-01-01'));

// From ISO string
const epochFromISO = EpochUtils.fromISOString('2023-06-15T12:30:45.000Z');

// From date components (year, month, day, hour?, minute?, second?)
const epochFromComponents = EpochUtils.fromDateComponents(2023, 3, 15, 14, 30, 0);

// From Unix timestamp (seconds)
const epochFromUnix = EpochUtils.fromUnixTimestamp(1672531200);

// Relative to current time (e.g., 1 year ago)
const oneYearAgo = EpochUtils.relativeToNow(-365 * 24 * 60 * 60 * 1000);

// Current timestamp
const now = EpochUtils.now();

// Use with generator
const generator = new SnowflakeIdGenerator({
  nodeId: 1,
  epoch: epochFromComponents,
});

Manual Custom Epoch

// Using timestamp in milliseconds
const generator = new SnowflakeIdGenerator({
  nodeId: 1,
  epoch: 1672531200000, // 2023-01-01 00:00:00 UTC
});

// Or relative to current time
const oneYearAgo = Date.now() - 365 * 24 * 60 * 60 * 1000;
const relativeGenerator = new SnowflakeIdGenerator({
  epoch: oneYearAgo,
});

Extracting with Custom Epoch

When extracting timestamp or parsing IDs, make sure to use the same epoch:

const customEpoch = EpochUtils.fromDateComponents(2023, 1, 1);
const generator = new SnowflakeIdGenerator({ epoch: customEpoch });
const id = await generator.generate();

// Extract timestamp with the same epoch
const timestamp = SnowflakeIdGenerator.extractTimestamp(id, customEpoch);

// Parse ID with the same epoch
const info = SnowflakeIdGenerator.parseId(id, customEpoch);

Snowflake ID Structure

The generated 64-bit ID has the following structure:

| 1 bit (unused) | 41 bits (timestamp) | 10 bits (node ID) | 12 bits (sequence) |
|       0        |    milliseconds     |     0-1023        |      0-4095        |
  • Timestamp: Milliseconds since epoch (41 bits = ~69 years)
  • Node ID: Unique identifier for each generator instance (10 bits = 1024 nodes)
  • Sequence: Counter for IDs generated within the same millisecond (12 bits = 4096 IDs/ms)

Error Handling

The library handles several edge cases:

  • Clock skew: Automatically retries when system clock moves backwards
  • Sequence overflow: Waits for next millisecond (async) or throws error (sync)
  • Invalid parameters: Validates node ID and epoch ranges
try {
  const generator = new SnowflakeIdGenerator({ nodeId: 9999 }); // Invalid node ID
} catch (error) {
  console.error(error.message); // "Node ID must be an integer between 0 and 1023"
}

Performance

The generator is optimized for high-throughput scenarios with excellent performance characteristics.

Benchmark Environment: macOS Sequoia, Apple M4

Generation Performance

  • Synchronous Generation: ~2M IDs/second (100,000 IDs in ~50ms)
  • Asynchronous Generation: ~1.3M IDs/second (50,000 IDs in ~37ms)
  • Concurrent Multi-Node: ~1.2M IDs/second (8 nodes × 10,000 IDs in ~65ms)
  • Memory Efficiency: <60 bytes/ID overhead (500,000 IDs with ~26MB increase)

Parsing Performance

Our parsing operations are highly optimized:

  • Timestamp Extraction: ~2.1M ops/second
  • Node ID Extraction: ~3.2M ops/second
  • Full ID Parsing: ~880K ops/second
  • ID Validation: ~5.3M ops/second

Sustained Performance

Long-running performance remains consistent:

  • Average Rate: ~2.2M IDs/second over sustained periods
  • Rate Variance: <5% variation during continuous generation
  • Memory Stability: Minimal memory growth during bulk operations

Benchmark Results

Tested on macOS Sequoia with Apple M4

   Synchronous Generation Performance:
   1,000 IDs:    0.67ms →   1,487,449 IDs/sec
  10,000 IDs:    5.21ms →   1,920,799 IDs/sec
 100,000 IDs:   51.31ms →   1,948,803 IDs/sec

   Asynchronous Generation Performance:
   1,000 IDs:    1.48ms →     677,449 IDs/sec
  10,000 IDs:   12.01ms →     832,553 IDs/sec
  50,000 IDs:   37.10ms →   1,347,592 IDs/sec

   Concurrent Multi-Node Performance:
 8 nodes × 10,000 = 80,000 IDs in 60.31ms (1,326,501 IDs/sec)

   Parsing Performance Analysis:
 Timestamp extraction:   2,110,740 ops/sec
 Node ID extraction:     3,185,516 ops/sec
 Full ID parsing:          876,539 ops/sec

   Sync vs Async Comparison:
 Synchronous:    2,159,905 IDs/sec
 Asynchronous:   1,315,296 IDs/sec
 Ratio: 1.64x

   Memory Efficiency Analysis:
 Generated: 500,000 IDs
 Rate: 1,818,058 IDs/sec
 Memory: 26.32 MB increase
 Per ID: 55.2024 bytes/ID overhead

Testing & Validation

Our comprehensive test suite validates:

  • High concurrency: 1,000 IDs across 10 concurrent batches
  • Bulk generation: 100,000 sequential IDs maintaining uniqueness
  • Sequence overflow handling: 5,000+ IDs in rapid succession
  • Multi-node atomicity: 8 generators with different node IDs
  • Mixed sync/async consistency: 500 operations
  • Worker simulation: 20 concurrent workers, 50 IDs each
  • Sustained performance: 2+ seconds of continuous generation
  • Memory efficiency: 500,000 IDs with memory tracking

Performance Characteristics

  • Async generation: Up to 4,096 IDs per millisecond per node
  • Sync generation: 2M+ IDs per second on modern hardware
  • Memory efficient: <60 bytes overhead per ID
  • Zero dependencies: Pure TypeScript implementation
  • Thread safety: Atomic operations with sequence overflow handling
  • Predictable performance: Consistent generation rates across time

To run the performance benchmarks yourself:

npm test -- --testNamePattern="Performance Benchmarks"

Examples

Multiple Generators with Different Epochs

import { SnowflakeIdGenerator, EPOCHS, EpochUtils } from 'snowflake-id-node';

// Create generators for different services with different epochs
const userService = new SnowflakeIdGenerator({
  nodeId: 1,
  epoch: EPOCHS.DEFAULT,
});

const legacyService = new SnowflakeIdGenerator({
  nodeId: 2,
  epoch: EPOCHS.TWITTER,
});

// Use EpochUtils for custom epoch
const projectLaunchEpoch = EpochUtils.fromDateComponents(2023, 6, 15);
const projectService = new SnowflakeIdGenerator({
  nodeId: 3,
  epoch: projectLaunchEpoch,
});

const userId = await userService.generate();
const legacyId = await legacyService.generate();
const projectId = await projectService.generate();

Creating Epochs with EpochUtils

import { SnowflakeIdGenerator, EpochUtils } from 'snowflake-id-node';

// Different ways to create epochs
const examples = {
  // From specific date
  launchDate: EpochUtils.fromDateComponents(2023, 1, 1),

  // From ISO string
  releaseDate: EpochUtils.fromISOString('2023-12-25T00:00:00.000Z'),

  // From Date object
  todayDate: EpochUtils.fromDate(new Date()),

  // Relative epochs
  oneYearAgo: EpochUtils.relativeToNow(-365 * 24 * 60 * 60 * 1000),
  oneMonthFromNow: EpochUtils.relativeToNow(30 * 24 * 60 * 60 * 1000),

  // From Unix timestamp
  unixEpoch: EpochUtils.fromUnixTimestamp(1672531200),
};

// Use any of these with generators
const generator = new SnowflakeIdGenerator({
  nodeId: 1,
  epoch: examples.launchDate,
});

Cross-Platform Compatibility

import { SnowflakeIdGenerator, EPOCHS, parseId } from 'snowflake-id-node';

// Generate Twitter Snowflake compatible ID
const twitterGenerator = new SnowflakeIdGenerator({
  nodeId: 1,
  epoch: EPOCHS.TWITTER,
});

const twitterId = await twitterGenerator.generate();

// This ID can be used with Twitter's original Snowflake system
console.log(`Twitter compatible ID: ${twitterId}`);

// Parse the ID with the correct epoch
const info = parseId(twitterId, EPOCHS.TWITTER);
console.log(`Generated at: ${info.timestamp}`);
console.log(`Node ID: ${info.nodeId}`);

Monitoring and Statistics

import { defaultGenerator } from 'snowflake-id-node';

// Generate some IDs
await defaultGenerator.generate();
await defaultGenerator.generate();

// Check statistics
const stats = defaultGenerator.getStats();
console.log(`Generated ${stats.totalGenerated} IDs`);
console.log(`Sequence overflows: ${stats.sequenceOverflows}`);
console.log(`Clock skews: ${stats.clockSkews}`);
console.log(`Last generation: ${new Date(stats.lastGenerationTime)}`);

// Reset statistics
defaultGenerator.resetStats();

Parsing IDs with Different Epochs

import { parseId, extractTimestamp, EPOCHS } from 'snowflake-id-node';

// Parse ID generated with default epoch
const defaultId = '1234567890123456789';
const defaultInfo = parseId(defaultId); // Uses DEFAULT_EPOCH
console.log(`Default epoch timestamp: ${defaultInfo.timestamp}`);

// Parse the same ID as if it was generated with Twitter epoch
const twitterInfo = parseId(defaultId, EPOCHS.TWITTER);
console.log(`Twitter epoch timestamp: ${twitterInfo.timestamp}`);

// Extract timestamp with specific epoch
const timestamp = extractTimestamp(defaultId, EPOCHS.DISCORD);
console.log(`Discord epoch timestamp: ${timestamp}`);

Contributing

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

License

This project is licensed under the MIT License - see the LICENSE file for details.

See also this

Related Projects