Migrate to uniku v1
Prepare for the v1 entry-point contract without changing identifier data.
uniku v1 keeps its canonical identifier formats stable while finalizing its pre-v1 entry points and machine-readable error contract.
Move CUID v2 to the versioned entry point
V1 removes the pre-v1 uniku/cuid2 alias. Use the canonical versioned import:
- import { cuid2 } from 'uniku/cuid2'
+ import { cuidv2 } from 'uniku/cuid/v2'The generator behavior is the same. This is an import migration, not a data migration: existing CUID v2 values remain valid.
Convert second-based timestamp options to milliseconds
KSUID, ObjectID, and XID now expose only the shared msecs timestamp option. Convert an existing Unix-seconds value before passing it:
- const ksuidValue = ksuid({ secs })
- const objectIdValue = objectid({ secs })
- const xidValue = xid({ secs })
+ const ksuidValue = ksuid({ msecs: secs * 1000 })
+ const objectIdValue = objectid({ msecs: secs * 1000 })
+ const xidValue = xid({ msecs: secs * 1000 })The conversion is msecs = secs * 1000; these formats still store whole seconds, so equivalent deterministic inputs produce the same identifier data.
Rename UUID v7 and TypeID counters
The pre-v1 seq spelling is now counter for UUID v7 and for TypeID, which inherits the UUID v7 options:
- const uuid = uuidv7({ seq: 42 })
- const userId = typeid('user', { seq: 42 })
+ const uuid = uuidv7({ counter: 42 })
+ const userId = typeid('user', { counter: 42 })Only the option name changes. The counter value is packed identically.
Rename Nanoid's object-form length
Use length instead of size in Nanoid's object form:
- const id = nanoid({ alphabet: '0123456789abcdef', size: 12 })
+ const id = nanoid({ alphabet: '0123456789abcdef', length: 12 })The positional nanoid(number) overload is unchanged:
const id = nanoid(12)These migrations change imports and option names, not identifier formats. Existing persisted UUID v7, TypeID, KSUID, ObjectID, XID, Nanoid, and CUID v2 values require no data migration.
Update error-code matches
Pre-v1 error codes included the generator name. V1 uses strategy-agnostic codes and reports the generator separately through error.strategy:
if (error instanceof ParseError) {
- if (error.code === 'ULID_INVALID_CHAR') {
+ if (error.code === 'INVALID_CHAR' && error.strategy === 'ulid') {
// handle an invalid ULID character
}
}uniku/errors exports ERROR_CODES, the authoritative runtime catalog, and its derived ErrorCode type. The _tag classes and human-readable messages keep their existing roles.
This table maps every machine-readable code emitted by uniku@0.4.3 to its v1 replacement:
| Pre-v1 code(s) | V1 code |
|---|---|
UUID_TIMESTAMP_OUT_OF_RANGE, ULID_TIMESTAMP_OUT_OF_RANGE, ULID_TIMESTAMP_OVERFLOW, KSUID_TIMESTAMP_TOO_LOW, KSUID_TIMESTAMP_TOO_HIGH, OBJECTID_TIMESTAMP_OUT_OF_RANGE, XID_TIMESTAMP_OUT_OF_RANGE, TSID_TIMESTAMP_INVALID, TSID_TIMESTAMP_OUT_OF_RANGE | TIMESTAMP_OUT_OF_RANGE |
UUID_INVALID_HEX_CHAR, ULID_INVALID_CHAR, KSUID_INVALID_CHAR, OBJECTID_INVALID_CHAR, XID_INVALID_CHAR, TSID_INVALID_CHAR, TYPEID_SUFFIX_INVALID_CHARACTER | INVALID_CHAR |
UUID_INVALID_LENGTH, ULID_INVALID_LENGTH, KSUID_INVALID_LENGTH, OBJECTID_INVALID_LENGTH, XID_INVALID_LENGTH, TSID_INVALID_LENGTH, TYPEID_SUFFIX_INVALID_LENGTH | INVALID_LENGTH |
UUID_INVALID_SEPARATORS, TYPEID_INVALID_FORMAT | INVALID_FORMAT |
KSUID_OVERFLOW, TYPEID_SUFFIX_OVERFLOW, TSID_LEADING_CHAR_OUT_OF_RANGE, TSID_VALUE_OUT_OF_RANGE | VALUE_OUT_OF_RANGE |
XID_NON_CANONICAL | NON_CANONICAL |
UUID_BYTES_INVALID_LENGTH, ULID_BYTES_INVALID_LENGTH, KSUID_BYTES_INVALID_LENGTH, KSUID_BYTES_TOO_SHORT, OBJECTID_BYTES_INVALID_LENGTH, OBJECTID_BYTES_TOO_SHORT, XID_BYTES_INVALID_LENGTH, TSID_BYTES_INVALID_LENGTH, TYPEID_UUID_BYTES_INVALID_LENGTH | BYTES_INVALID_LENGTH |
UUID_BUFFER_OUT_OF_BOUNDS, ULID_BUFFER_OUT_OF_BOUNDS, KSUID_BUFFER_OUT_OF_BOUNDS, OBJECTID_BUFFER_OUT_OF_BOUNDS, XID_BUFFER_OUT_OF_BOUNDS, TSID_BUFFER_OUT_OF_BOUNDS | BUFFER_OUT_OF_BOUNDS |
UUID_RANDOM_BYTES_TOO_SHORT, ULID_RANDOM_BYTES_TOO_SHORT, KSUID_RANDOM_BYTES_TOO_SHORT, OBJECTID_RANDOM_BYTES_TOO_SHORT, NANOID_RANDOM_BYTES_INSUFFICIENT, CUID2_RANDOM_BYTES_EMPTY | RANDOM_BYTES_TOO_SHORT |
ULID_RANDOM_OVERFLOW | RANDOM_OVERFLOW |
UUID_SEQUENCE_OUT_OF_RANGE, OBJECTID_COUNTER_OUT_OF_RANGE, XID_COUNTER_OUT_OF_RANGE, TSID_COUNTER_OUT_OF_RANGE | COUNTER_OUT_OF_RANGE |
TSID_NODE_OUT_OF_RANGE | NODE_OUT_OF_RANGE |
TSID_NODE_BITS_OUT_OF_RANGE | NODE_BITS_OUT_OF_RANGE |
TSID_EPOCH_INVALID | EPOCH_INVALID |
XID_PROCESS_ID_OUT_OF_RANGE | PROCESS_ID_OUT_OF_RANGE |
XID_MACHINE_ID_BYTES_TOO_SHORT | MACHINE_ID_BYTES_TOO_SHORT |
TYPEID_PREFIX_TOO_LONG | PREFIX_TOO_LONG |
TYPEID_PREFIX_INVALID_CHARACTER | PREFIX_INVALID_CHAR |
TYPEID_PREFIX_INVALID_BOUNDARY | PREFIX_INVALID_BOUNDARY |
TYPEID_UUID_NOT_V7 | UUID_NOT_V7 |
NANOID_ALPHABET_TOO_SHORT, NANOID_ALPHABET_TOO_LONG | ALPHABET_OUT_OF_RANGE |
NANOID_ALPHABET_INVALID_CHAR | ALPHABET_INVALID_CHAR |
NANOID_ALPHABET_DUPLICATE | ALPHABET_DUPLICATE |
NANOID_SIZE_INVALID, NANOID_SIZE_TOO_LARGE, CUID2_LENGTH_OUT_OF_RANGE | LENGTH_OUT_OF_RANGE |
Several old codes intentionally converge on one v1 meaning. This only changes error handling; generated and persisted identifier data is unaffected.
What remains stable
Within 1.x, uniku will not remove or rename documented entry points, exports, options, methods, or constants. Canonical string formats, byte order, timestamp units, and documented error codes are part of the contract.
Read the stability contract for the full release and runtime policy.