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

npm Workspaces no Node.js

Atualizado em: 23 de setembro de 2026

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

O recurso npm Workspaces permite administrar vários pacotes Node.js dentro de um único repositório, com instalação centralizada, links locais automáticos e comandos executados por pacote ou em todo o monorepo. Ele reduz a necessidade de usar npm link manualmente e ajuda equipes a manter bibliotecas, serviços e aplicações relacionadas no mesmo projeto.

Um workspace é um pacote com seu próprio package.json localizado abaixo de um pacote raiz. O arquivo raiz lista quais diretórios fazem parte do conjunto. Durante npm install, o npm reconhece esses pacotes e cria os links necessários em node_modules.

Estrutura básica de um monorepo

Uma estrutura simples pode separar aplicações e bibliotecas reutilizáveis:

meu-projeto/
├── package.json
├── package-lock.json
├── apps/
│   ├── api/
│   │   └── package.json
│   └── worker/
│       └── package.json
└── packages/
    ├── config/
    │   └── package.json
    └── logger/
        └── package.json

No package.json raiz, declare padrões ou caminhos explícitos:

{
  "name": "plataforma",
  "private": true,
  "workspaces": [
    "apps/*",
    "packages/*"
  ]
}

O campo private evita publicar acidentalmente o pacote raiz. Cada workspace continua podendo ser publicado separadamente, desde que sua configuração permita.

Criando workspaces com npm init

É possível criar a estrutura manualmente ou usar o comando:

npm init -w ./packages/logger
npm init -w ./apps/api

O npm cria os diretórios, gera o package.json e atualiza a lista de workspaces do projeto raiz quando necessário.

Defina nomes únicos nos pacotes internos. Pacotes privados podem usar um escopo da organização:

{
  "name": "@empresa/logger",
  "version": "1.0.0",
  "type": "module",
  "private": true
}

Instalação centralizada

Execute npm install na raiz. O npm gera um único package-lock.json para todo o monorepo e organiza dependências compartilhadas. Quando dois workspaces precisam da mesma versão de uma biblioteca, ela geralmente pode ser instalada no nível superior. Dependências incompatíveis ainda podem aparecer em níveis específicos.

Esse comportamento reduz duplicação, mas não significa que qualquer pacote possa usar dependências não declaradas. Cada workspace deve listar explicitamente o que importa. Caso contrário, o código pode funcionar localmente por causa do hoisting e falhar quando o pacote for publicado ou instalado isoladamente.

Adicionando dependências a um workspace

Use -w ou --workspace para escolher o destino:

npm install fastify -w @empresa/api
npm install pino -w @empresa/logger
npm install -D typescript -w @empresa/api

O npm altera o package.json do workspace selecionado, não o arquivo raiz.

Também é possível adicionar um workspace como dependência de outro:

npm install @empresa/logger -w @empresa/api

Como o pacote existe localmente, o npm cria um link em vez de baixá-lo do registro. A dependência ainda recebe um intervalo de versão normal no package.json, o que é importante para publicação e versionamento.

Executando scripts em um pacote

Para executar um script em um workspace específico:

npm run test --workspace=@empresa/api
npm run build -w @empresa/logger

Para executar em todos:

npm run test --workspaces
npm run lint --workspaces --if-present

--if-present ignora pacotes que não possuem o script. Sem essa opção, a ausência pode interromper o comando.

A ordem segue a sequência declarada no campo workspaces. Isso não substitui um grafo de dependências. Se o pacote B depende do pacote A, não confie apenas na ordem da lista; crie scripts explícitos ou use uma ferramenta de orquestração quando o projeto exigir execução topológica e cache.

Scripts úteis na raiz

Centralize tarefas comuns:

{
  "scripts": {
    "test": "npm run test --workspaces --if-present",
    "lint": "npm run lint --workspaces --if-present",
    "build": "npm run build --workspaces --if-present",
    "dev:api": "npm run dev -w @empresa/api",
    "dev:worker": "npm run dev -w @empresa/worker"
  }
}

Isso oferece uma interface única para desenvolvedores e para o CI.

Versionamento de pacotes

Existem duas estratégias principais. No versionamento fixo, todos os pacotes compartilham a mesma versão e são publicados juntos. No independente, cada pacote evolui separadamente.

O npm Workspaces fornece a estrutura, mas não administra changelogs e versões complexas sozinho. Para bibliotecas publicadas, combine-o com Changesets ou outra ferramenta de release. Em aplicações privadas, versões podem servir apenas para expressar compatibilidade interna.

Sempre atualize dependências internas quando houver mudança incompatível. Um pacote que depende de @empresa/logger deve declarar uma faixa coerente com a versão realmente testada.

package-lock.json e npm ci

Mantenha o lockfile raiz no controle de versão. Em CI, use:

npm ci

O comando instala exatamente as versões registradas e falha se package.json e package-lock.json estiverem inconsistentes.

Evite executar instalações independentes dentro de cada workspace, pois isso pode gerar lockfiles concorrentes e ambientes diferentes. O fluxo padrão deve começar na raiz.

Imports entre pacotes

Importe pelo nome declarado no pacote, não por caminhos relativos que atravessam diretórios:

import { logger } from '@empresa/logger';

Evite:

import { logger } from '../../../packages/logger/src/index.js';

O primeiro formato respeita a API pública e se comporta como ocorrerá após a publicação. O segundo cria acoplamento à estrutura do repositório.

Defina corretamente exports e types no pacote interno para que Node.js, TypeScript e editores resolvam os arquivos certos.

TypeScript em workspaces

Uma configuração compartilhada pode ficar em packages/config ou na raiz. Cada pacote estende essa base:

{
  "extends": "../../tsconfig.base.json",
  "compilerOptions": {
    "outDir": "dist",
    "rootDir": "src"
  },
  "include": ["src"]
}

Não use aliases TypeScript como substitutos de dependências reais. Um alias pode funcionar durante a compilação, mas não existir na resolução do Node.js. Prefira nomes de pacotes e mapas de exports.

Testes e isolamento

Cada workspace deve ter testes próprios. Além disso, execute testes de integração envolvendo vários pacotes. Um bom pipeline inclui:

  • instalação com npm ci;
  • lint em todos os workspaces;
  • build das bibliotecas antes das aplicações dependentes;
  • testes unitários por pacote;
  • testes de integração do conjunto;
  • npm pack para validar pacotes publicáveis.

Docker e workspaces

Ao criar uma imagem, copie primeiro os manifestos e o lockfile para aproveitar cache:

FROM node:24-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
COPY apps/api/package.json apps/api/package.json
COPY packages/logger/package.json packages/logger/package.json
RUN npm ci

FROM deps AS build
COPY . .
RUN npm run build --workspaces --if-present

Uma cópia incompleta dos manifestos pode fazer o npm ignorar workspaces ou invalidar o lockfile. Inclua todos os package.json necessários antes de instalar.

Boas práticas de segurança

Use npm audit, atualize dependências e não armazene tokens em arquivos versionados. Pacotes privados devem ter configuração de acesso explícita. Em CI, prefira OIDC ou tokens de escopo reduzido.

Revise scripts preinstall, postinstall e dependências transitivas. Um monorepo centraliza dependências, mas também amplia o impacto de uma alteração maliciosa ou quebrada.

Quando npm Workspaces é suficiente

Para monorepos pequenos e médios, o recurso nativo costuma bastar. Ele resolve links locais, instalação, lockfile e execução de comandos. Projetos grandes podem adicionar ferramentas para cache remoto, análise de dependências e execução incremental, sem abandonar o npm como gerenciador.

O ponto principal é manter limites claros entre pacotes. Combine workspaces com Exports e Imports no Node.js, pipelines de GitHub Actions no Node.js, imagens com GitHub Container Registry e segurança de dependências descrita em Segurança de Dependências no Node.js.

Consulte a documentação oficial de npm Workspaces e a referência oficial do npm run-script.

10 melhores cursos de programação em 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