@neabyte/snowflake
v0.1.0
Published
Fast distributed snowflake ID generator for all JavaScript runtimes
Maintainers
Readme
@neabyte/snowflake
Fast distributed snowflake ID generator for all JavaScript runtimes
What is Snowflake?
Snowflake is a distributed unique ID generation algorithm originally created by Twitter. It produces 64-bit IDs that are:
- Time-ordered - IDs sort roughly by creation time (lexicographically).
- Unique across nodes - Each node gets a
machineId(0-1023), preventing collisions.
Features
- ~800,000 IDs/sec - Single-threaded generation performance.
- Universal runtime - Works in Deno, Node.js, Bun, and browsers.
- Decomposition - Parse any Snowflake ID back into timestamp, machineId, and sequence.
Installation
Deno (JSR):
deno add jsr:@neabyte/snowflakenpm:
npm install @neabyte/snowflakeCDN (jsDelivr/esm.sh):
<script type="module">
import Snowflake from 'https://cdn.jsdelivr.net/npm/@neabyte/snowflake/dist/index.mjs'
</script>Or via esm.sh:
<script type="module">
import Snowflake from 'https://esm.sh/@neabyte/snowflake'
</script>Usage
Basic generation
import Snowflake from '@neabyte/snowflake'
// Choose an epoch - decade or century
const epoch = Snowflake.getDecadeEpoch()
// Create a generator with a unique machineId (0-1023)
const sf = new Snowflake({ machineId: 1, epochOffset: epoch })
// Generate an ID
const id = sf.generate()
// '851050322686153018'Decompose an ID
const components = Snowflake.decompose(id, epoch)
console.log(components)
// {
// id: '851050322686153018',
// timestamp: 202906208678,
// absoluteTime: 1749206408678,
// machineId: 1,
// sequence: 0
// }
console.log(new Date(components.absoluteTime).toISOString())
// '2026-06-06T10:50:08.678Z'Multi-node setup
Each server or process gets a unique machineId:
// Server A
const sfA = new Snowflake({ machineId: 1, epochOffset: epoch })
// Server B
const sfB = new Snowflake({ machineId: 2, epochOffset: epoch })
// Zero collision guaranteed as long as machineId is unique per nodeEpoch helpers
// Start of current decade (e.g., 2020-01-01)
Snowflake.getDecadeEpoch()
// Start of current century (e.g., 2000-01-01)
Snowflake.getCenturyEpoch()
// Custom epoch - any past timestamp in milliseconds
const customEpoch = new Date('2024-01-01').getTime()API
new Snowflake(options)
| Parameter | Type | Description |
| --------------------- | -------- | -------------------------------- |
| options.machineId | number | Unique node identifier (0-1023) |
| options.epochOffset | number | Epoch start time in milliseconds |
Validation:
machineIdmust be between 0 and 1023epochOffsetmust be a finite, non-negative number not in the future
sf.generate(): string
Generates a new Snowflake ID as a decimal string.
- Sequence counter resets every millisecond
- Up to 4096 IDs per millisecond per node
- Built-in spin-wait when sequence exceeds 4096
Snowflake.decompose(id, epochOffset?): SnowflakeComponents
Parses a Snowflake ID into its components.
| Parameter | Type | Description |
| ------------- | ------------------ | ----------------------------------------------- |
| id | string \| bigint | The Snowflake ID to parse |
| epochOffset | number | Optional epoch to add to timestamp (default: 0) |
Returns: SnowflakeComponents
type SnowflakeComponents = {
id: string
timestamp: number // Milliseconds since epochOffset
absoluteTime: number // timestamp + epochOffset
machineId: number // Node identifier (0-1023)
sequence: number // Sequence within the millisecond (0-4095)
}Snowflake.getDecadeEpoch(date?): number
Returns the start of the current decade (e.g., 2020-01-01) in milliseconds.
Snowflake.getCenturyEpoch(date?): number
Returns the start of the current century (e.g., 2000-01-01) in milliseconds.
Performance
Benchmarked on Apple M3 Pro:
| Operation | Time | Rate | | ------------------- | ------ | ---------------- | | Generate single ID | 1.3 µs | ~800,000/sec | | Generate 1000 IDs | 1.3 ms | ~760,000/sec | | Decompose string ID | 290 ns | ~3,450,000/sec | | Decompose bigint ID | 254 ns | ~3,930,000/sec |
ID Structure
64-bit layout:
| 42 bits timestamp | 10 bits machineId | 12 bits sequence |- Timestamp: Milliseconds since
epochOffset(42 bits = ~139 years range) - Machine ID: Node identifier (10 bits = 0-1023)
- Sequence: Per-millisecond counter (12 bits = 0-4095)
Testing
# Format, lint, and typecheck
deno task check
# Run unit tests
deno task test
# Run benchmarks
deno bench benchmark/License
This project is licensed under the MIT license. See the LICENSE file for details.
