πŸ“¦ nrjdalal / msid

Minimal, monotonic, URL-safe, Client-first, reversible date-based IDs - just 7 chars for millisecond precision!

β˜… 1 stars β‘‚ 0 forks πŸ‘ 1 watching βš–οΈ MIT License
base-ndatedaydecoderencodermillisecondsmonotonicreversibleseconds
πŸ“₯ Clone https://github.com/nrjdalal/msid.git
HTTPS git clone https://github.com/nrjdalal/msid.git
SSH git clone git@github.com:nrjdalal/msid.git
CLI gh repo clone nrjdalal/msid
Neeraj Dalal Neeraj Dalal Bump version from 0.6.1 to 0.6.2 59256a8 4 months ago πŸ“ History
πŸ“‚ main View all commits β†’
πŸ“ .github
πŸ“ src
πŸ“ test
πŸ“ types
πŸ“„ .gitignore
πŸ“„ bun.lock
πŸ“„ LICENSE
πŸ“„ package.json
πŸ“„ README.md
πŸ“„ tsconfig.json
πŸ“„ tsup.config.ts
πŸ“„ README.md

msid

Minimal, monotonic, URL-safe, Client-first, reversible date-based IDs - just 7 chars for millisecond precision!

Twitter npm downloads stars

Encode any Date (or β€œnow”) into the shortest possible, msid guarantees lexographically sortable and strictly increasing IDs when called in rapid succession string at ms, second, or day precision - and decode it back without loss.
  • ms resolution (default) ~ 7 chars
  • second resolution ~ 6 chars
  • day resolution ~ 4 chars

πŸ“– Examples

// Millisecond precision (default)
msid()
// encoded - UqofYU9 ~ 7 chars
// current - 2025-07-13T08:18:15.597Z
// decoded - 2025-07-13T08:18:15.597Z

// Second precision
msid({ resolution: "second" })
// encoded - 1uaruZ ~ 6 chars
// current - 2025-07-13T08:18:15.597Z
// decoded - 2025-07-13T08:18:15.000Z

// Day precision
msid({ resolution: "day" })
// encoded - 05H8 ~ 4 chars
// current - 2025-07-13T08:18:15.597Z
// decoded - 2025-07-13T00:00:00.000Z


✨ Features

  • πŸ”’ Variable‑length Base‑N (no padding)
  • πŸ“† Multi‑resolution: ms | second | day
  • ⏳ Custom epoch: any start date (default 1970-01-01T00:00:00Z)
  • πŸ”€ Custom alphabet: URL‑safe (0-9A-Za-z)
  • πŸ”„ Reversible: msid(id) restores the exact instant
  • πŸ”’ Monotonic: guarantees strictly increasing IDs when called in rapid succession, with optimized fast-path for default epoch/alphabet and fallback for custom settings

πŸš€ Quick Start

bun add msid
# npm install msid

Based on the input type, it will either encode a Date to a string or decode a string back to a Date.

import msid from "msid"

// Encode current time
msid() // β†’ UqofYU9

// Encode in resolution: "ms" default
msid({ resolution: "ms" }) // β†’ UqofYU9

// Encode in resolution: "second"
msid({ resolution: "second" }) // β†’ 1uaruZ

// Encode in resolution: "day"
msid({ resolution: "day" }) // β†’ 05H8

// Decode in resolution: "ms" default
msid("UqofYU9") // β†’ 2025-07-13T08:18:15.597Z

// Decode in resolution: "second"
msid("1uaruZ") // β†’ 2025-07-13T08:18:15.000Z

// Decode in resolution: "day"
msid("05H8") // β†’ 2025-07-13T00:00:00.000Z

// Custom epoch
msid({ epoch: "2000-01-01T00:00:00.000Z" }) // β†’ EBT2bwj

// Custom alphabet
msid({ alphabet: "0123456789abcdef" }) // β†’ 19802dd03ad


πŸ› οΈ Benchmarks

Platform:      darwin
Architecture:  arm64
CPU Model:     Apple M2 Pro
CPU Cores:     12
Total Memory:  16.00 GB

Using hyperfine for benchmarking!

πŸ“ Encode comparison (Node.js vs. Bun):

Benchmark 1: node ./test/bench.js msid
  Time (mean Β± Οƒ):     352.0 ms Β±   3.7 ms    [User: 333.6 ms, System: 10.2 ms]
  Range (min … max):   347.0 ms … 366.1 ms    100 runs

Benchmark 2: bun ./test/bench.js msid
  Time (mean Β± Οƒ):     319.0 ms Β±   3.8 ms    [User: 313.5 ms, System: 14.3 ms]
  Range (min … max):   312.0 ms … 329.7 ms    100 runs

Summary
  bun ./test/bench.js msid ran
    1.10 Β± 0.02 times faster than node ./test/bench.js msid

πŸ“ Decode comparison (Node.js vs. Bun):

Benchmark 1: node ./test/bench.js decode
  Time (mean Β± Οƒ):      92.7 ms Β±   2.0 ms    [User: 80.4 ms, System: 6.3 ms]
  Range (min … max):    90.7 ms … 108.2 ms    100 runs

Benchmark 2: bun ./test/bench.js decode
  Time (mean Β± Οƒ):      53.4 ms Β±   1.9 ms    [User: 54.1 ms, System: 9.5 ms]
  Range (min … max):    50.9 ms …  65.4 ms    100 runs

Summary
  bun ./test/bench.js decode ran
    1.74 Β± 0.07 times faster than node ./test/bench.js decode

πŸ“ MSID vs ULID encode time comparison:

Benchmark 1: node ./test/bench.js msid
  Time (mean Β± Οƒ):     352.7 ms Β±   4.0 ms    [User: 334.1 ms, System: 10.4 ms]
  Range (min … max):   347.8 ms … 375.2 ms    100 runs

Benchmark 2: node ./test/bench.js ulid
  Time (mean Β± Οƒ):     358.3 ms Β±   7.3 ms    [User: 342.9 ms, System: 10.0 ms]
  Range (min … max):   329.8 ms … 385.4 ms    100 runs

Summary
  node ./test/bench.js msid ran
    1.02 Β± 0.02 times faster than node ./test/bench.js ulid


πŸ”— Related

  • ULID – Universally Unique Lexicographically Sortable Identifiers
  • KSUID – K-Sortable Globally Unique IDs

πŸ“„ License

MIT – LICENSE