Seu primeiro XML offline
Neste guia você cria nota-teste.xml no seu computador. O exemplo usa dados sintéticos, não usa certificado e não transmite a nota. Assim você confere a instalação e conhece a estrutura do ACBr.
Antes, conclua a instalação.
1. Baixe o exemplo completo
Salve primeiro-xml.mjs na pasta do projeto, ao lado do package.json. Esse arquivo já inclui todos os dados sintéticos usados na geração.
Há também uma versão TypeScript, com satisfies TNFeInput. A versão .mjs é a opção para executar diretamente no Node.js.
2. Execute
node primeiro-xml.mjsVocê deve ver:
XML sintético salvo em nota-teste.xml. Estado: XML_GERADOAbra o arquivo nota-teste.xml no editor. Ele contém o XML gerado pelo motor instalado, incluindo a identidade sintética e o texto TESTE OFFLINE.
3. Entenda a chamada
O arquivo importa criarEmissor e TNFe. Após definir o objeto nota, executa:
const emissor = criarEmissor({
cnpj: '11222333000181',
uf: 'CE',
modelo: 55,
ambiente: 2
});
try {
const resultado = await emissor.gerarXml(new TNFe(nota));
if (!resultado.sucesso || !resultado.xmlBase64) {
throw new Error(resultado.codigo ?? resultado.xMotivo ?? resultado.estado);
}
await writeFile('./nota-teste.xml', Buffer.from(resultado.xmlBase64, 'base64'));
console.log('XML sintético salvo em nota-teste.xml. Estado:', resultado.estado);
} finally {
await emissor.fechar();
}criarEmissor configura o emitente. new TNFe(nota) organiza os dados com os modelos gerados. gerarXml devolve um resultado que precisa ser conferido antes de salvar o arquivo. fechar() encerra a instância, inclusive quando ocorre uma falha.
O XML vem em xmlBase64. Buffer.from(..., 'base64') recupera os bytes originais para gravar UTF-8 sem alteração.
Os dados do exemplo
Ver o objeto completo da nota sintética
const nota = {
"infNFe": {
"Versao": "4.00"
},
"Ide": {
"cUF": 23,
"cNF": 12345678,
"natOp": "VENDA TESTE OFFLINE",
"modelo": 55,
"serie": 1,
"nNF": 1,
"dEmi": "2026-10-08T12:00:00",
"tpNF": "tnSaida",
"idDest": "doInterna",
"cMunFG": 2304400,
"tpImp": "tiRetrato",
"tpEmis": "teNormal",
"tpAmb": "taHomologacao",
"finNFe": "fnNormal",
"indFinal": "cfConsumidorFinal",
"indPres": "pcPresencial",
"procEmi": "peAplicativoContribuinte",
"verProc": "ACBR-NODE-OFFLINE"
},
"Emit": {
"CNPJCPF": "11222333000181",
"xNome": "Café São José TESTE OFFLINE SEM VALOR FISCAL",
"IE": "123456789",
"CRT": "crtSimplesNacional",
"EnderEmit": {
"xLgr": "RUA TESTE",
"nro": "1",
"xBairro": "TESTE",
"cMun": 2304400,
"xMun": "FORTALEZA",
"UF": "CE",
"CEP": 60000000,
"cPais": 1058,
"xPais": "BRASIL"
}
},
"Dest": {
"CNPJCPF": "12345678909",
"xNome": "NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL",
"indIEDest": "inNaoContribuinte",
"EnderDest": {
"xLgr": "RUA TESTE",
"nro": "2",
"xBairro": "TESTE",
"cMun": 2304400,
"xMun": "FORTALEZA",
"UF": "CE",
"CEP": 60000000,
"cPais": 1058,
"xPais": "BRASIL"
}
},
"Det": [
{
"Prod": {
"nItem": 1,
"cProd": "TESTE",
"cEAN": "SEM GTIN",
"xProd": "Café São José PRODUTO SINTÉTICO OFFLINE",
"NCM": "22021000",
"CFOP": "5102",
"uCom": "UN",
"qCom": "1",
"vUnCom": "10",
"vProd": "10",
"cEANTrib": "SEM GTIN",
"uTrib": "UN",
"qTrib": "1",
"vUnTrib": "10",
"IndTot": "itSomaTotalNFe"
},
"Imposto": {
"ICMS": {
"orig": "oeNacional",
"CSOSN": "csosn102"
},
"PIS": {
"CST": "pis07"
},
"COFINS": {
"CST": "cof07"
}
}
}
],
"Total": {
"ICMSTot": {
"vProd": "10",
"vNF": "10"
}
},
"Transp": {
"modFrete": "mfSemFrete"
},
"pag": [
{
"tPag": "fpDinheiro",
"indPag": "ipVista",
"vPag": "10"
}
]
};Os nomes têm a mesma grafia do ACBr: Ide, Emit, Dest, Det, Total, Transp e pag. Valores como qCom, vProd e vNF são strings decimais. A data é uma string civil ISO; o motor escreve o fuso da UF no XML.
NCM, CFOP, CSOSN, CST e totais deste documento são dados sintéticos para aprender a estrutura. Eles não definem a tributação correta de uma venda.
O que você concluiu
Você verificou a importação e a execução do motor, e gerou um XML sem rede. O arquivo ainda não está assinado nem autorizado. A validação de schema de uma NF-e completa exige a assinatura; chamar validar neste XML sem assinatura não equivale ao fluxo completo.
Ambiente 2
ambiente: 2 significa homologação, não um simulador local. Métodos de transmissão e consulta usam serviços fiscais. O exemplo permanece offline porque chama apenas gerarXml.
O próximo passo é entender certificado A1 e assinatura.