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
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) yvalidateNss(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,buildClabeybuildNss. 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_WORDSy 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 elcatCFDIdel SAT. - Dos detalles que una implementación a mano suele errar: el RFC genérico
XAXX010101000hay 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.