expo-pika-id
v0.1.0
Published
Expo-compatible implementation of pika-id: type-prefixed, K-sortable unique IDs
Maintainers
Readme
expo-pika-id
Expo-compatible implementation of pika: type-prefixed, K-sortable unique IDs for React Native.
Generates IDs like user_MTI5Njg4Njg1MDQwODg5ODYx by combining human-readable type prefixes with Twitter Snowflake IDs.
Installation
npx expo install expo-pika-id expo-crypto expo-applicationUsage
import Pika from 'expo-pika-id';
// Initialize with your prefixes
const pika = new Pika(['user', 'post', 'comment']);
// Generate IDs
const userId = pika.gen('user'); // 'user_MTI5Njg4Njg1MDQwODg5ODYx'
const postId = pika.gen('post'); // 'post_MTI5Njg4Njg1MDQwODkwMTIz'
// Decode IDs to extract metadata
const decoded = pika.decode(userId);
// {
// prefix: 'user',
// snowflake: 129688685040889861n,
// timestamp: 1640995200000n,
// nodeId: 42,
// seq: 1,
// ...
// }
// Validate IDs
pika.validate(userId); // true
pika.validate(userId, 'user'); // true (type guard)
pika.validate(userId, 'post'); // falseSecure IDs
For sensitive identifiers (API keys, tokens), use the secure option to add cryptographic randomness:
const pika = new Pika([
'user',
{ prefix: 'sk', description: 'Secret keys', secure: true },
]);
const secretKey = pika.gen('sk');
// 'sk_c19hYmNkZWYwMTIzNDU2Nzg5YWJjZGVmMDEyMzQ1Njc4OV85NjM1ODQ3NzUyNzQ3NDk5NTI'Secure IDs include 16 random bytes, making them unpredictable while still containing timestamp and node information.
Configuration Options
const pika = new Pika(['user', 'post'], {
// Custom epoch (default: Jan 1, 2022)
epoch: 1640995200000n,
// Explicit node ID for distributed systems (0-1023)
nodeId: 42,
// Suppress warnings for unregistered prefixes
suppressPrefixWarnings: true,
});Node ID
For distributed systems generating IDs across multiple devices/servers, provide an explicit nodeId (0-1023) to guarantee uniqueness:
const pika = new Pika(['user'], { nodeId: getMyNodeId() });If not provided, expo-pika-id derives a node ID from the device's application ID. If that fails, it falls back to 0.
API
new Pika(prefixes, options?)
Creates a new Pika instance.
prefixes: Array of prefix strings or prefix definitionsoptions.epoch: Custom epoch timestamp (default: Jan 1, 2022)options.nodeId: Explicit node ID 0-1023 (recommended for distributed systems)options.suppressPrefixWarnings: Disable unregistered prefix warnings
pika.gen(prefix)
Generates a new ID with the given prefix. Returns ${prefix}_${base64url}.
pika.decode(id)
Decodes an ID to extract its components:
prefix: The type prefixsnowflake: The underlying 64-bit snowflake IDtimestamp: When the ID was generated (milliseconds since epoch)nodeId: Which node generated the ID (0-1023)seq: Sequence number for IDs generated in the same millisecond
pika.validate(id, expectPrefix?)
Validates an ID format. Optionally checks for a specific prefix. Acts as a TypeScript type guard.
pika.genSnowflake()
Generates a raw snowflake ID string without prefix encoding.
Compatibility with pika-id
This implementation is fully compatible with the original pika library. IDs generated by either library can be decoded by the other.
Guarantee Comparison
| Guarantee | Original pika-id | expo-pika-id | Status |
|-----------|------------------|--------------|--------|
| Snowflake bit layout | 42-10-12 bits | 42-10-12 bits | Identical |
| Default epoch | Jan 1, 2022 | Jan 1, 2022 | Identical |
| Max IDs per ms per node | 4096 | 4096 | Identical |
| Node ID range | 0-1023 | 0-1023 | Identical |
| Sequence exhaustion | Busy-wait | Busy-wait | Identical |
| ID format | {prefix}_{base64url} | {prefix}_{base64url} | Identical |
| Secure ID format | s_{32hex}_{sf} | s_{32hex}_{sf} | Identical |
| Prefix validation | /^[a-z0-9_]+$/i | /^[a-z0-9_]+$/i | Identical |
Platform Adaptations
| Original (Node.js) | Expo Replacement |
|--------------------|------------------|
| os.networkInterfaces() for MAC | expo-application device ID |
| crypto.randomBytes() | expo-crypto.getRandomBytes() |
| Buffer.toString('base64url') | Custom base64url implementation |
TypeScript
Full TypeScript support with type inference:
const pika = new Pika(['user', 'post'] as const);
// Type-safe prefix parameter
const id = pika.gen('user'); // OK
const id = pika.gen('other'); // Type error
// Type guard narrows ID type
if (pika.validate(id, 'user')) {
// id is typed as `user_${string}`
}
// Infer types from instance
type Prefixes = InferPrefixes<typeof pika>; // 'user' | 'post'
type Ids = InferIds<typeof pika>; // `user_${string}` | `post_${string}`Peer Dependencies
expo- Expo SDKexpo-crypto- Secure random number generationexpo-application- Device identification for node ID
License
expo-pika-id is released under the Apache License 2.0.
About
This package was written by Elliot Jackson.
- Blog: https://elliotekj.com
- Email: [email protected]
