npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

open-nfse

v0.9.1

Published

Biblioteca TypeScript/Node.js para o Padrão Nacional de NFS-e (nfse.gov.br): consulta, distribuição, emissão síncrona, cancelamento e substituição — direto na API oficial da Receita Federal.

Readme

open-nfse

Cliente TypeScript/Node.js para o Padrão Nacional de NFS-e (nfse.gov.br) — a API unificada da Receita Federal, obrigatória em todo o Brasil a partir de 1º de janeiro de 2026 (LC 214/2025). Fala direto na API oficial, sem gateway intermediário.

npm version License: MIT TypeScript

📚 Documentação: fm-s.github.io/open-nfse · API cheat sheet · API completa

Status

v0.9.x — alinhamento ao schema oficial RTC v1.01 + NT-007. Ciclo fiscal completo: consulta (chave + NSU), emissão segura com DpsCounter + RetryStore, cancelamento e substituição com máquina de 5 estados, validações locais (XSD / CPF+CNPJ / CEP), parâmetros municipais com cache, DANFSe em PDF (online + fallback local), NfseClientFake em open-nfse/testing. Pipeline de retry consciente de 429 (TooManyRequestsErrorretry_pending com notBefore honrando Retry-After; RetryPolicy pluggable).

Novidades em v0.9 — o validador passou a ser gerado dos schemas oficiais schemas/1.01/ e a lib foi auditada campo a campo contra eles: domínio completo do CST PIS/COFINS e TipoRetPisCofins (NT-007, em produção desde 2026-02-09), cNBS opcional, remoção de elementos inexistentes no RTC v1.01 (lsadppu/explRod), correção do parsing de eventos de rejeição/anulação e de campos minOccurs="0" lidos como obrigatórios. Inclui breaking renames pré-1.0 (fetchDanfseconsultarDanfse, EmitManyOptionsEmitLoteOptions, InvalidIdDpsErrorInvalidDpsIdError, enums de PIS/COFINS, xOutInf movido para InfNFSe). Veja CHANGELOG para a lista completa.

v0.9.1 — segunda auditoria de conformidade (o bundle oficial não mudou): confirmada conformante, com o valor faltante RegimeEspecialTributacao.Outros ('9') e novos enums para campos antes string (SituacaoNfse/cStat, IndicadorDestinatario/indDest, MecanismoApoioComExPrestador/Tomador/mecAFComex*), verAplic de evento obrigatório, e cinco correções no cheat sheet da API.

Foco até 1.0 é estabilização; a API pública pode receber ajustes, sem breaking changes sem aviso em CHANGELOG.

Instalar

npm install open-nfse

Requer Node.js 20+ e certificado digital A1 (ICP-Brasil) em .pfx ou .p12 do CNPJ emitente habilitado no Emissor Nacional.

Exemplo mínimo

Setup do cliente com counter atômico de nDPS e store de retry (in-memory para início rápido; produção usa Postgres):

import {
  NfseClient, Ambiente,
  createInMemoryDpsCounter, createInMemoryRetryStore,
} from 'open-nfse';
import { readFileSync } from 'node:fs';

const cliente = new NfseClient({
  ambiente: Ambiente.ProducaoRestrita,
  certificado: { pfx: readFileSync('./cert.pfx'), password: process.env.CERT_PASSWORD! },
  dpsCounter: createInMemoryDpsCounter(),
  retryStore: createInMemoryRetryStore(),
});

Emissão com resultado discriminado (ok autorizada, retry_pending salvo no store, throw em rejeição permanente):

import {
  OpcaoSimplesNacional, RegimeApuracaoSimplesNacional, RegimeEspecialTributacao,
  ReceitaRejectionError,
} from 'open-nfse';

try {
  const r = await cliente.emitir({
    emitente: {
      cnpj: '00574753000100',
      codMunicipio: '2111300',
      regime: {
        opSimpNac: OpcaoSimplesNacional.MeEpp,
        regApTribSN: RegimeApuracaoSimplesNacional.FederalEMunicipalPeloSN,
        regEspTrib: RegimeEspecialTributacao.Nenhum,
      },
    },
    serie: '1',
    servico: { cTribNac: '010101', cNBS: '123456789', descricao: 'Consultoria' },
    valores: { vServ: 1500.0, aliqIss: 2.5 },
    // Simples Nacional? informe a alíquota aproximada:
    // valores: { vServ: 1500.0, pTotTribSN: 6.0 },
    tomador: { documento: { CNPJ: '11222333000181' }, nome: 'Acme Ltda' },
  });

  if (r.status === 'ok') {
    console.log('autorizada:', r.nfse.chaveAcesso);
  } else {
    console.warn('pendente no store:', r.pending.id);
  }
} catch (err) {
  if (err instanceof ReceitaRejectionError) {
    console.error(`rejeitada [${err.codigo}]: ${err.descricao}`);
  } else {
    throw err;
  }
}

Cron de retry (mesma função cobre emitir, cancelar, substituir):

// schedule: a cada 1-5 minutos, um worker só
const items = await cliente.replayPendingEvents();
for (const item of items) {
  if (item.status === 'success_emission') await persistirNfse(item.emission);
  if (item.status === 'success')          await persistirEvento(item.evento);
  if (item.status === 'failed_permanent') alertar(item);
  // still_pending fica no store para próxima rodada
}

Exemplos runnables em examples/emit-nfse/. Padrão completo de produção (persistência, bulk com counter+retry, reconciliação) em Emitir NFS-e.

O que a lib cobre

| Escopo | Guia | |-----------------------------------------|----------------------------------------------------------------------| | Consulta por chave + distribuição por NSU | Consultar | | Emissão segura com counter + retry store | Emitir | | Cancelamento e substituição (5 estados) | Substituir e cancelar | | Validações XSD + CPF/CNPJ + CEP | Validações | | Parâmetros municipais com cache | Parâmetros | | DANFSe em PDF (online + local) | DANFSe | | Dublê em memória para testes | Testing | | Schema SQL sugerido para integração | Integração em serviços |

Arquitetura

┌────────────────────────────────────────────────────────────┐
│   API pública (NfseClient + open-nfse/testing)             │
├────────────────────────────────────────────────────────────┤
│  Leitura            │  Emissão        │  Eventos            │
│  fetch-by-chave     │  emitir         │  cancelar           │
│  fetch-by-nsu       │  emitir-em-lote │  substituir (4-st)  │
│                     │  emitirDpsPronta│  replayPendingEvents│
│                                                            │
│  Retry pipeline (429-aware): PendingEvent + RetryStore +   │
│   RetryPolicy (notBefore + attempts + safe-wrap)           │
│                                                            │
│  parse-xml ↔ build-xml + sign-xml (RTC v1.01 ↔ DTO)         │
│  build-dps (helper) + dps-id + validate-xml (XSD WASM)      │
├────────────────────────────────────────────────────────────┤
│  Validações: CPF/CNPJ DV · CEP (ViaCEP)                    │
│  Parâmetros municipais (6× consultar + cache)              │
│  DANFSe: fetch (ADN) + gerar (pdfkit local)                │
├────────────────────────────────────────────────────────────┤
│  HTTP client (undici + mTLS + HTTP/1.1, GZip/Base64, PDF)  │
│  · TooManyRequestsError (429) + getRetryAfterMs()          │
├────────────────────────────────────────────────────────────┤
│  Certificado A1 (node-forge, ICP-Brasil, pluggable)        │
└────────────────────────────────────────────────────────────┘

A API oficial está dividida em quatro hosts distintos (SEFIN Nacional, ADN Contribuintes, ADN DANFSe, ADN Parâmetros Municipais) com contratos wire diferentes — camelCase vs PascalCase, tipoAmbiente int vs string. O NfseClient resolve o host por chamada; DTOs públicos normalizam.

Princípios

DTO in, DTO out. Erros tipados em 3 níveis. Sem estado interno, com primitives de orquestração (emitirEmLote, máquina de 5 estados de substituir) e retry (RetryStore + RetryPolicy + replayPendingEvents). Types derivados dos XSDs RTC v1.01 oficiais; xs:choice vira discriminated union. Identificadores fiscais como string para preservar zeros. Builder de DPS separável do transporte (dry-run). Detalhes em Princípios de design.

Ambientes

| Serviço | Produção Restrita (homologação) | Produção (notas válidas) | |--------------------------------|----------------------------------------------------|-------------------------------------------| | SEFIN Nacional | sefin.producaorestrita.nfse.gov.br/SefinNacional | sefin.nfse.gov.br/SefinNacional | | ADN Contribuintes | adn.producaorestrita.nfse.gov.br/contribuintes | adn.nfse.gov.br/contribuintes | | ADN DANFSe | adn.producaorestrita.nfse.gov.br/danfse | adn.nfse.gov.br/danfse | | ADN Parâmetros Municipais | adn.producaorestrita.nfse.gov.br/parametrizacao | adn.nfse.gov.br/parametrizacao |

Status dos municípios

Todo município é obrigado a aderir ao Padrão Nacional, mas a migração é gradual ao longo de 2026. A lib funciona com qualquer município aderente — a API é a mesma. Municípios ainda não aderentes continuam no sistema municipal até a migração.

Escopo explícito

Suportado: consulta (chave + NSU), emissão segura (emitir(params)), eventos 101101 e 105102 (cancelamento + substituição) como emissão; parse de todos os 16 tipos de eventos via NSU distribuição (inclusive confirmação/rejeição P/T/I, cancelamento por ofício); validações locais; parâmetros municipais; DANFSe PDF; fetchDpsStatus para reconciliação.

Fora de escopo (intencional):

  • POST /decisao-judicial/nfse — backs the Emissor Público Web UI per Guia v1.2 §4.3, não é uma API de contribuinte. Emissão por decisão judicial acontece via UI Web da Receita, não via lib.
  • CNC (Cadastro Nacional de Contribuintes) — schemas CNC_v1.00.xsd / tiposCnc_v1.00.xsd não são referenciados pelo fluxo NFS-e; fora do escopo.
  • Emissão dos 14 tipos de evento "não-cancelamento" (202201 etc.) — parseamos quando chegam via NSU, mas não há builders públicos. Município-only em sua maioria; abra uma issue se precisar.
  • ADN Parâmetros Municipais — endpoints POST (beneficiomunicipal/{idManut}, regimes_especiais/{idManut}, retencoes/{idManut}) — admin-only da municipalidade.

Backlog (worth wrapping antes de 1.0):

  • GET /nfse/{chave}/eventos/{tipoEvento}/{numSeqEvento} (SEFIN) — fetch específico de evento
  • GET /NFSe/{chave}/Eventos (ADN Contribuintes) — event list por chave sem passar por NSU

Contribuindo

Bugs e sugestões: issues. PRs bem-vindos — rode npm run lint && npm run typecheck && npm test antes de abrir. Histórico de versões no CHANGELOG.md.

Links

Aviso legal

Biblioteca não oficial, sem vínculo com a Receita Federal do Brasil. Software open source, distribuído sob licença MIT, sem garantias. Homologação e conformidade fiscal são responsabilidade de quem utiliza.