<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mateus Alves</title>
    <description>The latest articles on DEV Community by Mateus Alves (@msilvaspa).</description>
    <link>https://dev.to/msilvaspa</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F67991%2F7a6f9ce2-fde5-4d23-9504-ba4298cfb636.png</url>
      <title>DEV Community: Mateus Alves</title>
      <link>https://dev.to/msilvaspa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/msilvaspa"/>
    <language>en</language>
    <item>
      <title>brazuka-utils: a lib TypeScript que já suporta o CNPJ alfanumérico</title>
      <dc:creator>Mateus Alves</dc:creator>
      <pubDate>Wed, 25 Mar 2026 01:34:33 +0000</pubDate>
      <link>https://dev.to/msilvaspa/brazuka-utils-a-lib-typescript-que-ja-suporta-o-cnpj-alfanumerico-3ae5</link>
      <guid>https://dev.to/msilvaspa/brazuka-utils-a-lib-typescript-que-ja-suporta-o-cnpj-alfanumerico-3ae5</guid>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;&lt;a href="https://www.npmjs.com/package/brazuka-utils" rel="noopener noreferrer"&gt;brazuka-utils&lt;/a&gt;&lt;/strong&gt; nasceu pra resolver isso. É uma lib TypeScript com &lt;strong&gt;zero dependências&lt;/strong&gt;, &lt;strong&gt;tree-shakeable&lt;/strong&gt;, que cobre CPF, CNPJ, CEP, telefone, moeda e placas veiculares — tudo num pacote só.&lt;/p&gt;

&lt;p&gt;Mas o que realmente diferencia ela são dois recursos que (ainda) são raros de encontrar:&lt;/p&gt;




&lt;h2&gt;
  
  
  1. CNPJ alfanumérico — pronto pra julho de 2026
&lt;/h2&gt;

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

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

&lt;p&gt;A &lt;code&gt;brazuka-utils&lt;/code&gt; já suporta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;validateCNPJ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;formatCNPJ&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;brazuka-utils/cnpj&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// CNPJ numérico (formato atual) — continua funcionando normalmente&lt;/span&gt;
&lt;span class="nf"&gt;validateCNPJ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;11.222.333/0001-81&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="c1"&gt;// CNPJ alfanumérico (novo formato)&lt;/span&gt;
&lt;span class="nf"&gt;validateCNPJ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AA.000.000/0010-66&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="nf"&gt;validateCNPJ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;B3.CD5.E6F/7G8H-84&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="c1"&gt;// Formatação também funciona com o novo formato&lt;/span&gt;
&lt;span class="nf"&gt;formatCNPJ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AA000000001066&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;// 'AA.000.000/0010-66'&lt;/span&gt;
&lt;span class="nf"&gt;formatCNPJ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;B3CD5E6F7G8H84&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// 'B3.CD5.E6F/7G8H-84'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Como funciona por baixo
&lt;/h3&gt;

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

&lt;ul&gt;
&lt;li&gt;Dígitos &lt;code&gt;0-9&lt;/code&gt; continuam valendo &lt;code&gt;0-9&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Letras &lt;code&gt;A-Z&lt;/code&gt; valem &lt;code&gt;10-35&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// A validação por dentro (simplificado):&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;weights&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;weights&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// parseInt com base 36!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A retrocompatibilidade é total: todo CNPJ numérico válido continua sendo aceito sem nenhuma mudança.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Busca de CEP com fallback automático
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;brazuka-utils&lt;/code&gt; resolve isso com uma &lt;strong&gt;estratégia de fallback entre provedores&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BrasilAPI (primário) → ViaCEP (fallback)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;lookupCEP&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;brazuka-utils/cep&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;lookupCEP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;01001000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// {&lt;/span&gt;
&lt;span class="c1"&gt;//   cep: '01001000',&lt;/span&gt;
&lt;span class="c1"&gt;//   state: 'SP',&lt;/span&gt;
&lt;span class="c1"&gt;//   city: 'São Paulo',&lt;/span&gt;
&lt;span class="c1"&gt;//   neighborhood: 'Sé',&lt;/span&gt;
&lt;span class="c1"&gt;//   street: 'Praça da Sé',&lt;/span&gt;
&lt;span class="c1"&gt;//   provider: 'BrasilAPI'  ← indica qual provedor respondeu&lt;/span&gt;
&lt;span class="c1"&gt;// }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Detalhes técnicos
&lt;/h3&gt;

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

&lt;p&gt;A arquitetura é aberta: internamente usa uma interface &lt;code&gt;CepProvider&lt;/code&gt;, então novos provedores podem ser adicionados facilmente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;CepProvider&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cep&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CepData&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  O que mais tem na lib
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Módulo&lt;/th&gt;
&lt;th&gt;Funções&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CPF&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;validateCPF&lt;/code&gt;, &lt;code&gt;formatCPF&lt;/code&gt;, &lt;code&gt;generateCPF&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CNPJ&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;validateCNPJ&lt;/code&gt;, &lt;code&gt;formatCNPJ&lt;/code&gt;, &lt;code&gt;generateCNPJ&lt;/code&gt;, &lt;code&gt;generateAlphanumericCNPJ&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CEP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;validateCEP&lt;/code&gt;, &lt;code&gt;lookupCEP&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Telefone&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;validatePhone&lt;/code&gt;, &lt;code&gt;formatPhone&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Moeda&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;formatCurrency&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Placa&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;validatePlate&lt;/code&gt; (Mercosul + antigo)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Exemplos rápidos&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;validateCPF&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;formatCPF&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;brazuka-utils/cpf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;formatCurrency&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;brazuka-utils/currency&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;validatePlate&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;brazuka-utils/plate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nf"&gt;validateCPF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;123.456.789-09&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="nf"&gt;formatCPF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;12345678909&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="c1"&gt;// '123.456.789-09'&lt;/span&gt;
&lt;span class="nf"&gt;formatCurrency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1234.56&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       &lt;span class="c1"&gt;// 'R$ 1.234,56'&lt;/span&gt;
&lt;span class="nf"&gt;validatePlate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ABC1D23&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="c1"&gt;// true (Mercosul)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Por que usar
&lt;/h2&gt;

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




&lt;h2&gt;
  
  
  Instalação
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;brazuka-utils
&lt;span class="c"&gt;# ou&lt;/span&gt;
pnpm add brazuka-utils
&lt;span class="c"&gt;# ou&lt;/span&gt;
yarn add brazuka-utils
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;npm&lt;/strong&gt;: &lt;a href="https://www.npmjs.com/package/brazuka-utils" rel="noopener noreferrer"&gt;npmjs.com/package/brazuka-utils&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/mateus-alves-dev/brazuka-utils" rel="noopener noreferrer"&gt;github.com/mateus-alves-dev/brazuka-utils&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Se curtiu, deixa uma ⭐ no repo. Feedback e PRs são bem-vindos!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Tags: #typescript #javascript #brazil #opensource #webdev&lt;/em&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>brazil</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
