JavaScript CNPJ Validation: Handling Alphanumeric Formats
BIGINT or ^\d{14}$ for CNPJ validation is now a ticking time bomb. By July 2026, new companies will start receiving alphanumeric CNPJs (e.g., 12.ABC.345/01DE-35), and if your system expects only numbers, it's going to crash and burn the moment a client with a "lettered" ID tries to sign up.The technical shift is simple: the first 12 characters now accept 0-9 and A-Z, while the last two check digits remain numeric. The math still uses Modulo 11, but the twist is that characters are now processed as ASCII - 48. This means '0' stays 0, but 'A' becomes 17.
If you're doing a deep dive into your legacy code, look for parseInt() calls or numeric database columns—those are your primary points of failure.
Here is a practical tutorial on how to implement the official validation logic from scratch in JavaScript:
function checkDigits(base12) {
const W1 = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
const W2 = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
const val = (ch) => ch.charCodeAt(0) - 48; // '0'-'9' → 0-9, 'A'-'Z' → 17-42
const dv = (chars, weights) => {
const sum = chars.reduce((acc, ch, i) => acc + val(ch) * weights[i], 0);
const rest = sum % 11;
return rest < 2 ? 0 : 11 - rest;
};
const c = base12.split("");
const dv1 = dv(c, W1);
const dv2 = dv([...c, String(dv1)], W2);
return `${dv1}${dv2}`;
}
// Official example: should return "35"
console.log(checkDigits("12ABC34501DE"));For those who don't feel like reinventing the wheel or writing their own regex to handle normalization and repetition checks, there's a zero-dependency package that handles this. It's basically a complete guide in a library.
npm install valida-cnpj-alfanumericoconst CNPJ = require("valida-cnpj-alfanumerico");
CNPJ.isValid("12.ABC.345/01DE-35"); // true
CNPJ.generate({ alphanumeric: true, masked: true }); // Great for test dataIf you're managing a massive codebase, manually searching for every regex is a nightmare. There is a GitHub Action called cnpj-scan that scans your PRs for "dangerous" patterns like numeric-only columns or restrictive regex, which is a lifesaver for avoiding production regressions.
For a full deployment of this logic, keep the source link handy:
https://github.com/andrehenrique311085-debug/valida-cnpj-alfanumerico