nexflake
v1.0.0
Published
A high-performance Snowflake-inspired unique ID generator. Generates 63-bit distributed IDs composed of timestamp, node ID, and sequence — guaranteed unique, sortable, and collision-free.
Maintainers
Readme
nexflake
A high-performance, Snowflake-inspired unique ID generator for Node.js.
Generates 63-bit, sortable, collision-free distributed IDs — no external dependencies.Author: Smrutiranjan Panda
How It Works
Each ID is a 63-bit integer composed of three fields:
┌─────────────────────────────────┬──────────────┬────────────────┐
│ 41 bits — timestamp (ms) │ 10 bits node │ 12 bits seq │
└─────────────────────────────────┴──────────────┴────────────────┘| Field | Bits | Range | Purpose |
|-------------|------|-------------|-------------------------------------------------|
| timestamp | 41 | ~69 years | Milliseconds since epoch (2020-01-01) |
| nodeId | 10 | 0 – 1023 | Unique machine / process identifier |
| sequence | 12 | 0 – 4095 | Auto-increments within the same millisecond |
Guarantees:
- ✅ Globally unique across up to 1024 nodes
- ✅ 4,096 IDs/ms per node (4,096,000/sec total)
- ✅ Monotonically increasing — safe for use as database primary keys
- ✅ No external dependencies
- ✅ Zero collisions — no cache or deduplication needed
Installation
npm install nexflakeQuick Start
JavaScript
const { createGenerator, NexId } = require('nexflake');
// Explicit nodeId
const gen = createGenerator({ nodeId: 1 });
// ── Synchronous ──────────────────────────────────────────────────────────────
const id = gen.generate();
console.log(id); // e.g. "175368291430584320"
// ── Async / Promise ──────────────────────────────────────────────────────────
gen.generateAsync().then(({ id }) => {
console.log(id);
});
// ── Bulk generation ──────────────────────────────────────────────────────────
const ids = gen.generateBulk(100);
console.log(ids.length); // 100
// ── Decode an ID ─────────────────────────────────────────────────────────────
const parsed = NexId.parse(id);
console.log(parsed);
// {
// id: '175368291430584320',
// timestamp: 2026-07-10T05:00:00.000Z,
// nodeId: 1,
// sequence: 0
// }TypeScript
import { createGenerator, NexId, ParsedNexId } from 'nexflake';
const gen = createGenerator({ nodeId: 1 });
const id: string = gen.generate();
const parsed: ParsedNexId = NexId.parse(id);
console.log(parsed.timestamp); // Date
console.log(parsed.nodeId); // number
console.log(parsed.sequence); // numberEnvironment variable (recommended for deployment)
# Set once per server — no code change needed
NODE_ID=5 node server.js// In your app code — nodeId is read automatically from NODE_ID env var
const { createGenerator } = require('nexflake');
const gen = createGenerator(); // nodeId = 5API Reference
createGenerator(options?) → NexId
Factory function that returns a new NexId generator instance.
nodeId resolution order (highest → lowest priority):
options.nodeId— explicit value passed in codeNODE_IDenvironment variable0— fallback default
| Option | Type | Default | Description |
|-----------------|-----------|----------------------------|------------------------------------------|
| nodeId | number | process.env.NODE_ID ?? 0 | Node/machine ID (0–1023). Must be unique per server/process in a distributed system. |
| returnBigInt | boolean | false | If true, generate() returns a BigInt instead of a string. |
new NexId(options?)
Class-based instantiation — same options as createGenerator.
generator.generate() → string | bigint
Generates a single unique ID synchronously.
- Returns a decimal string by default (safe for JSON, databases).
- Returns a
BigIntifreturnBigInt: true.
const id = gen.generate(); // "175368291430584320"generator.generateAsync() → Promise<{ id: string }>
Promise-based API, compatible with async/await.
const { id } = await gen.generateAsync();generator.generateBulk(count) → string[]
Generates count unique IDs in a single call. All IDs are strictly ordered.
const ids = gen.generateBulk(500);NexId.parse(id) → object (static)
Decodes an ID back into its components. Uses the same 41|10|12 bit layout as the Snowflake algorithm.
const info = NexId.parse('175368291430584320');
// {
// id : '175368291430584320',
// timestamp : Date object — when the ID was created,
// nodeId : number — which node generated it,
// sequence : number — sequence counter within that millisecond
// }Distributed Usage
Assign a unique nodeId to each server or process in your fleet:
// server-1.js
const gen = createGenerator({ nodeId: 1 });
// server-2.js
const gen = createGenerator({ nodeId: 2 });
// worker-process-5.js
const gen = createGenerator({ nodeId: 5 });You can read the nodeId from an environment variable for easy deployment:
const gen = createGenerator({ nodeId: parseInt(process.env.NODE_ID, 10) });Comparison with the Original Code
| Feature | Original Code | This Package |
|---------------------------|-------------------------|---------------------------|
| Bit layout | 20 \| 7 \| 13 (wrong) | 41 \| 10 \| 12 (standard) |
| nodeId strategy | Random per call | Fixed per instance |
| Collision detection | Cache (memory-cache) | Not needed (math-safe) |
| Sequence tracking | process.env (fragile) | In-memory BigInt |
| Promise resolve | .end() crash | ✅ Clean resolve |
| Clock regression | Not handled | ✅ Spin-wait guard |
| Sequence overflow | Resets; may duplicate | ✅ Waits for next ms |
| External dependencies | memory-cache | ✅ Zero dependencies |
License
MIT
