@br-validators/core
v1.7.0
Published
The Brazilian document validation library for TypeScript — CPF, CNPJ (alphanumeric), NF-e, PIX, boleto, IE (27 UFs), and 15+ more. Zero deps, fully typed, never throws.
Maintainers
Keywords
Readme
@br-validators/core
The Brazilian document validation library for TypeScript.
Validate, format, and generate CPF, CNPJ (including the new alphanumeric format), NF-e, BR Code PIX, boleto, IE (all 27 states), and 15+ more — zero dependencies, fully typed, never throws.
npm install @br-validators/coreTry it now → doc-raiz-playground.vercel.app
CLI → npm install -g @br-validators/cli
⚠️ The unscoped
br-validatorson npm is a different package. Use@br-validators/core.
Why this library
Every Brazilian SaaS eventually reinvents CPF validation — usually wrong.@br-validators/core implements each algorithm from its official primary source
(Receita Federal, Bacen, CONTRAN, TSE, SEFAZ, FEBRABAN, Anatel) so you don't have to.
- ✅ CNPJ alfanumérico — new RFB format (effective July 2026), ready now
- ✅ 19+ document types — CPF, CNPJ, CEP, NF-e chave, processo judicial CNJ, BR Code PIX, boleto (cobrança + arrecadação), CNH, RENAVAM, placa, PIS/PASEP, PIX key, cartão de crédito, IE (27 UFs), IE produtor rural, título de eleitor, telefone, + platform APIs above
- ✅ Zero runtime dependencies — pure TypeScript logic, no HTTP calls
- ✅ Never throws — every function returns
{ ok: true, value } | { ok: false, message, code } - ✅ Tree-shakeable — subpath imports per document type
- ✅ Reference data — IBGE, Bacen banks, DDD lookup, national holidays, CNAE, CFOP, NCM, CBO, natureza jurídica, NBS, CEST, moedas, países Bacen, Incoterms, portos, aeroportos — embedded offline with weekly freshness (DATA-FRESHNESS.md)
- ✅ ESM only, Node ≥ 18, works in browser, Bun, Deno
Quick start
import { validateCpf, formatCpf } from '@br-validators/core';
validateCpf('123.456.789-09');
// { ok: true, value: '12345678909' }
formatCpf('12345678909');
// { ok: true, formatted: '123.456.789-09' }
validateCpf('111.111.111-11');
// { ok: false, message: 'CPF with all identical digits is invalid', code: 'KNOWN_INVALID_PATTERN' }CNPJ — numeric and alphanumeric (new RFB format)
import { validateCnpj, formatCnpj } from '@br-validators/core/cnpj';
// Numeric (current format)
validateCnpj('11.222.333/0001-81');
// { ok: true, value: '11222333000181', format: 'numeric' }
// Alphanumeric (new format — effective July 2026)
validateCnpj('12ABC34501DE35');
// { ok: true, value: '12ABC34501DE35', format: 'alphanumeric' }
formatCnpj('12ABC34501DE35');
// { ok: true, formatted: '12.ABC.345/01DE-35' }Auto-detect document type
import { detect } from '@br-validators/core';
detect('123.456.789-09');
// { type: 'cpf', ok: true, value: '12345678909' }
detect('ABC1D23');
// { type: 'placa', ok: true, format: 'mercosul' }
detect('110042490114', { uf: 'SP' });
// { type: 'inscricao-estadual', ok: true }Generate valid documents for tests
import { generate } from '@br-validators/core';
generate('cpf', { seed: 42 }); // reproducible, always valid
generate('cnpj', { format: 'alphanumeric', masked: true });
generate('placa', { format: 'mercosul' });
generate('renavam');
generate('cnh');
generate('inscricao-estadual', { uf: 'SP', seed: 42 });
generate('titulo-eleitor', { uf: 'SC', seed: 42 });
generate('cartao-credito', { brand: 'visa', seed: 42 });
generate('pix', { seed: 42 }); // EVP UUID — Bacen DICT
generate('nfe-chave', { seed: 42 }); // MOC §2.2.6 modulo-11 DV
generate('brcode', { seed: 42 }); // static PIX EMV + CRC16
generate('boleto', { masked: true }); // FEBRABAN cobrança Situação 1
generate('boleto-arrecadacao'); // FEBRABAN Layout v7
generate('inscricao-estadual-produtor-rural', { masked: true }); // SP SINTEGRA Bloco II
generate()is for test fixtures and seed data only — never use in production.
Alphanumeric CPF:generate('cpf', { format: 'alphanumeric' })throwsCPF_ALPHA_SPEC_PENDINGuntil RFB publishes the official algorithm (OFFICIAL-SOURCES.md).
ETL / data cleanup
import { sanitize } from '@br-validators/core';
sanitize(' 123.456.789-09 ', 'cpf');
// { ok: true, value: '12345678909', fixes: ['trimmed', 'removed_non_digits'] }
sanitize('110.042.490.114', 'inscricao-estadual', { uf: 'SP' });
// { ok: true, value: '110042490114', fixes: [...] }NF-e chave de acesso (44 digits)
import { validateNfeChave, parseNfeChave } from '@br-validators/core/nfe-chave';
const result = validateNfeChave('52060433009911002506550120000007800267301615');
// { ok: true, parsed: { cUF: '52', cnpj: '33009911002506', mod: '55', ... }, uf: 'GO' }BR Code (PIX QR payload)
import {
buildStaticPixBrCode,
parseBrCode,
validateBrCode,
} from '@br-validators/core/brcode';
// Permanent static QR (no amount — payer sets value at payment time)
const payload = buildStaticPixBrCode({
pixKey: '[email protected]',
merchantName: 'Fulano de Tal',
merchantCity: 'BRASILIA',
});
validateBrCode(payload).ok; // true
// Fixed-value static QR
buildStaticPixBrCode({
pixKey: '[email protected]',
merchantName: 'Fulano de Tal',
merchantCity: 'BRASILIA',
amount: '10.50',
});
parseBrCode(payload);
// { ok: true, pixKey, pixKeyType, merchantName, merchantCity, amount, txid }Playground: doc-raiz-playground.vercel.app/pix renders the QR image from buildStaticPixBrCode output. Official sources: Bacen Manual BR Code · Manual de Padrões PIX.
Boleto — cobrança + arrecadação
import { validateBoleto, validateArrecadacao } from '@br-validators/core/boleto';
validateBoleto('03399.02579 08991.834006 71742.301014 6 14500000099668');
// cobrança Situação 1/2 — FEBRABAN FB-0061/2021
validateArrecadacao('846300000003812345678906123456789015234567890129');
// arrecadação 48-digit — FEBRABAN Layout v7Platform APIs — mask, compare, batch, diff
import { mask, compare, batch, diff } from '@br-validators/core';
mask('12345678909', 'cpf');
// { ok: true, formatted: '123.456.789-09' }
compare('123.456.789-09', '12345678909', 'cpf');
// { equal: true }
batch(['12345678909', 'invalid'], 'cpf');
// { valid: [...], invalid: [...], summary: { total: 2, valid: 1, invalid: 1 } }
diff('12345678909', '12345678901', 'cpf');
// { changed: true, fields: [{ field: 'dv', a: '09', b: '01' }] }Per-type rules and official sources: docs/OFFICIAL-SOURCES.md · API contract: docs/LIBRARY-API.md
Backend / form integration:
format*andmask()validate first — they never left-pad partial input ("0"will not become000.000.000-00). Do not combinepadStartwith display formatting inonChange; pad to full width only at submit if your API requires it. Details: LIBRARY-API.md — display vs backend normalization.
Form handler (React / Next.js)
'use client';
import { validateCnpj, formatCnpj } from '@br-validators/core/cnpj';
import { useState } from 'react';
export function CnpjField() {
const [input, setInput] = useState('');
const result = input ? validateCnpj(input) : null;
const formatted = result?.ok ? formatCnpj(result.value) : null;
return (
<div>
<input value={input} onChange={e => setInput(e.target.value)} />
{formatted?.ok && <p>✅ {formatted.formatted}</p>}
{result && !result.ok && <p>❌ {result.message}</p>}
</div>
);
}Shell / CI
br-validators cnpj validate "$CNPJ" --quiet || exit 1
br-validators ie validate "$IE" --uf SP --json
br-validators detect '123.456.789-09' --json
br-validators generate cpf --seed 42 --masked
br-validators generate pix --seed 42
br-validators generate nfe-chave --seed 42
br-validators generate brcode --seed 42
br-validators generate boleto --masked --seed 42
br-validators generate boleto-arrecadacao --seed 42
br-validators generate inscricao-estadual-produtor-rural --masked --seed 42All supported types
| Document | Subpath import | CLI | Playground |
|---|---|---|---|
| CPF | @br-validators/core/cpf | br-validators cpf … | /cpf |
| CNPJ (numeric + alphanumeric) | @br-validators/core/cnpj | br-validators cnpj … | /cnpj |
| CEP | @br-validators/core/cep | br-validators cep … | /cep (+ getCepFaixaInfo prefix lookup) |
| Telefone | @br-validators/core/telefone | br-validators telefone … | /telefone |
| CNH | @br-validators/core/cnh | br-validators cnh … | /cnh |
| RENAVAM | @br-validators/core/renavam | br-validators renavam … | /renavam |
| Título de Eleitor | @br-validators/core/titulo-eleitor | br-validators titulo-eleitor … | /titulo-eleitor |
| Processo judicial CNJ | @br-validators/core/processo-judicial | br-validators processo-judicial … | /processo-judicial |
| RG (per-UF identity card) | @br-validators/core/rg | br-validators rg … --uf SP | /rg |
| Placa (Mercosul + legada) | @br-validators/core/placa | br-validators placa … | /placa |
| PIS / PASEP / NIS | @br-validators/core/pis-pasep | br-validators pis-pasep … | /pis |
| PIX key | @br-validators/core/pix | br-validators pix … | /pix |
| BR Code (PIX QR payload + builder) | @br-validators/core/brcode | br-validators brcode … | /brcode |
| Boleto cobrança (Situação 1 + 2) | @br-validators/core/boleto | br-validators boleto … | /boleto |
| Boleto arrecadação (48/44) | @br-validators/core/boleto | br-validators boleto … | /boleto |
| NF-e / NFC-e chave (44 digits) | @br-validators/core/nfe-chave | br-validators nfe-chave … | /nfe-chave |
| Cartão de crédito (Luhn) | @br-validators/core/cartao-credito | br-validators cartao … | /cartao-credito |
| Inscrição Estadual (27 UFs) | @br-validators/core/inscricao-estadual | br-validators ie … --uf SP | /ie |
| IE Produtor Rural | @br-validators/core/inscricao-estadual-produtor-rural | br-validators ie … (auto P) | /ie |
| detect() | @br-validators/core/detect | br-validators detect … | /detect |
| sanitize() | @br-validators/core/sanitize | br-validators sanitize … | /sanitize |
| mask() | @br-validators/core/mask | — | via per-type format |
| compare() | @br-validators/core/compare | — | — |
| batch() | @br-validators/core/batch | — | — |
| diff() | @br-validators/core/diff | — | — |
| generate() | @br-validators/core/generate | br-validators generate … | /generate |
| buildStaticPixBrCode() | @br-validators/core/brcode | — | /pix (QR panel) |
Reference data (offline lookup)
Embedded JSON from official .gov.br sources — no runtime HTTP. Each module exports *_DATA_VERSION with capture date, row counts, and source URLs. Aggregated via @br-validators/core/data-catalog.
| Dataset | Subpath | CLI | Playground | Key APIs | Official source |
|---------|---------|-----|------------|----------|-----------------|
| IBGE states + municipalities | @br-validators/core/ibge | ibge lookup · list | /data/ibge | getEstados, getMunicipios, getMunicipioPorCodigo | IBGE localidades API |
| Bacen STR banks (COMPE / ISPB) | @br-validators/core/bancos | bancos lookup · list | /data/bancos | getBancos, getBancoPorCodigo, getBancoPorIspb | Bacen Participantes STR |
| ANAC public aerodromos | @br-validators/core/aeroportos | aeroportos lookup | /data/logistics | getAeroportos, getAeroportoPorIata, getAeroportoPorIcao, getAeroportosPorMunicipio | ANAC aeródromos públicos CSV |
| ANTAQ port installations | @br-validators/core/portos | portos lookup | /data/logistics | getPortoPorCodigo, searchPortos, getPortosPorMunicipio | ANTAQ instalações portuárias zip |
| ANP fuel prices (LPC) | @br-validators/core/anp-combustiveis | — | /data/logistics | getAnpPrecosMedios, getAnpPrecosMediosPorIbge, getAnpSemanaAtual | ANP levantamento LPC |
| TSE ↔ IBGE municipality codes | @br-validators/core/tse-municipios | tse-municipios lookup | /data/ibge (cross-ref) | getMapeamentoTseIbge, getMunicipioIbgePorCodigoTse, getCodigosTsePorMunicipio | TSE municipio_tse_ibge.zip |
| DDD geographic lookup | @br-validators/core/telefone | ddd lookup | — | getDddInfo (extends telefone validator) | Anatel DDD panel |
| National holidays | @br-validators/core/feriados | feriados list --year | /data/calendar | isFeriadoNacional, getFeriadosNacionais, getProximoDiaUtil | Lei 662/1949 + annual Portaria MGI |
| CNAE 2.3 subclasses | @br-validators/core/cnaes | cnae lookup · search | /data/fiscal | getCnaePorCodigo, searchCnaes | IBGE CNAE API v2 |
| CFOP fiscal operations | @br-validators/core/cfop | cfop lookup · search | /data/fiscal | getCfopPorCodigo, searchCfop | CONFAZ CFOP SINIEF |
| NCM Mercosur nomenclature | @br-validators/core/ncm | ncm lookup · search | /data/fiscal | getNcmPorCodigo, searchNcm | Siscomex NCM JSON |
| Natureza jurídica (CNPJ) | @br-validators/core/natureza-juridica | natureza-juridica lookup | /data/fiscal | getNaturezaJuridicaPorCodigo | RFB Naturezas.zip |
| NBS (NFSe Nacional) | @br-validators/core/nbs | nbs lookup | /data/fiscal | getNbsPorCodigo, searchNbs | NFSe Anexo B NBS2 xlsx |
| CEST (substituição tributária) | @br-validators/core/cest | cest lookup | /data/fiscal | getCestPorCodigo, getCestPorNcm, searchCest | CONFAZ ICMS 142/2018 |
| ISO 4217 + Bacen PTAX moedas | @br-validators/core/moedas | moedas lookup | /data/trade | getMoedaPorCodigo, searchMoedas | Bacen PTAX Moedas API |
| NF-e Bacen country codes | @br-validators/core/paises-bacen | paises-bacen lookup | /data/trade | getPaisPorCodigoBacen, getPaisesBacen | NF-e country table |
| ICC Incoterms 2020 | @br-validators/core/incoterms | incoterms lookup | /data/trade | getIncotermPorCodigo, getIncoterms | ICC Incoterms rules |
| CBO 2002 occupations | @br-validators/core/cbo | cbo lookup · search | /data/fiscal | getCboPorCodigo, searchCbo | MTE CBO downloads |
| CEP prefix lookup | @br-validators/core/cep | cep faixa | — | getCepFaixaInfo, getCepFaixas | IBGE CNEFE 2022 |
| Data transparency catalog | @br-validators/core/data-catalog | — | /data/catalog | getDataCatalog, getDatasetMetadata | Aggregates all metadata.json entries |
import { getMunicipioPorCodigo } from '@br-validators/core/ibge';
import { getBancoPorCodigo } from '@br-validators/core/bancos';
import { getDddInfo } from '@br-validators/core/telefone';
import { isFeriadoNacional } from '@br-validators/core/feriados';
import { getCnaePorCodigo } from '@br-validators/core/cnaes';
import { getCfopPorCodigo } from '@br-validators/core/cfop';
import { getNcmPorCodigo } from '@br-validators/core/ncm';
import { getCboPorCodigo } from '@br-validators/core/cbo';
import { getNaturezaJuridicaPorCodigo } from '@br-validators/core/natureza-juridica';
import { getNbsPorCodigo } from '@br-validators/core/nbs';
import { getCestPorCodigo } from '@br-validators/core/cest';
import { getMoedaPorCodigo } from '@br-validators/core/moedas';
import { getPaisPorCodigoBacen } from '@br-validators/core/paises-bacen';
import { getIncotermPorCodigo } from '@br-validators/core/incoterms';
import { getAeroportoPorIata } from '@br-validators/core/aeroportos';
import { getPortoPorCodigo } from '@br-validators/core/portos';
import { getDataCatalog } from '@br-validators/core/data-catalog';
getMunicipioPorCodigo(3550308)?.nome; // São Paulo
getBancoPorCodigo('001')?.nome; // Banco do Brasil
getDddInfo('11')?.uf; // SP
isFeriadoNacional('2026-01-01'); // true — Confraternização Universal
getCnaePorCodigo('6201501'); // custom software development
getCfopPorCodigo('1.102'); // accepts CONFAZ dotted format
getNcmPorCodigo('01012100'); // purebred horses (8-digit leaf)
getCboPorCodigo('212405'); // systems development analyst
getNaturezaJuridicaPorCodigo('2062'); // Sociedade Empresária Limitada
getNbsPorCodigo('1.1502.50.00'); // TI systems integration (NFSe)
getCestPorCodigo('0302100'); // returnable beer bottle (ST)
getMoedaPorCodigo('BRL')?.nome; // Real Brasileiro
getPaisPorCodigoBacen('1058')?.nome; // Brasil (NF-e cPais)
getIncotermPorCodigo('FOB')?.nome; // Free On Board
getAeroportoPorIata('GRU')?.nome; // Guarulhos — SP
getPortoPorCodigo('BRSSZ')?.nome; // Santos organized port
getDataCatalog().length; // registered datasetsFreshness table (auto-updated weekly): docs/DATA-FRESHNESS.md · Per-type official URLs: docs/OFFICIAL-SOURCES.md
Tree-shaking
// Only ships the CPF module — nothing else
import { validateCpf } from '@br-validators/core/cpf';
// Only ships NF-e module
import { parseNfeChave } from '@br-validators/core/nfe-chave';Related packages
| Package | Status |
|---|---|
| @br-validators/cli | Published |
| @br-validators/zod | Published — Zod 3/4 schemas |
| @br-validators/react-hook-form | Published — RHF resolvers |
Contributing
Issues, corrections, and new document types are welcome.
See CONTRIBUTING.md and open good first issue items.
License
MIT — permanently free and open source.
