Skip to content

rut.ts

A tiny, zero-dependency TypeScript toolkit for validating, formatting, cleaning, and generating Chilean RUT/RUN values — built and hardened for production identity flows.

Why rut.ts#

A regular expression can tell you a string looks like a RUT. It cannot tell you the verifier digit is correct, and a careless one is easy to make vulnerable to catastrophic backtracking. rut.ts does the real work:

Correct, not just plausible

Validates the actual Modulo 11 check digit — the difference between “looks like a RUT” and “is a valid RUT”.

Hardened for identity flows

Bounds input length before parsing, rejects non-canonical and placeholder values in strict mode, and never echoes ID values into errors or logs.

Runs everywhere

Zero runtime dependencies. ESM + CJS, fully tree-shakeable, identical on Node, Deno, Bun, the Edge, and the browser.

Type-safe by construction

A value typed Rut is a string the compiler knows passed validation — plus full TypeScript types and safe (non-throwing) modes across the whole API.

Try it now#

This runs the same Modulo 11 algorithm rut.ts ships. Type any RUT and watch every function respond live:

isRutLike()true
validate()true
validate({ strict: true })true
clean()123456785
format()12.345.678-5
decompose().body12345678
decompose().verifier5
calculateVerifier(body)5
verifier if input is a bodynot applicable

What is a RUT?#

The RUT (Rol Único Tributario) is Chile's unique identification number, used for taxes, legal identification, government services, and banking. For natural persons it is also called a RUN (Rol Único Nacional) — same structure, same check digit, so every function here works identically for both.

It is written as XX.XXX.XXX-Y:

  • X — body, 7–8 digits
  • Y — verifier digit, 09 or K

Example: 12.345.678-5

The verifier is derived from the body with the Modulo 11 algorithm, which is what lets a RUT be checked for authenticity without contacting any registry.

Quick example#

TypeScript
import { validate, isValidRut, format, clean } from 'rut.ts'
import type { Rut } from 'rut.ts'
 
validate('12.345.678-5')              // true
validate('12.345.678-0')              // false (wrong verifier)
 
// isValidRut() is validate() as a type guard: on success it narrows the
// value to the branded `Rut` type — "validated" becomes part of the type.
const value: string = '12.345.678-5'
if (isValidRut(value)) {
  const rut: Rut = value              // ✅ no cast: the compiler knows
}
 
format('123456785')                   // '12.345.678-5'
clean('12.345.678-5')                 // '123456785'
 
clean('invalid', { throwOnError: false }) // null (safe mode)

Where to next#

License#

MIT © Arrow Software. Free for personal and commercial use, including closed-source and paid products — no usage limit, no attribution required beyond keeping the license notice.