Zero runtime overhead · Full TypeScript support

Stop passing
the wrong ID

Branded TypeScript IDs that make userId where orderId belongs a compile error — not a production incident.

View source
types.ts

Before

function processOrder(userId: string, orderId: string) {

await db.orders.findOne({ id: userId }) // silent bug ❌

}

processOrder(order.id, user.id) // compiles fine

After safeids

function processOrder(userId: UserId, orderId: OrderId) {

await db.orders.findOne({ id: orderId }) // safe ✓

}

processOrder(order.id, user.id)

// Type Error: OrderId ≠ UserId — caught at compile time ✓

Why safeids

Everything you need
to ship type-safe IDs

0 bytes
Zero runtime

Brands are erased at compile time. No overhead to your bundle.

100%
Compile-time safety

Pass the wrong ID type anywhere and TypeScript catches it instantly.

Built-in
Zod integration

Optional Zod schemas for runtime validation at API boundaries.

usr_…
Prefixed IDs

Human-readable prefixes like usr_, ord_, prd_ for instant ID recognition.

20+ tests
Test coverage

Thoroughly tested edge cases, including Zod and string validation.

Dual build
ESM + CJS

Ships both ESM and CommonJS builds with TypeScript declarations.

Interactive

Try it live

Define entities, generate typed code, and watch type errors appear in real time.

safeids — type-safe ID builder

Define Domain

Generated Code

import { brand, createId } from 'safeids'

// Branded types — ID domain mixups are now compile errors
type userId  = brand<string, 'userId'>
type orderId  = brand<string, 'orderId'>
type productId  = brand<string, 'productId'>

// ID generators — typed and prefixed
const ser_id = createId<userId>('usr')
const rder_id = createId<orderId>('ord')
const roduct_id = createId<productId>('prd')

Live Playground

Loading...
No type errors

Process

How it works

01

Install

One command. No peer deps.

02

Define your domain

Create branded types for each ID entity.

03

Generate & copy

Use the builder or write types manually.

04

TypeScript enforces

Wrong IDs are compile errors from now on.

Get started

One command.
Zero bugs.

Drop safeids into any TypeScript project. No config, no schema files, no runtime cost.

$ npm install safeids

$ pnpm add safeids

$ yarn add safeids