O tsx no Node.js permite executar arquivos TypeScript diretamente durante desenvolvimento sem criar um build intermediário manual. A ferramenta transforma o código rapidamente, entende ESM e CommonJS, oferece watch mode e pode ser usada como substituta do comando node em scripts de desenvolvimento.
Esse fluxo reduz atrito para CLIs, APIs, migrations, seeds e testes. Porém, tsx não substitui o TypeScript como verificador de tipos. Ele executa o código mesmo quando existem erros de tipo que seriam detectados por tsc. Em produção, muitas equipes ainda preferem compilar e executar JavaScript estável, mantendo tsx somente no desenvolvimento e em tarefas controladas.
Neste guia, você aprenderá a instalar tsx, executar arquivos, usar watch mode, configurar scripts, trabalhar com ESM, tsconfig paths, variáveis de ambiente, Node Test Runner, debugging, CI e escolher entre execução direta e build.
O que é tsx?
tsx significa TypeScript Execute. O projeto oficial está no repositório privatenumber/tsx e se apresenta como uma forma simples de executar TypeScript no Node.js. A ferramenta usa transformação rápida e integra comportamentos necessários para módulos e source maps.
O comando básico:
npx tsx src/server.tsEle executa o arquivo sem gerar uma pasta dist visível.
Instalação
npm install --save-dev tsxPrefira a dependência local para fixar a versão no lockfile. Evite depender de instalação global em equipes e pipelines.
Primeiro arquivo
// src/index.ts
type User = {
id: string;
name: string;
};
const user: User = {
id: crypto.randomUUID(),
name: 'Leandro'
};
console.log(user);Execute:
npx tsx src/index.tsScript de desenvolvimento
{
"scripts": {
"dev": "tsx src/server.ts"
}
}npm run devO script usa o binário local de node_modules/.bin. Veja npm Scripts no Node.js.
Watch mode
{
"scripts": {
"dev": "tsx watch src/server.ts"
}
}tsx reinicia o processo quando dependências importadas mudam. Arquivos dentro de diretórios ignorados, como node_modules e outputs, não devem disparar ciclos desnecessários.
Para o recurso nativo, consulte Watch Mode no Node.js.
Incluindo arquivos extras no watch
Quando a aplicação depende de templates ou configuração não importada diretamente:
tsx watch \
--include "templates/**/*.html" \
--include "config/**/*.json" \
src/server.tsA disponibilidade e sintaxe das opções devem ser confirmadas na versão instalada.
Ignorando caminhos
tsx watch \
--exclude "coverage/**" \
--exclude "logs/**" \
src/server.tsEvite observar arquivos que a própria aplicação gera, pois isso pode criar loop de reinicialização.
ESM e package.json
Com:
{
"type": "module"
}Você pode escrever:
import Fastify from 'fastify';
import { createApp } from './app.ts';Durante execução direta, tsx consegue trabalhar com extensões TypeScript. Entretanto, o código destinado a ser compilado por tsc e executado pelo Node.js deve seguir as regras do output, normalmente usando ./app.js nos imports relativos.
O artigo TypeScript ESM no Node.js explica NodeNext, extensões e publicação.
Não esconda incompatibilidade do build
Este código pode funcionar em execução direta:
import { config } from './config.ts';Mas um build convencional pode emitir:
import { config } from './config.ts';e o arquivo .ts não existirá em produção. Defina uma estratégia:
- usar tsx também em produção, conscientemente;
- escrever imports compatíveis com o JavaScript emitido;
- usar bundler que reescreve caminhos;
- testar sempre a forma de execução final.
tsx não faz typecheck
Um exemplo com erro:
const total: number = 'dez';
console.log(total);tsx pode transformar e executar o arquivo, porque sua função principal não é verificar tipos. Mantenha:
{
"scripts": {
"dev": "tsx watch src/server.ts",
"typecheck": "tsc --noEmit"
}
}No CI:
npm run typechecktsconfig
Uma configuração para desenvolvimento com executor:
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"noEmit": true,
"isolatedModules": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src", "test", "scripts"]
}Essa configuração pode ser adequada quando tsx é o runtime de desenvolvimento e um bundler controla produção. Se tsc produz JavaScript executado pelo Node.js, use NodeNext em uma configuração de build separada.
Configurações separadas
// tsconfig.json
{
"compilerOptions": {
"strict": true,
"noEmit": true,
"module": "ESNext",
"moduleResolution": "Bundler"
}
}// tsconfig.build.json
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"rootDir": "src",
"outDir": "dist",
"declaration": true,
"sourceMap": true
},
"include": ["src/**/*.ts"]
}Não mantenha configurações divergentes sem testar ambas.
tsconfig paths
{
"compilerOptions": {
"paths": {
"@app/*": ["./src/*"]
}
}
}import { logger } from '@app/logger';tsx oferece suporte útil a mappings em desenvolvimento. Mas paths não altera o JavaScript emitido pelo TypeScript. Se o build final roda no Node.js sem tsx, o alias pode quebrar.
Para aliases de runtime padrão, use imports no package.json:
{
"imports": {
"#app/*": "./dist/*.js"
}
}Veja Exports e Imports no package.json.
Scripts TypeScript
tsx é útil para tarefas administrativas:
{
"scripts": {
"seed": "tsx scripts/seed.ts",
"migrate": "tsx scripts/migrate.ts",
"generate": "tsx scripts/generate.ts"
}
}Esses scripts precisam de validação, códigos de saída e proteção contra execução no ambiente errado.
Variáveis de ambiente
DATABASE_URL=postgresql://localhost/app npx tsx scripts/migrate.tsPara portabilidade entre Windows e Linux, use cross-env ou carregamento controlado.
O Node.js também possui suporte a arquivos de ambiente em versões atuais:
node --env-file=.env dist/server.jsVerifique como encaminhar flags pelo comando tsx na versão usada. Consulte Variáveis de Ambiente no Node.js.
Encaminhando flags do Node.js
tsx pode ser usado com opções do runtime em diferentes formas, conforme a CLI. Exemplos frequentes incluem:
NODE_OPTIONS="--enable-source-maps" tsx src/server.tsPara flags críticas, valide o comportamento e documente o comando.
Source maps
tsx fornece stacks que apontam para TypeScript:
throw new Error('Falha de teste');Confirme a qualidade dos source maps em erros assíncronos e bibliotecas. Em produção compilada, gere source maps no build e use --enable-source-maps.
Node Test Runner com tsx
Uma forma é importar tsx antes dos testes:
node --import tsx --test "test/**/*.test.ts"Ou usar o binário conforme a versão:
tsx --test "test/**/*.test.ts"No package.json:
{
"scripts": {
"test": "node --import tsx --test",
"test:watch": "node --import tsx --test --watch"
}
}Consulte Node Test Runner.
Separação entre testes e typecheck
{
"scripts": {
"test": "node --import tsx --test",
"typecheck": "tsc --noEmit",
"check": "npm run typecheck && npm test"
}
}Testes verificam comportamento; TypeScript verifica contratos estáticos. Execute ambos.
Debug no VS Code
Uma configuração pode carregar tsx pelo --import:
{
"type": "node",
"request": "launch",
"name": "Debug TypeScript com tsx",
"runtimeArgs": ["--import", "tsx"],
"program": "${workspaceFolder}/src/server.ts",
"console": "integratedTerminal",
"skipFiles": ["<node_internals>/**"]
}A sintaxe depende das versões do Node.js, tsx e extensão de debug. Teste breakpoints e source maps.
REPL e comandos rápidos
Para uma expressão simples:
npx tsx -e "const value: number = 42; console.log(value)"Use apenas com entrada confiável. Nunca concatene dados de usuário em código executado.
stdin
Ferramentas de execução podem aceitar código via stdin, mas esse fluxo aumenta risco de injeção e dificulta auditoria. Prefira arquivos versionados para tarefas de produção.
CommonJS
tsx consegue executar projetos CommonJS e ESM, mas o formato ainda é definido pelas extensões e pelo pacote. Para uma transição gradual:
- mantenha scripts legados em
.cts; - use novos módulos em
.tssobtype: module; - evite misturar
requireeimportsem compreender o output.
Quando usar em produção?
É tecnicamente possível iniciar uma aplicação com:
tsx src/server.tsVantagens:
- sem etapa de build;
- deploy mais simples para scripts pequenos;
- source maps diretos.
Desvantagens:
- transformação no startup;
- dependência de desenvolvimento vira runtime;
- menos validação do artefato final;
- possíveis diferenças em loaders;
- superfície adicional de supply chain.
Para APIs críticas, compilar e executar dist continua sendo uma escolha previsível. Para CLIs internas e automações, tsx em produção pode ser aceitável com versão fixa e testes.
Docker
Desenvolvimento:
CMD ["npm", "run", "dev"]Produção compilada:
RUN npm run build
CMD ["node", "--enable-source-maps", "dist/server.js"]Veja Docker Multi-stage para Node.js.
CI
- run: npm ci
- run: npm run lint
- run: npm run typecheck
- run: npm test
- run: npm run build
- run: node dist/smoke-test.jsMesmo que os testes rodem com tsx, compile e execute pelo menos um smoke test do output real. Consulte CI para Node.js com GitHub Actions.
Performance
tsx é otimizado para startup e transformação rápida, mas compare o tempo no projeto real:
time npx tsx scripts/task.ts
time node dist/scripts/task.jsPara processos longos, a diferença de startup pode ser irrelevante. Para comandos executados milhares de vezes, o build pode ser mais eficiente.
Cache
A ferramenta pode usar cache para acelerar execuções. Em CI e containers, não dependa de cache externo para correção. Quando houver comportamento estranho após atualização, limpe caches e reproduza com instalação limpa.
Segurança
- Fixe a versão no lockfile.
- Não execute arquivos TypeScript recebidos de usuário.
- Não concatene entrada em
-e. - Proteja scripts de migration.
- Use variáveis de ambiente seguras.
- Revise atualizações e dependências.
- Execute CI antes de produção.
tsx versus ts-node
Ambas executam TypeScript, mas possuem implementações e opções diferentes. tsx prioriza uma experiência rápida e simples para ESM moderno. ts-node oferece integração histórica com o compilador TypeScript e modos específicos. Avalie:
- ESM;
- velocidade;
- typecheck;
- plugins do compilador;
- debug;
- compatibilidade com ferramentas.
tsx versus tsc
Não são substitutos diretos:
- tsx: transforma e executa;
- tsc –noEmit: verifica tipos;
- tsc build: gera JavaScript e declarations;
- bundler: empacota e otimiza conforme objetivo.
Um fluxo equilibrado usa tsx para desenvolvimento e scripts, tsc para typecheck e build quando necessário.
Erros comuns
- Não executar tsc: erros de tipo chegam ao CI ou produção.
- Imports .ts no build: JavaScript emitido quebra.
- paths somente no TypeScript: runtime final não resolve.
- Watch em outputs: reinicia em loop.
- Executar código não confiável: permite execução arbitrária.
- Usar devDependency ausente na imagem: startup falha.
- Testar só com tsx: dist nunca é validado.
- Confundir transformação com typecheck: falsa sensação de segurança.
Configuração recomendada
{
"type": "module",
"scripts": {
"dev": "tsx watch src/server.ts",
"typecheck": "tsc --noEmit",
"test": "node --import tsx --test",
"build": "tsc -p tsconfig.build.json",
"start": "node --enable-source-maps dist/server.js",
"check": "npm run typecheck && npm test && npm run build"
},
"devDependencies": {
"tsx": "versão-fixada",
"typescript": "versão-fixada"
}
}Conclusão
O tsx no Node.js oferece uma experiência rápida para executar TypeScript durante desenvolvimento, testes e automações. Watch mode, ESM e integração com o Node Test Runner reduzem configuração e aceleram feedback.
Mantenha tsc --noEmit para tipos e valide o build usado em produção. Quando execução direta, aliases e imports são tratados conscientemente, tsx simplifica o fluxo sem esconder as regras do Node.js nem substituir as garantias do compilador.



