1

Calculando o limite do MEI e o DAS de 2026 em ~50 linhas de JavaScript (com o que muda pela LC 238/2026)

Muita gente dev é MEI (ou presta serviço para MEI) e acaba controlando faturamento numa planilha improvisada. Resolvi escrever a lógica em código, com cada número amarrado a uma fonte oficial, para quem quiser colocar isso num script, num bot ou num painel próprio.

Conteúdo informativo, não substitui contador. Confira sempre o valor exibido no PGMEI.

1. Os números (e de onde vêm)

DAS mensal 2026, MEI comum. O INSS é 5% do salário mínimo = R$ 81,05. Somam-se R$ 1,00 de ICMS (comércio/indústria) e/ou R$ 5,00 de ISS (serviços):

AtividadeMEI comumMEI caminhoneiro
Só INSSR$ 81,05R$ 194,52
Comércio/indústria (+ICMS)R$ 82,05R$ 195,52
Serviços (+ISS)R$ 86,05R$ 199,52
Comércio + serviçosR$ 87,05R$ 200,52

Vencimento: dia 20 de cada mês. Emissão no PGMEI (dá para gerar as guias do ano inteiro).

Limite anual de faturamento. A Lei Complementar nº 238, de 21/10/2026, mudou o teto:

AnoLimite
2026R$ 81.000
2027R$ 110.000
2028 em dianteR$ 140.000

No ano de abertura, o limite é R$ 6.750 (2026) multiplicado pelos meses entre o início da atividade e dezembro, contando a fração de mês como mês inteiro (LC 123, art. 18-A, § 2º). Em 2027 o valor por mês é R$ 9.166,67 (LC 238, art. 2º, parágrafo único) e, a partir de 2028, R$ 11.666,67 (novo § 2º, efeitos em 01/01/2028, LC 238, art. 10, I). A mesma lei prevê até 2 empregados, mas a maior parte dela só vale a partir de 01/01/2027; hoje a regra continua sendo 1.

2. O código

// Valores em centavos para evitar erro de ponto flutuante.
const INSS = { comum: 8105, caminhoneiro: 19452 };          // 2026
const ICMS = 100, ISS = 500;
// Limite anual (LC 123, art. 18-A, § 1º; LC 238/2026, art. 2º)
const LIMITE = { 2026: 8_100_000, 2027: 11_000_000 };        // 2028+ = 14_000_000
// Valor por mês no ano de abertura (art. 18-A, § 2º; LC 238, art. 2º, par. único)
const POR_MES = { 2026: 675_000, 2027: 916_667 };            // 2028+ = 1_166_667

function das({ tipo = 'comum', comercio = false, servicos = false }) {
  return INSS[tipo] + (comercio ? ICMS : 0) + (servicos ? ISS : 0);
}

// Fração de mês conta como mês inteiro: abriu em março => 13 - 3 = 10 meses.
function mesesNoAno(ano, dataAbertura) {
  if (!dataAbertura) return 12;
  const [a, m] = dataAbertura.split('-').map(Number);       // 'AAAA-MM-DD'
  if (a > ano) throw new Error('abertura depois do ano consultado');
  return a === ano ? 13 - m : 12;
}

function limiteAnual(ano, dataAbertura) {
  const cheio = LIMITE[ano] ?? (ano >= 2028 ? 14_000_000 : null);
  if (cheio == null) throw new Error('ano sem limite cadastrado');
  const meses = mesesNoAno(ano, dataAbertura);
  if (meses === 12) return cheio;
  return (POR_MES[ano] ?? 1_166_667) * meses;
}

// LC 123, art. 18-A, § 7º, III e IV, e § 10
function faixa(valor, lim) {
  if (valor <= lim) return 'dentro';
  return valor * 10 <= lim * 12 ? 'excesso_ate_20' : 'excesso_acima_20'; // inteiros, sem 1.2
}

function situacao(faturadoCentavos, ano, dataAbertura, mesesDecorridos = 12) {
  const lim = limiteAnual(ano, dataAbertura);
  const meses = mesesNoAno(ano, dataAbertura);
  const projecao = Math.round(faturadoCentavos / mesesDecorridos * meses);
  return { lim, meses, usadoPct: +(100 * faturadoCentavos / lim).toFixed(1),
           faixa: faixa(faturadoCentavos, lim), projecao, faixaProjecao: faixa(projecao, lim) };
}

const brl = c => (c / 100).toLocaleString('pt-BR', { style: 'currency', currency: 'BRL' });
console.log(brl(das({ servicos: true })));                   // R$ 86,05
console.log(brl(limiteAnual(2026)));                         // R$ 81.000,00
console.log(brl(limiteAnual(2026, '2026-03-15')));           // R$ 67.500,00 (10 meses)
console.log(situacao(7_000_000, 2026, '2026-03-15', 7).faixa); // excesso_ate_20
console.log(situacao(9_800_000, 2026).faixa);                // excesso_acima_20

Notas de implementação:

  • Centavos como inteiro. 0.1 + 0.2 já mostrou o motivo.
  • Ano de abertura: dataAbertura, não "meses ativos". O art. 18-A, § 2º, da LC 123 diz "consideradas as frações de mês como um mês inteiro". Quem abriu em 15/03 tem 10 meses (13 − 3), não 9,5. Por isso a função recebe a data e calcula 13 - mês no ano de abertura e 12 nos demais. Obrigado ao plugandship pela correção nos comentários.
  • Estouro não é binário: 3 faixas. Pelo art. 18-A, § 7º, III (limite anual) e IV (limite proporcional do ano de abertura), e § 10:
    • dentro: até o limite;
    • excesso_ate_20: passou em até 20%. O desenquadramento vale a partir de 1º de janeiro do ano seguinte e você recolhe a diferença, sem acréscimos, em parcela única junto com o DAS de janeiro do ano seguinte;
    • excesso_acima_20: passou mais de 20%. O desenquadramento é retroativo a 1º de janeiro do ano do excesso, ou ao início da atividade se você abriu no ano.
      Em qualquer excesso, a comunicação é obrigatória até o último dia útil do mês seguinte ao excesso. A comparação usa inteiros (valor * 10 <= lim * 12) para não depender de 1.2 em ponto flutuante. A LC 238/2026 não mexeu nessas faixas nem na regra da fração de mês (ela só reescreveu o § 1º e o § 2º para os novos valores).
  • Projeção linear é ingênua (sazonalidade existe), mas serve como alerta precoce. Na prática uso faixas: verde < 70%, amarelo 70–90%, vermelho > 90% (faixa arbitrária minha, ajuste ao seu caso).
  • Parametrize por ano. O INSS acompanha o salário mínimo, então INSS muda todo janeiro; o limite muda em 2027 e 2028 pela LC 238. Hardcode sem ano é bug com data marcada.
  • Passou do limite? O código só classifica a faixa; a decisão (e o cálculo da diferença a recolher) é com um contador.

3. Fontes


Transparência / vínculo: sou o Cairo, da Cairo Labs (projeto independente meu). Mantenho uma calculadora gratuita do limite do MEI, que roda no navegador e não coleta o que você digita (https://claude-md-generator.pages.dev/mei/), e vendo uma planilha paga (R$ 37, na Kiwify) com essa mesma lógica. Tenho interesse comercial nesse assunto. O código acima é livre para usar; você não precisa de nada pago para aproveitar este post. Texto escrito com ajuda de IA e conferido nas fontes oficiais acima.

Carregando publicação patrocinada...
1

Sobre a dúvida do mês de abertura: o art. 18-A da LC 123 manda contar fração de mês como mês inteiro, então quem abriu em 28 de março tem 10 meses no ano (março a dezembro), não 9. No limiteAnual dá pra receber a data de abertura e usar 13 - mes.

Outra coisa que muda o estoura: pela regra atual, passar do limite em até 20% não tira o MEI na hora, a pessoa recolhe a diferença sobre o excesso e sai no ano seguinte. Acima de 20% o desenquadramento volta pro começo do ano (ou pra abertura). Eu faria o situacao devolver essas faixas em vez de só true/false, e conferiria se a LC 238 mexeu nesses 20%.

1

Valeu, plugandship, você tem razão nos dois pontos.

  1. Fração de mês = mês inteiro. Está no art. 18-A, § 2º, da LC 123: o limite do ano de abertura é o valor mensal "multiplicado pelo número de meses compreendidos entre o início da atividade e o final do respectivo ano-calendário, consideradas as frações de meses como um mês inteiro". Quem abriu em 15/03/2026 tem 10 meses, ou seja, R$ 6.750 × 10 = R$ 67.500.
  2. Faixa de 20%. Art. 18-A, § 7º, III (limite anual) e IV (ano de abertura): excesso de até 20% desenquadra a partir de 1º de janeiro do ano seguinte, e a diferença é recolhida sem acréscimos junto com o DAS de janeiro (§ 10). Acima de 20%, o desenquadramento é retroativo a 1º de janeiro, ou ao início da atividade.

A LC 238/2026 não mudou nenhuma das duas regras. Ela reescreve o § 1º (R$ 140 mil) e o § 2º (R$ 11.666,67 por mês) mantendo "consideradas as frações de mês como um mês inteiro", com efeitos a partir de 01/01/2028 (art. 10, I). Para 2027 ela fixa R$ 110 mil e R$ 9.166,67 por mês, com a mesma regra da fração (art. 2º e parágrafo único). Os §§ 7º e 10 não foram alterados.

Atualizei o código do post: agora ele recebe dataAbertura (13 − mês no ano de abertura) e situacao devolve dentro, excesso_ate_20 ou excesso_acima_20. Também corrigi a calculadora e a planilha.

Fontes: LC 123 compilada https://www.planalto.gov.br/ccivil_03/leis/lcp/lcp123.htm · LC 238/2026 https://www.planalto.gov.br/ccivil_03/leis/lcp/Lcp238.htm

1

boa, ficou bem mais útil com as três faixas. e bom saber que a LC 238 manteve a regra da fração, aí em 2027 e 2028 só muda o valor mensal no código.