Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

Single Executable no Node.js

Atualizado em: 13 de agosto de 2026

Estação de trabalho usada no desenvolvimento de aplicações Node.js

Distribuir uma aplicação Node.js normalmente exige instalar o runtime, copiar arquivos, instalar dependências e manter uma estrutura de diretórios. O recurso de Single Executable no Node.js permite empacotar o código da aplicação dentro de um executável baseado no binário do Node.js.

Essa abordagem é útil para CLIs, ferramentas internas, agentes, utilitários de suporte e aplicações que precisam ser entregues a usuários sem configurar um ambiente Node.js completo. Entretanto, gerar um único arquivo não elimina dependências nativas, arquivos externos, diferenças entre sistemas operacionais ou responsabilidades de atualização.

Neste guia, você aprenderá o fluxo de geração de um executável, o arquivo de configuração SEA, o blob de preparação, injeção no binário, assets, CommonJS, ES Modules, dependências, assinatura, cross-compilation, segurança e atualização.

O que é uma Single Executable Application?

Single Executable Applications, ou SEA, é um recurso do Node.js para incorporar um script e recursos em um binário. A documentação oficial de Single Executable Applications descreve o processo e as limitações. O projeto postject no GitHub é uma ferramenta usada para injetar o blob em executáveis.

Para entender os formatos de módulos, veja CommonJS no Node.js e ES Modules no Node.js.

Casos de uso

  • ferramentas de linha de comando;
  • agentes instalados em servidores;
  • utilitários de migração;
  • diagnóstico offline;
  • aplicações distribuídas para equipes não técnicas;
  • executáveis usados em pipelines;
  • provas de conceito com instalação simples.

O que não é resolvido automaticamente?

  • dependências nativas por plataforma;
  • arquivos de configuração externos;
  • certificados e segredos;
  • migrações de banco;
  • atualizações do executável;
  • compatibilidade entre sistemas;
  • assinatura de código;
  • antivírus e políticas corporativas.

Preparando o script principal

// cli.cjs
console.log('Aplicação iniciada');
console.log({
  version: process.version,
  platform: process.platform,
  arch: process.arch
});

O fluxo mais direto usa um arquivo CommonJS. Recursos mais recentes podem ampliar suporte, mas consulte a versão do Node.js escolhida.

Arquivo de configuração

{
  "main": "cli.cjs",
  "output": "sea-prep.blob",
  "disableExperimentalSEAWarning": true,
  "useSnapshot": false,
  "useCodeCache": true
}

Salve como sea-config.json. Os campos disponíveis dependem da versão.

Gerando o blob

node --experimental-sea-config sea-config.json

O comando gera o arquivo de preparação definido em output. A flag e o aviso experimental podem mudar conforme o recurso amadurece.

Copiando o binário do Node.js

Em sistemas Unix:

cp "$(command -v node)" my-tool

No Windows, copie node.exe para um novo nome. Use o binário oficial e verifique sua origem.

Removendo assinatura antes da injeção

Em plataformas como macOS e Windows, um binário assinado pode precisar ter sua assinatura removida antes da alteração. Depois da injeção, assine novamente.

Os comandos variam conforme a plataforma e os certificados disponíveis.

Injetando o blob

npx postject my-tool \
  NODE_SEA_BLOB sea-prep.blob \
  --sentinel-fuse NODE_SEA_FUSE_...

Use exatamente o fuse documentado pela versão. Um valor incorreto gera executável inválido.

Executando

./my-tool

O executável inicia o runtime incorporado e executa o script empacotado.

Automatizando o build

set -e

node --experimental-sea-config sea-config.json
cp "$(command -v node)" dist/my-tool
npx postject dist/my-tool NODE_SEA_BLOB sea-prep.blob \
  --sentinel-fuse NODE_SEA_FUSE_...

Use CI reprodutível, versão fixa do Node.js e checksum dos artefatos.

Code cache

useCodeCache pode reduzir trabalho de compilação no início. O cache é ligado à versão e à arquitetura do runtime. Teste o executável na mesma plataforma de destino.

Snapshot

useSnapshot pode inicializar estado antecipadamente, mas impõe limitações. Não inclua conexões, descritores ou dados específicos da máquina no snapshot.

Assets

A configuração pode permitir incorporar arquivos:

{
  "main": "cli.cjs",
  "output": "sea-prep.blob",
  "assets": {
    "help.txt": "./assets/help.txt",
    "schema.json": "./assets/schema.json"
  }
}

Assets ficam disponíveis por APIs específicas do módulo SEA.

Lendo assets

const { getAsset } = require('node:sea');

const help = getAsset('help.txt', 'utf8');
console.log(help);

A assinatura da API depende da versão. Consulte a documentação.

Assets não são segredos

Dados incorporados podem ser extraídos do executável. Não inclua chaves privadas, tokens ou senhas.

Arquivos externos

Configurações que mudam após o build devem permanecer externas:

const configPath = process.env.APP_CONFIG;
const config = JSON.parse(
  fs.readFileSync(configPath, 'utf8')
);

Use validação e caminhos controlados. Veja File System no Node.js e Variáveis de Ambiente no Node.js.

Dependências JavaScript

O script incorporado não transforma automaticamente todo o node_modules em um bundle. Muitas equipes usam um bundler para gerar um único arquivo CommonJS antes do SEA.

Bundling

Um bundler pode:

  • resolver imports;
  • eliminar código não usado;
  • incluir dependências JavaScript;
  • minificar;
  • gerar sourcemap.

Teste módulos dinâmicos, leitura de arquivos e caminhos relativos.

require dinâmico

require(pluginName);

Bundlers não conseguem resolver todos os valores dinâmicos. Mantenha uma allowlist ou distribua plugins externamente.

__dirname e caminhos

O script incorporado não está em um arquivo comum no disco. Não presuma que __dirname aponta para assets da aplicação.

Use APIs SEA para assets e process.execPath para localizar o executável.

Diretório do executável

const path = require('node:path');
const executableDirectory = path.dirname(process.execPath);

Esse diretório pode ser somente leitura. Para dados graváveis, use diretório de dados do usuário ou configuração explícita.

process.argv

const args = process.argv.slice(1);

O formato dos argumentos pode diferir de um script normal. Teste a versão e use um parser.

ES Modules

O suporte direto ao script principal pode ter restrições. Uma estratégia é gerar bundle CommonJS. Outra é usar import dinâmico conforme suportado.

Não assuma que import.meta.url representa um arquivo real.

Addons nativos

Arquivos .node são binários por plataforma e geralmente precisam existir fora do executável ou ser extraídos para o disco. Eles também dependem da ABI.

Prefira dependências puramente JavaScript quando a portabilidade é prioridade.

Child Process

Se a aplicação chama binários externos, eles continuam necessários:

spawn('git', ['--version']);

O SEA não incorpora automaticamente o Git. Veja Child Process no Node.js.

Certificados

HTTPS pode depender do store de certificados do sistema. Teste em ambientes mínimos e containers.

Cross-compilation

Normalmente, gere um executável para cada combinação de sistema operacional e arquitetura:

  • Windows x64;
  • Linux x64;
  • Linux arm64;
  • macOS x64;
  • macOS arm64.

O binário base precisa corresponder ao destino.

Build matrix

Use runners nativos ou pipelines separados. Teste o artefato em ambiente limpo, não apenas na máquina de build.

Assinatura no macOS

Após a injeção, assine o binário. Distribuição ampla pode exigir notarização.

Assinatura no Windows

Use certificado de code signing e timestamp. Binários não assinados podem gerar alertas de reputação.

Linux

Bibliotecas do sistema, glibc e outras dependências ainda afetam compatibilidade. Teste em distribuições suportadas.

Tamanho

O executável inclui o runtime e pode ter dezenas de megabytes. Compressão do instalador pode reduzir download, mas o arquivo final continua grande.

Inicialização

Code cache e snapshot podem melhorar startup, mas meça. Antivírus, disco e assinatura também influenciam.

Atualizações

Um executável incorpora uma versão do Node.js. Para receber correções de segurança, é preciso rebuildar e redistribuir.

Versão

console.log({
  app: '1.4.0',
  node: process.version
});

Exponha versão da aplicação e runtime para suporte.

Atualização automática

Se implementar auto-update:

  • use HTTPS;
  • verifique assinatura;
  • verifique hash;
  • faça download atômico;
  • mantenha rollback;
  • não execute arquivo parcial.

Segurança

Empacotamento não protege o código contra análise. Strings, assets e lógica podem ser extraídos.

Permission Model

O executável pode ser iniciado com opções do runtime ou configuração compatível. Avalie o Permission Model no Node.js para limitar arquivos e processos.

Integridade

Publique checksums:

sha256sum my-tool

Checksums sem canal confiável não provam autoria. Combine com assinatura.

Sourcemaps

Manter sourcemaps externos ajuda suporte, mas pode expor código. Armazene em sistema restrito e associe à versão.

Logs

Uma CLI deve separar stdout e stderr. Consulte Console no Node.js.

Testes

Teste:

  • execução sem Node instalado;
  • argumentos;
  • assets;
  • configuração externa;
  • diretório somente leitura;
  • atualização;
  • assinatura;
  • cada plataforma;
  • antivírus corporativo;
  • caminhos com Unicode.

CI

O pipeline deve:

  1. fixar Node.js;
  2. instalar dependências com lockfile;
  3. executar testes;
  4. gerar bundle;
  5. gerar blob;
  6. copiar binário;
  7. injetar;
  8. assinar;
  9. testar artefato;
  10. publicar checksum.

Erros comuns

  • Assumir que node_modules foi incluído: require falha.
  • Usar caminhos relativos: assets não são encontrados.
  • Incluir segredos: dados podem ser extraídos.
  • Gerar só para uma plataforma: usuários incompatíveis ficam sem artefato.
  • Não rebuildar o runtime: vulnerabilidades permanecem.
  • Ignorar assinatura: sistema e antivírus bloqueiam.
  • Não testar em máquina limpa: dependências externas ficam escondidas.

Boas práticas

  • Use versão fixa do Node.js.
  • Gere bundle controlado.
  • Mantenha segredos externos.
  • Use assets apenas para conteúdo público.
  • Crie build por plataforma.
  • Assine artefatos.
  • Publique checksums.
  • Teste em ambiente limpo.
  • Planeje atualização.
  • Monitore versões incorporadas.

Conclusão

O recurso de Single Executable no Node.js simplifica a distribuição de CLIs e utilitários ao incorporar o código em um binário baseado no runtime.

O arquivo único não elimina as responsabilidades de build e segurança. Dependências, assets, addons nativos, assinatura, plataformas e atualizações precisam de planejamento. Com bundle reproduzível, matriz de builds, testes em máquinas limpas e artefatos assinados, SEA pode oferecer uma experiência de instalação simples sem perder controle operacional.

Os 10 Melhores Cursos de Programação de 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita