Template React Enterprise-Grade focado em Escalabilidade, Modularidade e AI-Native DX
- ⚡ Tech Stack & Diferenciais
- 🤖 O Gerador de Código (Killer Feature)
- 🏗️ Arquitetura e Padrões
- 🚀 Getting Started
- 📊 Fluxo de Dados
| Categoria | Tecnologia | Versão | Propósito |
|---|---|---|---|
| Framework | React | 19.2.0 | UI Library |
| Build Tool | Vite | 7.2.4 | Build System & Dev Server |
| Language | TypeScript | 5.9.3 | Type Safety |
| Styling | Tailwind CSS | v4 | Utility-First CSS |
| UI Components | Shadcn/UI | Latest | Component Library |
| Routing | TanStack Router | 1.154.6 | File-based Routing |
| Data Fetching | TanStack Query | 5.90.19 | Server State Management |
| Forms | React Hook Form + Zod | Latest | Form Validation |
| Testing | Vitest | 4.0.17 | Unit Testing |
Separação estrita entre Roteamento (src/app/) e Regras de Negócio (src/modules/):
src/app/: Apenas definições de rota e loaders (magros)src/modules/: Toda a lógica de negócio isolada por domínio- Zero acoplamento entre rotas e módulos
- Router: File-based routing com TypeScript end-to-end
- Query v5: Server state management com cache inteligente
- Integração nativa: Loaders pré-carregam dados via
ensureQueryData
- Configuração via
@themeno CSS (semtailwind.config.jscomplexo) - Sistema de tokens semânticos para Dark/Light Mode automático
- Zero configuração manual de cores hardcoded
- Projeto configurado com
.cursor/rulespara garantir consistência - Padrões arquiteturais documentados para assistência por IA
- Naming conventions estritas (Interfaces:
I*, Types:T*)
Este projeto possui um CLI poderoso que gera módulos CRUD completos em segundos, seguindo todos os padrões arquiteturais do projeto.
npm run gen:module -- --name=client --pt=clientesParâmetros:
--name: Nome do módulo em kebabCase (ex:client,userProfile)--pt: Label em português para exibição (ex:clientes,perfil-usuario)
O comando cria uma estrutura completa e funcional:
src/modules/client/
├── components/ # Formulários e componentes visuais
│ └── client-form.tsx
├── create/ # Lógica e View de Criação
│ ├── client-create.tsx
│ ├── schema.ts # Validação Zod
│ └── use-client-create.ts # Hook de criação
├── update/ # Lógica e View de Edição
│ ├── client-update.tsx
│ ├── schema.ts
│ └── use-client-update.ts
├── list/ # Listagem com DataTable
│ ├── columns.tsx # Definição de colunas (TanStack Table)
│ ├── client-list.tsx
│ ├── client-list-skeleton.tsx
│ └── use-client-list.ts
├── http/ # Camada de Rede
│ ├── api/ # Chamadas Axios puras (sem hooks)
│ │ └── index.ts
│ ├── mutations/ # Hooks de Mutação (Create/Update/Delete/Toggle)
│ │ ├── use-client-create.ts
│ │ ├── use-client-update.ts
│ │ ├── use-client-delete.ts
│ │ └── use-client-toggle-status.ts
│ └── queries/ # Query Options (Factory Pattern)
│ └── index.ts
└── _app-routes/ # Arquivos de rota (TanStack Router)
├── index.tsx # Listagem
├── criar.tsx # Criação
└── $client_id.tsx # Detalhe/Edição
- ✅ CRUD Completo: Create, Read, Update, Delete
- ✅ Listagem Paginada: Com busca, filtros e ordenação
- ✅ Validação de Formulários: Schemas Zod prontos
- ✅ Type Safety: TypeScript end-to-end
- ✅ Loading States: Skeletons e pending components
- ✅ Error Handling: Tratamento de erros padronizado
- ✅ Rotas Integradas: File-based routing configurado
O projeto segue um pipeline estrito para busca de dados:
Service (API) → Query Options → Loader → Component
Funções assíncronas puras que executam chamadas HTTP:
// modules/client/http/api/index.ts
export const clientApi = {
list: async (params: TGenericListSchema) =>
(await api.get('/clients', { params })).data,
getById: async (id: string) =>
(await api.get(`/clients/${id}`)).data,
}Factory de queryOptions do TanStack Query:
// modules/client/http/queries/index.ts
export const clientQueries = {
list: (params: TGenericListSchema) => queryOptions({
queryKey: ['clients', 'list', params],
queryFn: () => clientApi.list(params),
placeholderData: keepPreviousData, // UX: evita "pisca" de loading
})
}Pré-carrega dados na rota usando ensureQueryData:
// src/app/_private/clientes/index.tsx
export const Route = createFileRoute("/_private/clientes/")({
loader: ({ context, deps }) =>
context.queryClient.ensureQueryData(clientQueries.list(deps)),
component: ClientListPage,
});Consome dados com useSuspenseQuery (dados já no cache):
// modules/client/list/client-list.tsx
const { data } = useSuspenseQuery(clientQueries.list(params));Padrão obrigatório para todos os formulários:
- Schema Zod: Define validação e tipos
- React Hook Form: Controla estado do formulário
- Shadcn Form Components: UI consistente
// 1. Schema
const formSchema = z.object({
name: z.string().min(1, "Nome é obrigatório"),
email: z.string().email("Email inválido"),
});
type TFormData = z.infer<typeof formSchema>;
// 2. Form Hook
const form = useForm<TFormData>({
resolver: zodResolver(formSchema),
});
// 3. UI (Shadcn)
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>Nome</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>Padrões de teste seguindo Branch Coverage:
- ✅ Happy Path: Caso de uso padrão
⚠️ Null/Undefined: Tratamento de valores opcionais- 🛑 Error Handling: Blocos
try/catch - 🔄 Condicionais: Todos os branches de
if/else - 📏 Boundaries: Limites de strings e arrays
describe('ClientService', () => {
describe('getById', () => {
it('should return client data when id is valid', () => { ... });
it('should throw error when id is invalid', () => { ... });
it('should handle undefined id gracefully', () => { ... });
});
});Sistema de tokens semânticos que funciona automaticamente:
/* ❌ EVITE: Cores hardcoded */
bg-white text-black border-gray-200
/* ✅ USE: Tokens semânticos */
bg-background text-foreground border-borderO Tailwind v4 resolve automaticamente as cores baseado na classe .dark no root.
- Node.js 18+
- npm ou yarn
# Clone o repositório
git clone https://github.com/celsolnv/react-base.git
cd react-base
# Instale as dependências
npm install# Inicie o servidor de desenvolvimento
npm run dev
# O app estará disponível em http://localhost:5173# Build para produção
npm run build
# Preview da build
npm run preview# Executar testes
npm run test
# Modo watch
npm run test:watch
# Com cobertura
npm run test:toPush# Verificar código
npm run lint
# Corrigir automaticamente
npm run lint:fix# Gere um módulo CRUD completo
npm run gen:module -- --name=product --pt=produtosO diagrama abaixo ilustra o fluxo completo de dados em um módulo gerado, desde a interação do usuário até a API:
graph TB
subgraph "View Layer"
A[Component] --> B[React Hook Form]
B --> C[Zod Schema Validation]
end
subgraph "State Management"
C --> D[TanStack Query Hook]
D --> E[Query Options Factory]
end
subgraph "Routing Layer"
E --> F[TanStack Router Loader]
F --> G[ensureQueryData]
G --> H[React Query Cache]
end
subgraph "API Layer"
D --> I[Axios Service]
I --> J[HTTP Request]
J --> K[Backend API]
K --> L[Response Data]
end
subgraph "Cache Flow"
L --> H
H --> M[Component Re-render]
M --> A
end
style A fill:#61DAFB
style D fill:#FF4154
style F fill:#FF4154
style I fill:#5A67D8
style K fill:#4CAF50
- Usuário interage com o formulário (Component)
- React Hook Form gerencia o estado local
- Zod valida os dados antes do submit
- TanStack Query Hook (mutation) executa a ação
- Axios Service faz a requisição HTTP
- Backend API processa e retorna dados
- React Query Cache armazena a resposta
- Component re-renderiza com dados atualizados
Para leitura de dados:
- O Loader do TanStack Router pré-carrega dados via
ensureQueryData - O componente usa
useSuspenseQuerypara acessar dados já em cache - Zero loading states manuais necessários
src/
├── app/ # Rotas (TanStack Router)
│ ├── __root.tsx # Root layout
│ ├── _public/ # Rotas públicas
│ └── _private/ # Rotas protegidas
├── modules/ # Módulos de negócio (DDD)
│ ├── user/ # Exemplo: módulo de usuários
│ │ ├── components/
│ │ ├── create/
│ │ ├── update/
│ │ ├── list/
│ │ └── http/
│ └── template-base/ # Template para gerador
├── components/ # Componentes compartilhados
│ ├── layouts/
│ └── shared/
├── lib/ # Configurações de infra
│ ├── query-client.ts
│ └── api-client.ts
├── constants/ # Constantes globais
└── global.css # Tailwind v4 (@theme)
- Interfaces: Sempre começam com
I(ex:IUserData) - Types: Sempre começam com
T(ex:TUserRole) - Components: PascalCase (ex:
UserForm) - Hooks: camelCase com prefixo
use(ex:useUserList) - Files: kebab-case (ex:
user-form.tsx)
Use path aliases configurados:
// ✅ Correto
import { Button } from "@/components/ui/button";
import { userApi } from "@/modules/user/http/api";
// ❌ Evite
import { Button } from "../../../components/ui/button";Este é um template/boilerplate. Sinta-se à vontade para:
- Fork o projeto
- Crie uma branch para sua feature (
git checkout -b feature/AmazingFeature) - Commit suas mudanças (
git commit -m 'Add some AmazingFeature') - Push para a branch (
git push origin feature/AmazingFeature) - Abra um Pull Request
Este projeto está sob a licença MIT. Veja o arquivo LICENSE para mais detalhes.
Desenvolvido com ❤️ usando React, TypeScript e TanStack Ecosystem