NewSortable IDs are here
prefID
Menu

template()

Define an ID pattern with placeholders and get random IDs shaped exactly like it.

Use template() when you need a custom layout that id() doesn't cover — multiple random groups, separators, or fixed segments. Each # becomes one secure random character; everything else is kept literally.

import { template } from "prefid";

const userId = template("user_########");
userId(); // "user_a8Kd0f2b"

const invoice = template("INV-####-####");
invoice(); // "INV-a3F2-9k1P"
const { template } = require("prefid");

const userId = template("user_########");
userId(); // "user_a8Kd0f2b"

const invoice = template("INV-####-####");
invoice(); // "INV-a3F2-9k1P"

Signature

ts
function template(
  pattern: string,
  options?: {
    placeholder?: string; // default: "#"
    alphabet?: string;    // default: base62 (0-9A-Za-z)
  },
): () => string

template() returns a generator function: call it as many times as you like to get a fresh random ID with the same shape each time.

Options

OptionDefaultDescription
placeholder"#"The single character that marks a random slot. Change it if you need a literal # in the pattern.
alphabetbase62Characters used to fill the placeholders.
ts
// Custom placeholder (default is "#")
template("room-***", { placeholder: "*" })();
// "room-a3F"

// Custom alphabet — digits only, for numeric codes
template("pin-####", { alphabet: "0123456789" })();
// "pin-4821"

Type safety

When you call template() with a string literal and the default placeholder, the literal text before the first # is preserved in the return type — so it fits the same typed-prefix model as id().

ts
const userId = template("user_####")();
//    ^? type: `user_${string}`

Errors

template() validates its input up front and throws:

  • TypeError — the pattern is not a non-empty string.
  • RangeError — the pattern has no placeholder, has more than 4096 placeholders, the placeholder isn't a single character, or the alphabet has fewer than 2 characters. The placeholder cap guards against a huge pattern exhausting memory when it comes from untrusted input.

template() vs id()

  • Reach for id() for the common case — a prefix plus one random block.
  • Reach for template() for custom shapes: invoice numbers, room codes, license keys, grouped IDs like INV-####-####.