Kubo
Montar stack

Estrutura do projeto

Entendendo a estrutura dos projetos criados pela CLI kubojs

Visão geral

A CLI kubojs gera um monorepo com apps/* e packages/*. packages/config está sempre presente; outros packages e apps aparecem conforme suas escolhas (frontend, backend, API, database/ORM, auth, addons, runtime, deploy). Esta página espelha o que a CLI realmente grava.

Layout da raiz

Na raiz do repositório você verá:

package.json
bts.jsonc
turbo.json
nx.json
pnpm-workspace.yaml
bunfig.toml
.npmrc
README.md

Observações:

  • bts.jsonc permite que a CLI detecte e aprimore o projeto depois; mantenha-o se planejar usar kubojs add.
  • turbo.json existe apenas se você escolheu o addon Turborepo.
  • nx.json existe apenas se você escolheu o addon Nx.
  • pnpm-workspace.yaml, bunfig.toml e .npmrc são adicionados conforme o gerenciador de pacotes escolhido.
  • packages/infra é criado somente quando o deploy Cloudflare está habilitado.

Estrutura do monorepo por backend

Backends de server (hono, express, fastify, elysia)

Observações:

  • apps/desktop é criado apenas com o addon Electrobun.
  • apps/docs é criado apenas com o addon Starlight.
  • apps/fumadocs é criado apenas com o addon Fumadocs.

Backend self (fullstack)

Quando --backend self é usado, as rotas de API ficam dentro de apps/web (sem apps/server).

Backend Convex

Estrutura do frontend (apps/web)

A estrutura varia conforme o framework. Itens marcados com "(auth)" ou "(API)" aparecem somente quando essas opções estão habilitadas.

React com TanStack Router

header.tsx
loader.tsx
mode-toggle.tsx
theme-provider.tsx
main.tsx
index.css
index.html
components.json
tsconfig.json
vite.config.ts
package.json

Next.js

components.json
next.config.ts
postcss.config.mjs
tsconfig.json
package.json

Observações:

  • Se você escolher --backend self com Next.js, TanStack Start, Nuxt, SvelteKit ou Astro, as rotas de API ficam dentro de apps/web (sem apps/server).
  • (auth) adiciona src/app/login/* e src/app/dashboard/* mais componentes de sign-in.

Customização da UI React

Apps web React (tanstack-router, react-router, tanstack-start e next) compartilham primitivos shadcn/ui via packages/ui.

  • Altere design tokens e estilos globais em packages/ui/src/styles/globals.css
  • Atualize primitivos compartilhados em packages/ui/src/components/*
  • Ajuste aliases ou config de estilo do shadcn em packages/ui/components.json e apps/web/components.json

Adicionar mais componentes compartilhados

Rode isto na raiz do projeto para adicionar mais primitivos ao package de UI compartilhado:

npx shadcn@latest add accordion dialog popover sheet table -c packages/ui

Importe componentes compartilhados assim:

import { Button } from "@your-project/ui/components/button";

Adicionar blocks específicos do app

Se quiser adicionar blocks shadcn específicos do app em vez de primitivos compartilhados, rode a CLI do shadcn a partir de apps/web.

Estrutura do backend (apps/server)

A estrutura do server depende da escolha de backend:

Backend Hono

index.ts
package.json
tsconfig.json

Express / Fastify / Elysia

index.ts
package.json
tsconfig.json

Runtime workers (opcional)

Quando runtime=workers, o server mira Cloudflare Workers. Se também escolher deploy Cloudflare, você terá packages/infra/alchemy.run.ts e arquivos de infra relacionados.

Scaffold de API e auth (condicional):

  • API=trpc: src/lib/trpc.ts, src/lib/context.ts
  • API=orpc: src/lib/orpc.ts, src/lib/context.ts
  • Auth: src/lib/auth.ts

Configuração de banco de dados

Adicionada somente quando você selecionou um banco e um ORM:

Drizzle ORM

drizzle.config.ts

Prisma ORM

schema.prisma

Mongoose (MongoDB)

Auth + DB

Se você selecionou auth, arquivos adicionais são incluídos para o seu ORM:

  • Drizzle: src/db/schema/auth.ts
  • Prisma: prisma/schema/auth.prisma
  • Mongoose: src/db/models/auth.model.ts

Docker compose (opcional)

Se dbSetup=docker, um docker-compose.yml é adicionado em apps/server/ para o seu banco.

Estrutura do app native (apps/native)

Criado somente quando você inclui React Native (NativeWind ou Unistyles):

_layout.tsx
index.tsx
app.json
package.json
tsconfig.json

Se uma API for selecionada, um utilitário de cliente é adicionado:

  • API=trpc: utils/trpc.ts
  • API=orpc: utils/orpc.ts

Estrutura da documentação

Starlight (apps/docs)

astro.config.mjs
package.json
tsconfig.json

Fumadocs (apps/fumadocs)

O Fumadocs é gerado por create-fumadocs-app dentro de apps/fumadocs. A estrutura exata depende do template escolhido (MDX vs static).

Electrobun (apps/desktop)

O Electrobun adiciona um workspace apps/desktop com seu próprio package.json, electrobun.config.ts e src/bun/index.ts. O shell desktop reutiliza apps/web no desenvolvimento e empacota a saída estática buildada para releases. Use um backend separado ou nenhum backend para apps desktop; --backend self emite rotas de server dentro de apps/web e não pode ser empacotado como assets estáticos de desktop.

Arquivos de configuração

Config kubojs (bts.jsonc)

{
  "$schema": "https://r2.kubojs.dev/schema.json",
  "version": "<cli-version>",
  "createdAt": "<timestamp>",
  "database": "<none|sqlite|postgres|mysql|mongodb>",
  "orm": "<none|drizzle|prisma|mongoose>",
  "backend": "<none|hono|express|fastify|elysia|convex|self>",
  "runtime": "<bun|node|workers|none>",
  "frontend": ["<tanstack-router|react-router|tanstack-start|next|nuxt|svelte|solid|astro|native-bare|native-uniwind|native-unistyles|none>"] ,
  "addons": ["<pwa|tauri|electrobun|starlight|fumadocs|biome|lefthook|husky|mcp|turborepo|nx|vite-plus|ultracite|oxlint|opentui|wxt|skills|evlog|none>"] ,
  "examples": ["<ai|todo|none>"] ,
  "auth": <"better-auth"|"clerk"|"none">,
  "packageManager": "<bun|pnpm|npm>",
  "dbSetup": "<turso|neon|prisma-postgres|planetscale|mongodb-atlas|supabase|d1|docker|none>",
  "api": "<none|trpc|orpc>",
  "webDeploy": "<cloudflare|docker|vercel|none>",
  "serverDeploy": "<cloudflare|docker|vercel|none>"
}

Config Turborepo (turbo.json)

Gerado somente se você escolheu o addon Turborepo.

{
  "$schema": "https://turbo.build/schema.json",
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**", ".next/**", "!.next/cache/**"]
    },
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

Config Nx (nx.json)

Gerado somente se você escolheu o addon Nx.

Config Vite+

Frontends Vite gerados importam defineConfig de vite-plus quando você escolhe o addon Vite+. Um vite.config.ts na raiz centraliza lint, format e checks de arquivos staged do Vite+, enquanto os scripts do workspace na raiz usam vp run para orquestração de tasks.

Quando o Vite+ é selecionado sem Husky ou Lefthook, os projetos gerados também incluem hooks:setup para hooks Git nativos opcionais do Vite+. Rode-o se quiser que vp config instale hooks em .vite-hooks e use vp staged a partir de vite.config.ts; veja o guia de commit hooks do Vite+.

import { defineConfig } from "vite-plus";

export default defineConfig({
  lint: {
    options: {
      typeAware: false,
      typeCheck: false,
    },
  },
  fmt: {
    sortPackageJson: true,
  },
  staged: {
    "*.{js,ts,jsx,tsx,vue,svelte,json,jsonc,css,md}": "vp check --fix",
  },
});

Packages compartilhados

O kubojs sempre cria packages/config. Outros packages são adicionados conforme suas seleções:

  • packages/env: quando qualquer frontend é selecionado ou o backend não é none
  • packages/api: quando --api não é none (não-Convex)
  • packages/auth: quando --auth não é none (não-Convex)
  • packages/db: quando --database e --orm são selecionados (não-Convex)
  • packages/backend: somente backend Convex
  • packages/infra: somente deploy Cloudflare

Scripts de desenvolvimento

Os scripts são ajustados conforme o gerenciador de pacotes e se o addon Turborepo, Nx ou Vite+ está selecionado.

Com Turborepo:

{
  "scripts": {
    "dev": "turbo run dev",
    "build": "turbo run build",
    "check-types": "turbo run check-types",
    "dev:web": "turbo run dev -F web",
    "dev:server": "turbo run dev -F server",
    "db:push": "turbo run db:push -F server",
    "db:studio": "turbo run db:studio -F server"
  }
}

Com Nx:

{
  "scripts": {
    "dev": "nx run-many -t dev",
    "build": "nx run-many -t build",
    "check-types": "nx run-many -t check-types",
    "dev:web": "nx run-many -t dev --projects=web",
    "dev:server": "nx run-many -t dev --projects=server"
  }
}

Com Vite+:

{
  "scripts": {
    "dev": "vp run -r dev",
    "build": "vp run -r build",
    "check-types": "vp run -r check-types",
    "check": "vp check && vp run -r check-types",
    "lint": "vp lint",
    "format": "vp fmt",
    "staged": "vp staged",
    "dev:web": "vp run --filter web dev",
    "dev:server": "vp run --filter server dev"
  }
}

Sem Turborepo, Nx ou Vite+ (exemplo para Bun):

{
  "scripts": {
    "dev": "bun run --filter '*' dev",
    "build": "bun run --filter '*' build",
    "check-types": "bun run --filter '*' check-types",
    "dev:web": "bun run --filter web dev",
    "dev:server": "bun run --filter server dev"
  }
}

Observações:

  • Convex adiciona dev:setup para a configuração inicial do backend.
  • Scripts de banco (db:*) são adicionados somente quando database + ORM estão selecionados (Drizzle/Prisma). D1 + Cloudflare omite db:push e db:studio.

Detalhes importantes

  • Monorepo: apps/* e packages/* são criados somente quando relevantes (exceto packages/config, que está sempre presente)
  • Base web React: arquivos específicos do app ficam em apps/web, enquanto primitivos shadcn/ui compartilhados vivem em packages/ui
  • Clientes de API: src/utils/trpc.ts ou src/utils/orpc.ts adicionados a web/native quando selecionados
  • Auth: adiciona setup de autenticação conforme o provider:
    • better-auth: src/lib/auth.ts no server e páginas de login/dashboard no app web
    • clerk: setup do provider Clerk e componentes de autenticação
  • ORM/DB: arquivos Drizzle/Prisma/Mongoose adicionados somente quando selecionados
  • Extras: pnpm-workspace.yaml, bunfig.toml ou .npmrc adicionados conforme o gerenciador de pacotes e as escolhas
  • Deploy: deploy Cloudflare adiciona packages/infra/alchemy.run.ts e arquivos de infra relacionados

Isto reflete os arquivos realmente gravados pela CLI, para que novos projetos batam com o que está documentado aqui.