5 apps num único repositório - o monorepo Turborepo de um dev solo
Como montar um monorepo Turborepo para gerenciar vários apps e sites num único repositório. Compartilhamento de configurações, economia de build com cache e deploy por app, tudo do ponto de vista prático.
Resumo
Quando você cria vários apps sozinho, as configurações se espalham. Com um monorepo Turborepo, eslint e tsconfig ficam compartilhados em packages, o cache do turbo evita rebuildar apps que não mudaram, e o --filter permite deploy por app.
Nesta página
Quando você cria apps sozinho, os repositórios se multiplicam sem parar. Um app, um site, mais um app... e lá está você copiando e colando a configuração do eslint pela quinta vez. Eu juntei tudo isso num único monorepo.
O problema de verdade são as configurações espalhadas
Com muitos repositórios, o que mais dói não é o código, são as configurações.
- Copiar eslint, prettier e tsconfig para cada repositório
- Mudar uma regra significa percorrer todos eles corrigindo
- UI e utils compartilhados são pequenos demais para publicar no npm
O monorepo transforma isso em compartilhamento num único lugar.
Estrutura básica
apps/
├── web/ # 랜딩
├── blog/ # 이 블로그
├── wave/ # 오늘의 파도
└── ...
packages/
├── eslint-config/ # 공용 eslint
└── typescript-config/ # 공용 tsconfig
apps/* são os artefatos de deploy reais, e packages/* são as configurações e o código que os apps compartilham. O tsconfig.json de cada app só herda, assim:
{ "extends": "@repo/typescript-config/nextjs.json" }
Agora as regras são corrigidas num único lugar: packages.
O cache do turbo é o ponto-chave
A verdadeira arma do Turborepo é o cache. Se as entradas de uma tarefa (fontes e configurações) não mudaram, o resultado anterior é reutilizado como está.
turbo run build # 전체 빌드(바뀐 것만 실제로 돎)
turbo run build --filter=blog # blog 앱만
Basta declarar as dependências entre tarefas e as saídas no turbo.json.
{
"tasks": {
"build": { "dependsOn": ["^build"], "outputs": [".next/**"] }
}
}
A partir do segundo build, ele termina em poucos segundos com "FULL TURBO".
Deploy por app
Mesmo num único repositório, o deploy fica separado por app. Com Docker, o turbo prune recorta apenas a subárvore daquele app, deixando a imagem leve.
turbo prune blog --docker # blog + 내부 의존성만 남긴 out/ 생성
Este blog também foi recortado assim e subiu com Docker num mini PC. Essa história eu conto no post sobre self-hosting.
Resumo
apps/*= artefatos de deploy,packages/*= configurações compartilhadas- tsconfig e eslint gerenciados num único lugar via herança
- O cache do
turboevita rebuildar apps que não mudaram - Deploy por app com
--filtereprune
Se você toca vários produtos sozinho, o monorepo não é luxo, é ferramenta de sobrevivência.
Perguntas frequentes
A partir de quantos apps o monorepo compensa?
Já com mais de 2 apps, se surgem configurações compartilhadas (eslint, tsconfig, UI), compensa. O ponto central é corrigir a configuração num único lugar e refletir em todos os apps.
O build não fica mais lento?
Pelo contrário, fica mais rápido. O turbo faz cache do resultado das tarefas cujas entradas não mudaram e só rebuilda os apps que mudaram.
Artigos relacionados
- 💻 Dev
Criando um blog MDX do zero com Next.js - como este blog foi feito
O processo de criar um blog que roda só com arquivos markdown, sem CMS, usando o App Router do Next.js 16. Estrutura de pastas, configuração do MDX e SEO, tudo organizado com o fluxo de código real.
- 💻 Dev
Self-hosting num mini PC com Docker + Cloudflare Tunnel
Como expor vários serviços web com segurança usando um único mini PC em casa. HTTPS via Cloudflare Tunnel sem abrir portas, e tudo rodando com Docker Compose.
- ☕ Dia a dia
A rotina diária de um dev solo - como não se esgotar trabalhando sozinho
Trabalhar sozinho, sem chefe nem colegas, dá liberdade, mas cansa rápido. Organizei a rotina diária e algumas regras que sigo para não perder o ritmo.