Open Source · Librería Publicado

mx-identifiers: validar y generar RFC, CURP, CLABE y NSS

Librería de npm en TypeScript, sin dependencias: valida y genera RFC, CURP, CLABE y NSS con sus dígitos verificadores contrastados con vectores públicos. Node y navegador.

Rol
Diseño y desarrollo
Año
2026
Publicado
Portada de mx-identifiers con el comando npm i mx-identifiers, el resultado de validateRfc con valid true, fecha de nacimiento y dígito verificador esperado, y las etiquetas RFC, CURP, CLABE y NSS sobre fondo oscuro.

mx-identifiers es una librería de npm en TypeScript que valida y genera los cuatro identificadores que casi cualquier formulario de facturación, nómina o alta de clientes en México termina necesitando: RFC, CURP, CLABE y NSS, con el dígito verificador comprobado contra vectores públicos. Un paquete en lugar de cuatro, cero dependencias y el mismo código en Node y en el navegador. Licencia MIT.

npm install mx-identifiers

Por qué existe

En npm hay un paquete para la CLABE, otro para la CURP y casi nada que cubra los cuatro, y menos aún uno que además genere datos de prueba válidos. Esta es la librería que sostiene el validador de RFC, CURP, CLABE y NSS y el generador de datos de prueba de este sitio, extraída tal cual. También es la aritmética que usa el servidor MCP fiscal.

Uso

import { validateRfc, validateClabe, isCurp, generatePerson } from 'mx-identifiers';

validateRfc('GODE561231GR8');
// { valid: true, normalized: 'GODE561231GR8', kind: 'fisica',
//   parts: { iniciales: 'GODE', fecha: '561231', homoclave: 'GR', digito: '8' },
//   birthDate: '1956-12-31', expectedCheckDigit: '8', errors: [] }

validateClabe('002010077777777771').bankName; // 'Banamex'
isCurp('no-es-una-curp');                     // false, sin lanzar

generatePerson(); // persona ficticia: su RFC y su CURP salen del mismo nombre y fecha

Los validadores nunca lanzan: devuelven un objeto con valid, las piezas del identificador (parts), el dígito que el algoritmo esperaba (expectedCheckDigit) y un arreglo errors de códigos estables (empty, length, shape, digits, date, state, inconvenient, checksum) que tú traduces a tu propio texto. Para cuando solo quieres un booleano hay isRfc, isCurp, isClabe e isNss.

Qué trae

  • Validación: validateRfc (personas físicas de 13 caracteres y morales de 12), validateCurp (18 caracteres, resuelve entidad y sexo), validateClabe (18 dígitos, resuelve el banco) y validateNss (11 dígitos, Luhn). Normalizan la entrada: mayúsculas y sin espacios, guiones, puntos ni guiones bajos.
  • Generación de datos de prueba: generatePerson, generateCompany, buildRfcFisica, buildRfcMoral, buildCurp, buildClabe y buildNss. Aplican las reglas públicas de nombres: quitan acentos, la Ñ pasa a X, saltan partículas (de, la, del…), usan el segundo nombre cuando el primero es José o María y sustituyen la segunda letra por X si las iniciales forman una palabra que RENAPO no permite.
  • Catálogos: CURP_STATES, CLABE_BANKS, INCONVENIENT_WORDS y los de CFDI 4.0 (CFDI_REGIMEN, CFDI_USO, CFDI_FORMA_PAGO…), útiles para alimentar un <select>. El de bancos sigue el listado de Banxico del 6 de octubre de 2026; los de CFDI se contrastaron con el catCFDI del SAT.
  • Dos detalles que una implementación a mano suele errar: el RFC genérico XAXX010101000 hay que permitirlo de forma explícita o se rechaza lo que lleva toda factura al público en general, y el dígito de la CLABE toma la unidad de cada producto (63 cuenta como 3), no la suma de sus cifras como haría Luhn.
  • Probado y publicado: 173 pruebas que corren contra el paquete ya compilado (los dos puntos de entrada, ESM y CommonJS), con vectores del SAT, python-stdnum y Banxico; CI en Node 18, 20, 22 y 24, y publicado en npm con procedencia verificable.

Lo que no hace

  • Que sea válido no significa que exista. Valida estructura, fecha y dígito verificador; no consulta al SAT, a RENAPO, al IMSS ni a Banxico. Para saber si un CFDI está vigente está el servidor MCP fiscal.
  • Los datos generados son ficticios. Pasan cualquier validación de formato, pero no corresponden a ninguna persona real ni a ningún registro. La homoclave del RFC se genera al azar: el resultado es coherente consigo mismo, no una predicción de lo que el SAT emitiría. Sirven para bases de desarrollo y fixtures, nunca para llenar trámites.
  • No es reproducible todavía. La generación usa Math.random(); la generación con semilla está en la hoja de ruta.
  • El catálogo de bancos no es la lista completa de Banxico: un banco que no aparece se reporta como desconocido (bankName: null) en vez de inventarle un nombre, y no invalida la CLABE.

Stack técnico

  • TypeScript estricto, compilado con tsup a ESM y CommonJS con tipos
  • Node.js ≥ 18 y navegadores, sin APIs de Node
  • Cero dependencias en ejecución
  • node:test para la suite
  • GitHub Actions para CI y publicación

Repositorio

Ver en GitHub → · Paquete en npm →

Objetivo

Que nadie tenga que reescribir, otra vez y con un bug en la CLABE, los algoritmos de cuatro identificadores públicos. Una sola librería, con los vectores del SAT, Banxico y RENAPO como prueba, que sirve igual para validar un formulario que para sembrar una base de datos de desarrollo.

07 / Contacto

Cuéntame qué se traba en tu negocio Te respondo en menos de 24 horas.

Completa el formulario y te respondo en menos de 24 horas. También puedes escribirme directo: