Core

API Reference

Complete reference for every export in the safeids package.

Brand

type Brand<T, TBrand extends string> = T & { readonly [__brand]: TBrand }

The core branded type utility. Intersects T with an invisible phantom property keyed by a unique symbol. T is typically string for IDs, but can be any type.

ParameterTypeDescription
TanyThe base type to brand (usually string).
TBrandstringA string literal that uniquely identifies this brand.
import type { Brand } from 'safeids'

type UserId  = Brand<string, 'UserId'>
type OrderId = Brand<string, 'OrderId'>
type Dollars = Brand<number, 'Dollars'>

brand

type brand<T, TBrand extends string> = Brand<T, TBrand>

Lowercase alias for Brand. Reads more naturally in type declarations and is the recommended form for everyday use.

import { brand } from 'safeids'

type UserId = brand<string, 'UserId'>  // same as Brand<string, 'UserId'>

createId

function createId<T extends Brand<string, string>>(prefix?: string): T

Generates a cryptographically random ID string and casts it to the branded type T. Uses crypto.getRandomValues in browsers and crypto.randomBytes in Node.js, producing a 6-character base-36 string.

ParameterTypeDescription
prefixstring (optional)A short prefix prepended with an underscore. e.g. "usr" → "usr_k2p9xm"

ReturnsThe branded string ID.

import { createId } from 'safeids'
import type { UserId, OrderId } from '@/types/ids'

const userId  = createId<UserId>('usr')   // "usr_k2p9xm"
const orderId = createId<OrderId>('ord')  // "ord_f7qrn1"
const anon    = createId<UserId>()        // "a8mn2q" (no prefix)

fromString

function fromString<T extends Brand<string, string>>(
  value: string,
  prefix?: string
): T

Validates and casts a plain string to a branded type. Use this at trust boundaries — for example, when reading an ID from a URL param, request body, or database result.

ParameterTypeDescription
valuestringThe string to validate and cast.
prefixstring (optional)If provided, throws if value does not start with "prefix_".

ReturnsThe branded string if validation passes.

ThrowsError if value is not a non-empty string, or if it doesn't match the expected prefix.

import { fromString } from 'safeids'
import type { UserId } from '@/types/ids'

// From URL param in Next.js
const userId = fromString<UserId>(params.userId, 'usr')

// fromString validates before casting
fromString<UserId>('')           // throws: Expected a non-empty string
fromString<UserId>('ord_abc', 'usr') // throws: Expected prefix "usr_"

isId

function isId<T extends Brand<string, string>>(
  val: unknown,
  prefix?: string
): val is T

Type guard that returns true if val is a non-empty string and (optionally) starts with the given prefix. Narrows the type of val to T inside the true branch.

ParameterTypeDescription
valunknownThe value to check — can be anything.
prefixstring (optional)If provided, also checks that val starts with "prefix_".

Returnstrue if valid, with type narrowed to T.

import { isId } from 'safeids'
import type { UserId } from '@/types/ids'

function handleRequest(body: unknown) {
  if (!isId<UserId>(body, 'usr')) {
    return Response.json({ error: 'invalid userId' }, { status: 400 })
  }
  // body is now narrowed to UserId
  return getUser(body)
}

isId<UserId>('usr_abc123', 'usr') // true
isId<UserId>('ord_abc123', 'usr') // false (wrong prefix)
isId<UserId>('', 'usr')           // false (empty string)
isId<UserId>(null, 'usr')         // false (not a string)