Turborepo na Vercel: A Engenharia por trás dos Monorepos Corporativos
Índice do Manual
Conforme uma startup evolui para uma corporação estabelecida, a complexidade do software se multiplica. O que antes era apenas "um site", rapidamente se transforma em três sistemas distintos:
- O Site Institucional (Marketing).
- O Painel Administrativo (Operação Interna).
- O Aplicativo SaaS (Onde o cliente paga).
O erro fatal de muitas equipes de TI é criar três repositórios de código isolados para esses projetos. O resultado? O botão principal de "Ação" precisa ser programado três vezes. A regra de negócio que calcula o desconto do cliente é copiada e colada três vezes. Quando um bug é consertado no Admin, a equipe esquece de atualizar o App do Cliente.
Esse caos arquitetural é o que chamamos de Dependency Hell (Inferno das Dependências).
[!WARNING] Antes de continuar: Se você é um Solo Founder ou está iniciando um novo SaaS do zero, o Turborepo pode representar uma perigosa Otimização Prematura. Leia primeiro nosso guia definitivo sobre Turborepo vs Next.js Route Groups para descobrir a forma mais ágil de escalar seu projeto no "Dia 1".
A solução adotada por gigantes como Google, Meta e Uber é a arquitetura de Monorepo: colocar todos os softwares da empresa dentro de um único e gigantesco repositório. Para fazer isso no ecossistema JavaScript sem tornar o projeto lento, nós usamos a arma secreta da Vercel: o Turborepo.
1. O Que é o Turborepo?
O Turborepo é um sistema de build (construção de código) de alta performance para Monorepos em JavaScript e TypeScript.
Ele entende a árvore de dependências do seu projeto. Se você tem uma pasta chamada packages/ui contendo o seu Design System (botões, formulários) e tanto o seu apps/admin quanto o seu apps/web consomem esses botões, o Turborepo sabe exatamente quem depende de quem.
A Magia do Cache Distribuído (Remote Caching)
O recurso mais brutal do Turborepo é o Remote Caching. Imagine que a sua equipe tem 10 desenvolvedores. Se um desenvolvedor alterar apenas o código do apps/admin e mandar o código para a nuvem da Vercel, o Turborepo percebe que o apps/web e o packages/ui não foram tocados.
A Vercel pula a etapa de compilação desses dois pacotes e pega o resultado direto do cache. O deploy (que normalmente levaria 15 minutos) cai para 10 segundos. É uma economia massiva de tempo de infraestrutura de CI/CD.
2. Estruturando o Seu Monorepo Corporativo
Vamos ver como fica a organização de pastas de um Monorepo maduro:
meu-monorepo-corporativo/
├── apps/
│ ├── admin/ (Painel Interno - Next.js)
│ ├── web/ (Site Público - Next.js)
│ └── api/ (Backend Node.js/Edge)
├── packages/
│ ├── ui/ (Design System em React compartilhado)
│ ├── config/ (Regras de ESLint e TSConfig padrão)
│ └── database/ (Schema do Prisma ORM compartilhado)
├── turbo.json (O Cérebro do Turborepo)
└── package.json
Com essa estrutura, se você alterar a cor principal de um botão dentro de packages/ui, o site público e o painel administrativo recebem a nova cor automaticamente. Fim da duplicação de código.
Reflexo na Infraestrutura (Vercel e Domínios)
É vital entender que, ao contrário dos Route Groups, um Monorepo gera múltiplos projetos separados na nuvem:
- Projetos Vercel: Você criará 3 projetos distintos no painel da Vercel (
saas-web,saas-admin,saas-api), mas todos eles estarão apontando para o mesmo repositório do Github (apenas configurados para olhar para o seu respectivo "Root Directory" dentro deapps/). - Domínios Separados: Como são projetos Vercel isolados, eles devem rodar em URLs separadas (ex:
seu-saas.compara a Web,app.seu-saas.compara o Dashboard,admin.seu-saas.compara o Painel Interno). - Deploy Independente: Se você alterar apenas um texto no Site Público, o Turborepo avisará a Vercel para fazer o deploy apenas do
apps/web. Os outros dois projetos ignoram a atualização, poupando CPU e evitando quedas acidentais do sistema.
3. Mão no Código: Configuração de Alto Nível
Para orquestrar essa máquina, o arquivo turbo.json dita as regras de paralelismo e dependência. Veja um exemplo de Clean Configuration:
// turbo.json na raiz do projeto
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
// O build só acontece se os pacotes dependentes
// (ex: packages/ui) forem compilados antes (^build).
"dependsOn": ["^build"],
// O Turborepo guarda as pastas geradas no cache.
// Se o código não mudar, ele reaproveita essas pastas.
"outputs": [".next/**", "!.next/cache/**", "dist/**"]
},
"lint": {
// Tarefa de checagem de erros de código.
"dependsOn": ["^lint"]
},
"dev": {
// O modo de desenvolvimento não usa cache agressivo,
// ele roda eternamente ouvindo alterações.
"cache": false,
"persistent": true
}
}
}
E no package.json raiz, nós ativamos os Workspaces (suportados nativamente pelo NPM, PNPM ou Yarn) para conectar as pastas invisivelmente:
// package.json na raiz do projeto
{
"name": "empresa-monorepo",
"private": true,
"workspaces": [
"apps/*",
"packages/*"
],
"scripts": {
"build": "turbo run build",
"dev": "turbo run dev",
"lint": "turbo run lint"
}
}
Orquestração Perfeita
Quando você roda o comando npm run build na raiz do projeto, o Turborepo não compila um app por vez de forma linear. Ele analisa o grafo de dependências e compila tudo em paralelo usando o máximo de núcleos de CPU disponíveis na sua máquina ou no servidor, respeitando a ordem obrigatória (ex: compila o Banco de Dados e o UI System antes de compilar os Apps que dependem deles).
A Arte de Centralizar Inteligência
Construir múltiplos repositórios é o caminho dos amadores; é a fórmula perfeita para gerar retrabalho. O padrão ouro do desenvolvimento SaaS moderno é centralizar a inteligência e descentralizar as interfaces.