Validação de CNPJ em Node.js sem dependências
Validação de CNPJ em Node.js: implementação completa sem dependências
Se você está construindo um sistema que aceita CNPJ (cadastro de fornecedores, marketplace, emissão de NF-e), precisa validar o formato e os dígitos verificadores. Muitos devs instalam uma lib para isso, mas a validação é simples o suficiente para implementar em poucas linhas.
Estrutura do CNPJ
O CNPJ tem 14 dígitos no formato XX.XXX.XXX/XXXX-XX. Os 8 primeiros identificam a empresa, os 4 seguintes identificam a filial (0001 para matriz), e os 2 últimos são dígitos verificadores calculados pelo algoritmo módulo 11.
O algoritmo
O cálculo é similar ao do CPF, mas com pesos diferentes:
- Remova a formatação (pontos, barra, traço)
- Verifique se tem exatamente 14 dígitos e não é uma sequência repetida
- Para o primeiro dígito verificador: multiplique os 12 primeiros dígitos pelos pesos 5,4,3,2,9,8,7,6,5,4,3,2
- Some os resultados e calcule o resto da divisão por 11
- Se o resto for menor que 2, o dígito é 0; caso contrário, é 11 menos o resto
- Repita com os 13 dígitos e pesos 6,5,4,3,2,9,8,7,6,5,4,3,2 para o segundo dígito
Implementação em TypeScript
Testando a validação
Agora você precisa de CNPJs fictícios para testar. Se usar apenas CNPJs inválidos, você só testa o caminho de rejeição. Gere CNPJs válidos para testar o caminho de aceitação:
Clique em Gerar para começar
Casos de teste recomendados
Via API para testes em massa
Edge cases que quebram validadores simples
A função acima cobre o caminho feliz, mas CNPJ em produção chega sujo. Vale testar estes casos antes de publicar:
- Tipo errado: o campo pode chegar como número,
nullouundefined. Um CNPJ com zeros à esquerda perde dígitos quando viranumber(00.000.000/0001-91 vira 191). Aceite só string e recuse o resto. - Espaços e caracteres invisíveis: copiar de PDF ou planilha traz espaços não separáveis. A limpeza com regex remove, mas confira o tamanho depois dela.
- Zeros à esquerda: use
padStart(14, "0")só se a origem for um campo numérico legado. Em API pública, exija os 14 dígitos. - Sequências repetidas: 00000000000000 passa no cálculo do mod-11, por isso a checagem de repetição é obrigatória.
- Matriz e filial: a ordem (0001, 0002...) não altera o algoritmo. Os dígitos verificadores consideram os 12 primeiros dígitos inteiros.
- Validade matemática não é existência: um CNPJ pode passar no mod-11 e não existir na Receita Federal. Para saber se a empresa está ativa, consulte uma fonte oficial.
CNPJ alfanumérico a partir de 2026
A Receita Federal passou a emitir CNPJs com letras nas 12 primeiras posições. Os dois últimos caracteres continuam numéricos. O cálculo usa o mesmo mod-11 e os mesmos pesos, mas cada caractere entra como seu código ASCII menos 48 (o 0 vale 0, o A vale 17, o Z vale 42). Se o seu validador limpa a entrada com um regex de "só dígitos", ele apaga as letras e rejeita CNPJs legítimos. Troque por /[^0-9A-Z]/gi e converta para maiúsculas antes de calcular. Há um passo a passo no gerador de CNPJ alfanumérico.
Usando a validação em Express
Em Express, valide na borda da rota e devolva 422 com mensagem clara. Normalize o CNPJ antes de gravar, para que o índice único no banco não aceite duas versões do mesmo número.
import express from "express";
import { validateCNPJ } from "./validate-cnpj";
const app = express();
app.use(express.json());
app.post("/fornecedores", (req, res) => {
const { cnpj } = req.body ?? {};
if (typeof cnpj !== "string" || !validateCNPJ(cnpj)) {
return res.status(422).json({ error: "CNPJ inválido" });
}
// normaliza antes de salvar
const normalizado = cnpj.replace(/\D/g, "");
return res.status(201).json({ cnpj: normalizado });
});Usando a validação em NestJS
No NestJS o caminho natural é um decorator do class-validator. Assim o ValidationPipe global rejeita o DTO antes de chegar ao service.
import { registerDecorator, ValidationOptions } from "class-validator";
import { validateCNPJ } from "./validate-cnpj";
export function IsCNPJ(options?: ValidationOptions) {
return (object: object, propertyName: string) => {
registerDecorator({
name: "isCNPJ",
target: object.constructor,
propertyName,
options: { message: "CNPJ inválido", ...options },
validator: {
validate: (value: unknown) => typeof value === "string" && validateCNPJ(value),
},
});
};
}
// create-fornecedor.dto.ts
export class CreateFornecedorDto {
@IsCNPJ()
cnpj: string;
}Usando a validação em Fastify
No Fastify, o JSON Schema cuida do formato e do tamanho, e um hook preValidation aplica o dígito verificador. O schema barra lixo barato antes do cálculo.
import Fastify from "fastify";
import { validateCNPJ } from "./validate-cnpj";
const app = Fastify();
app.post("/fornecedores", {
schema: {
body: {
type: "object",
required: ["cnpj"],
properties: { cnpj: { type: "string", minLength: 14, maxLength: 18 } },
},
},
preValidation: async (req, reply) => {
const { cnpj } = req.body as { cnpj: string };
if (!validateCNPJ(cnpj)) {
return reply.code(422).send({ error: "CNPJ inválido" });
}
},
}, async () => ({ ok: true }));Perguntas frequentes
Preciso de uma biblioteca para validar CNPJ?
Não. São cerca de 20 linhas e você controla o comportamento com entradas estranhas. Uma dependência só compensa se o time precisar de CPF, CNPJ, título de eleitor e outros documentos com a mesma API.
Posso usar CNPJs gerados em ambiente de teste?
Sim, para validar formato e fluxo. Um CNPJ gerado passa no mod-11, mas pode coincidir com o de uma empresa real por acaso. Nunca use esses números para emitir nota fiscal ou chamar serviços oficiais.
O validador deve aceitar CNPJ formatado?
Aceite as duas formas na entrada e grave sempre só os 14 caracteres. Formate apenas na exibição.
Como testar o validador de forma automatizada?
Gere uma lista de CNPJs válidos pela API e rode todos no teste de aceitação. Depois altere um dígito de cada um e confirme que todos são rejeitados. Isso pega erros de peso e de resto que um único exemplo manual não pega.
Resumo
- Validação de CNPJ são ~20 linhas de código, sem necessidade de libs externas
- O algoritmo mod-11 com pesos específicos valida os 2 dígitos verificadores
- Teste com CNPJs válidos (gerados) e inválidos para cobrir ambos os caminhos
- Use o validador online para checar CNPJs rapidamente
- Trate tipo, zeros à esquerda e CNPJ alfanumérico antes de confiar no cálculo
- Use a API para gerar CNPJs em massa no CI/CD