DEV Community

Mateus Alves
Mateus Alves

Posted on

brazuka-utils: a lib TypeScript que já suporta o CNPJ alfanumérico

Se você é dev brasileiro, já passou por isso: precisou validar um CPF, formatar um CNPJ, buscar um endereço por CEP... e acabou juntando 3 libs diferentes, cada uma com sua interface, suas dependências e seus problemas.

A brazuka-utils nasceu pra resolver isso. É uma lib TypeScript com zero dependências, tree-shakeable, que cobre CPF, CNPJ, CEP, telefone, moeda e placas veiculares — tudo num pacote só.

Mas o que realmente diferencia ela são dois recursos que (ainda) são raros de encontrar:


1. CNPJ alfanumérico — pronto pra julho de 2026

A Receita Federal publicou a IN RFB nº 2229/2024, que muda o formato do CNPJ a partir de julho de 2026. As 12 primeiras posições passam a aceitar letras (A–Z) além de dígitos, mantendo os 2 dígitos verificadores como numéricos.

Se a sua lib de validação só aceita /^\d{14}$/, ela vai quebrar.

A brazuka-utils já suporta:

import { validateCNPJ, formatCNPJ } from 'brazuka-utils/cnpj'

// CNPJ numérico (formato atual) — continua funcionando normalmente
validateCNPJ('11.222.333/0001-81') // true

// CNPJ alfanumérico (novo formato)
validateCNPJ('AA.000.000/0010-66')  // true
validateCNPJ('B3.CD5.E6F/7G8H-84') // true

// Formatação também funciona com o novo formato
formatCNPJ('AA000000001066')   // 'AA.000.000/0010-66'
formatCNPJ('B3CD5E6F7G8H84')  // 'B3.CD5.E6F/7G8H-84'
Enter fullscreen mode Exit fullscreen mode

Como funciona por baixo

O algoritmo mod-11 é o mesmo que já existe, mas com uma diferença: cada caractere é convertido para base-36 antes da multiplicação pelos pesos. Na prática:

  • Dígitos 0-9 continuam valendo 0-9
  • Letras A-Z valem 10-35
// A validação por dentro (simplificado):
const weights = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
let sum = 0
for (let i = 0; i < 12; i++) {
  sum += parseInt(raw[i], 36) * weights[i] // parseInt com base 36!
}
Enter fullscreen mode Exit fullscreen mode

A retrocompatibilidade é total: todo CNPJ numérico válido continua sendo aceito sem nenhuma mudança.


2. Busca de CEP com fallback automático

Quem já dependeu de uma API única de CEP sabe: um dia ela cai, e a feature de preenchimento automático de endereço do seu app para de funcionar.

A brazuka-utils resolve isso com uma estratégia de fallback entre provedores:

BrasilAPI (primário) → ViaCEP (fallback)
Enter fullscreen mode Exit fullscreen mode

Se a BrasilAPI falhar (timeout, 500, indisponível), a lib automaticamente tenta a ViaCEP. Sem configuração, sem retry manual, sem try/catch da sua parte.

import { lookupCEP } from 'brazuka-utils/cep'

const address = await lookupCEP('01001000')
// {
//   cep: '01001000',
//   state: 'SP',
//   city: 'São Paulo',
//   neighborhood: 'Sé',
//   street: 'Praça da Sé',
//   provider: 'BrasilAPI'  ← indica qual provedor respondeu
// }
Enter fullscreen mode Exit fullscreen mode

Detalhes técnicos

  • Timeout de 5 segundos por provedor (via AbortSignal.timeout)
  • Normalização de resposta: cada provedor tem campos diferentes (a ViaCEP retorna uf, localidade, logradouro... a BrasilAPI retorna state, city, street). A lib normaliza tudo para a mesma interface CepData
  • Retorna null se nenhum provedor encontrar o CEP — sem exceções para 404
  • Campo provider na resposta, pra você saber quem respondeu (útil pra logs e debug)

A arquitetura é aberta: internamente usa uma interface CepProvider, então novos provedores podem ser adicionados facilmente:

interface CepProvider {
  name: string
  fetch(cep: string): Promise<CepData | null>
}
Enter fullscreen mode Exit fullscreen mode

O que mais tem na lib

Módulo Funções
CPF validateCPF, formatCPF, generateCPF
CNPJ validateCNPJ, formatCNPJ, generateCNPJ, generateAlphanumericCNPJ
CEP validateCEP, lookupCEP
Telefone validatePhone, formatPhone
Moeda formatCurrency
Placa validatePlate (Mercosul + antigo)
// Exemplos rápidos
import { validateCPF, formatCPF } from 'brazuka-utils/cpf'
import { formatCurrency } from 'brazuka-utils/currency'
import { validatePlate } from 'brazuka-utils/plate'

validateCPF('123.456.789-09') // true
formatCPF('12345678909')      // '123.456.789-09'
formatCurrency(1234.56)       // 'R$ 1.234,56'
validatePlate('ABC1D23')      // true (Mercosul)
Enter fullscreen mode Exit fullscreen mode

Por que usar

  • Zero dependências — nada é puxado pro seu node_modules além da própria lib
  • Tree-shakeable — importou só validateCPF? Só isso vai pro bundle
  • TypeScript-first — tipos completos, strict: true, sem any
  • ESM + CJS — funciona em qualquer ambiente
  • 100% de cobertura nos módulos de validação e formatação
  • Pronta pro futuro — CNPJ alfanumérico já é suportado, antes da maioria das libs

Instalação

npm install brazuka-utils
# ou
pnpm add brazuka-utils
# ou
yarn add brazuka-utils
Enter fullscreen mode Exit fullscreen mode

Links


Se curtiu, deixa uma ⭐ no repo. Feedback e PRs são bem-vindos!


Tags: #typescript #javascript #brazil #opensource #webdev

Top comments (0)