SWC, sigla de Speedy Web Compiler, é uma plataforma escrita em Rust para transformar JavaScript e TypeScript. Em projetos Node.js, ela pode substituir partes de pipelines baseados em Babel ou no emissor do TypeScript quando a prioridade é compilar rapidamente, gerar source maps, converter sintaxe moderna e produzir CommonJS ou ESM.
SWC não substitui automaticamente a verificação de tipos. Assim como outras ferramentas de transformação rápida, ele remove anotações TypeScript e gera JavaScript. O projeto ainda precisa executar tsc --noEmit ou outra verificação equivalente.
Instalação
npm install -D @swc/core @swc/cli typescript@swc/core fornece o compilador e bindings nativos. @swc/cli adiciona o comando swc.
Adicione scripts:
{
"scripts": {
"typecheck": "tsc --noEmit",
"build": "swc src -d dist --strip-leading-paths",
"build:watch": "swc src -d dist --watch"
}
}Configuração .swcrc
Crie .swcrc:
{
"$schema": "https://swc.rs/schema.json",
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": false,
"decorators": false,
"dynamicImport": true
},
"target": "es2022",
"keepClassNames": true
},
"module": {
"type": "es6"
},
"sourceMaps": true
}O parser precisa corresponder ao código. Para JavaScript com JSX, use syntax: ecmascript e jsx: true. Para TSX, mantenha typescript e ative tsx.
Escolhendo o target
jsc.target define a sintaxe de saída. Se a aplicação roda apenas em Node.js moderno, não é necessário converter tudo para ES5. Um target próximo à versão suportada produz código menor e mais legível.
Documente a versão mínima do Node.js e alinhe:
- imagem Docker;
- CI;
- campo
engines; - target do SWC;
- bibliotecas nativas.
Gerando ESM
Para módulos ES:
{
"module": {
"type": "es6"
}
}No package.json:
{
"type": "module",
"main": "./dist/index.js"
}Imports relativos em ESM precisam respeitar as regras do Node.js. Dependendo da estrutura, extensões devem aparecer no código final. Teste a saída executando diretamente com Node, não apenas dentro da ferramenta de desenvolvimento.
Gerando CommonJS
Para aplicações legadas:
{
"module": {
"type": "commonjs",
"strict": true,
"noInterop": false
}
}O package.json pode usar type: commonjs ou omitir type. Evite colocar JavaScript CommonJS dentro de um pacote marcado como ESM sem usar extensão .cjs.
Build de TypeScript
Uma estrutura:
src/
├── server.ts
├── config.ts
└── routes/
└── users.ts
Execute:
npx swc src -d dist --strip-leading-pathsValide:
node dist/server.jsInclua arquivos não compilados, como templates e schemas, por uma etapa de cópia explícita.
Source maps
Ative sourceMaps: true para mapear stack traces ao TypeScript original. No runtime:
node --enable-source-maps dist/server.jsSource maps podem conter caminhos e trechos do código. Defina se serão incluídos na imagem, enviados ao serviço de observabilidade ou mantidos separados.
Verificação de tipos separada
Configure um tsconfig.json sem emissão:
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"strict": true,
"noEmit": true,
"skipLibCheck": true
},
"include": ["src", "test"]
}No CI, execute typecheck antes ou em paralelo ao build. Nunca considere uma compilação SWC bem-sucedida como prova de correção de tipos.
Minificação
SWC pode minificar:
{
"minify": true,
"jsc": {
"minify": {
"compress": true,
"mangle": true
}
}
}Em servidores Node.js, minificar raramente é necessário. Pode piorar stack traces, dificultar diagnósticos e trazer pouco ganho. Use principalmente em artefatos enviados ao navegador ou funções em que tamanho afeta implantação.
Decorators
Frameworks podem depender de decorators e metadata:
{
"jsc": {
"parser": {
"syntax": "typescript",
"decorators": true
},
"transform": {
"legacyDecorator": true,
"decoratorMetadata": true
}
}
}Essas opções devem corresponder ao comportamento esperado pelo framework e pelo TypeScript. Decorators legados e o padrão moderno não são equivalentes.
Aliases de caminho
SWC pode transformar aliases com configuração adicional, mas o Node.js precisa resolver o caminho gerado. Não basta o editor aceitar @app/config. Prefira:
- imports do
package.jsoniniciados por#; - workspaces para pacotes internos;
- imports relativos simples;
- um bundler que resolva os aliases.
API programática
import { transform } from '@swc/core';
const resultado = await transform(codigo, {
filename: 'arquivo.ts',
jsc: {
parser: {
syntax: 'typescript',
},
target: 'es2022',
},
module: {
type: 'es6',
},
sourceMaps: true,
});
console.log(resultado.code);A API é útil em ferramentas próprias, geração de código e pipelines especializados. Para builds comuns, prefira CLI ou integração mantida pelo framework.
Watch mode
npx swc src -d dist --watchEm outro processo:
node --watch --enable-source-maps dist/server.jsUma ferramenta como concurrently pode executar os dois. Para desenvolvimento mais simples, tsx pode oferecer menos configuração.
SWC com Jest
Projetos que usam Jest podem adotar @swc/jest:
npm install -D jest @swc/jestexport default {
transform: {
'^.+\\.(t|j)sx?$': ['@swc/jest'],
},
};Confirme cobertura, source maps, decorators e formato de módulos. Uma transformação rápida não corrige incompatibilidades entre Jest ESM e CommonJS.
SWC em frameworks
Frameworks como Next.js e ferramentas de build podem usar SWC internamente. Quando a integração já existe, evite adicionar uma segunda etapa manual sem necessidade. Configure pela interface do framework para preservar cache, plugins e compatibilidade.
Plugins
SWC suporta extensões, inclusive plugins baseados em WebAssembly em determinados fluxos. Plugins executam transformações profundas no AST e precisam ser versionados com cuidado. Verifique compatibilidade entre a versão do plugin e @swc/core.
Cache
A compilação já é rápida, mas monorepos grandes se beneficiam de cache por conteúdo. Uma ferramenta de tarefas pode armazenar dist com base em:
- fontes;
.swcrc;- lockfile;
- versão do Node;
- versão do SWC;
- variáveis que afetam o build.
Docker multi-stage
FROM node:24-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run typecheck && npm run build
FROM node:24-alpine AS runtime
WORKDIR /app
ENV NODE_ENV=production
COPY package*.json ./
RUN npm ci --omit=dev
COPY --from=build /app/dist ./dist
CMD ["node", "--enable-source-maps", "dist/server.js"]A imagem final não precisa de SWC nem TypeScript.
Bindings nativos e plataformas
@swc/core usa binários específicos por plataforma. Problemas podem surgir em Alpine, arquiteturas ARM ou ambientes que bloqueiam pacotes opcionais. Instale no mesmo sistema operacional do build e não copie node_modules do Windows para Linux.
SWC ou tsc
Use tsc quando emissão de declarações, referências de projeto e fidelidade ao compilador forem centrais. Use SWC quando transformação rápida e integração de build forem prioritárias. Um fluxo híbrido é comum:
tsc --noEmit
swc src -d distSWC ou esbuild
SWC é uma plataforma de compilação e transformação. esbuild combina transformação e bundling. Se o objetivo é empacotar dependências em um único arquivo, esbuild pode ser mais direto. Se o objetivo é substituir Babel e manter arquivos separados, SWC pode se encaixar melhor.
Segurança
Fixe versões no lockfile, revise plugins e atualizações de bindings. O compilador processa todo o código-fonte e pode executar plugins. Gere artefatos em CI confiável e assine imagens quando necessário.
Fluxo recomendado
Defina target e módulos de acordo com o runtime, mantenha typecheck separado, habilite source maps, teste a saída com Node puro e use Docker multi-stage. Combine SWC com tsx no Node.js no desenvolvimento, ESLint Flat Config, Exports e Imports no Node.js e pipelines de GitHub Container Registry.
Consulte o repositório oficial do SWC e a documentação oficial do compilador TypeScript.




