Skip to content

A TanStack Start boilerplate implementing Clean Architecture principles for maintainable, testable, and scalable React applications.

Notifications You must be signed in to change notification settings

felipestanzani/tanstack-start-ca

Repository files navigation

TanStack Start Clean Architecture

A modern boilerplate for building full-stack React applications with TanStack Start, implementing Clean Architecture principles for maintainable, testable, and scalable code.

πŸš€ Tech Stack

Frontend

  • React 19.1.1 with TypeScript
  • TanStack Start 1.132.19 - Full-stack React framework
  • TanStack Router 1.132.19 - Type-safe file-based routing
  • Tailwind CSS 4.1.13 - Utility-first CSS framework
  • shadcn/ui - High-quality accessible component library
  • Radix UI - Primitive components for complex UI
  • Lucide React - Beautiful icon library

Backend & Database

  • TanStack Start Server Functions - Full-stack capabilities
  • Prisma - Modern database toolkit and ORM
  • SQLite - Lightweight database

Development Tools

  • Vite 7.1.7 - Lightning-fast build tool
  • TypeScript 5.9.2 - Type safety and enhanced DX
  • ESLint - Code linting with comprehensive presets
  • Prettier - Code formatting
  • Vitest - Fast unit testing framework

πŸ“‹ Prerequisites

  • Node.js (version 18 or higher)
  • pnpm or yarn or pnpm

πŸ› οΈ Installation

  1. Clone the repository:

    git clone git@github.com:felipestanzani/tanstack-start-ca.git
    cd tanstack-start-ca
  2. Install dependencies:

    pnpm install
  3. Set up environment variables:

    Create a .env file in the root directory with the following content:

    # Database
    DATABASE_URL="file:./dev.db"
  4. Set up the database:

    Generate the Prisma client from the schema:

    pnpm db:generate

    Create the SQLite database and apply the schema:

    pnpm db:push

πŸš€ Development

Start the development server:

pnpm dev

The application will be available at http://localhost:3000

Available Scripts

Development

  • pnpm dev - Start development server
  • pnpm build - Build for production
  • pnpm preview - Preview production build

Code Quality

  • pnpm lint - Run ESLint
  • pnpm format - Format code with Prettier

Testing

  • pnpm test - Run tests with Vitest
  • pnpm test:run - Run tests once
  • pnpm test:watch - Run tests in watch mode
  • pnpm test:coverage - Run tests with coverage

Database

  • pnpm db:generate - Generate Prisma client
  • pnpm db:push - Push schema changes to database
  • pnpm db:migrate - Create and apply migrations
  • pnpm db:studio - Open Prisma Studio for database management

πŸ—οΈ Clean Architecture Structure

This project follows Clean Architecture principles with clear separation of concerns and dependency inversion. For detailed architecture documentation, see CLEAN_ARCHITECTURE.md.

tanstack-start-clean-architecture/
β”œβ”€β”€ prisma/                         # Database schema and migrations
β”‚   └── schema.prisma
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ core/                       # Core Business Logic (Domain + Application Layers)
β”‚   β”‚   β”œβ”€β”€ domain/                 # 🟦 Domain Layer (Innermost)
β”‚   β”‚   β”‚   β”œβ”€β”€ entities/           # Business entities with domain logic
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ base.entity.ts  # Base entity with common properties
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ counter.entity.ts # Counter business entity
β”‚   β”‚   β”‚   β”‚   └── index.ts        # Domain entities barrel export
β”‚   β”‚   β”‚   β”œβ”€β”€ events/             # Domain events
β”‚   β”‚   β”‚   β”‚   └── index.ts
β”‚   β”‚   β”‚   β”œβ”€β”€ repositories/       # Repository interfaces (contracts)
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ counter.repository.ts
β”‚   β”‚   β”‚   β”‚   └── index.ts
β”‚   β”‚   β”‚   └── value-objects/      # Domain value objects
β”‚   β”‚   β”‚       └── index.ts
β”‚   β”‚   └── application/            # 🟨 Application Layer
β”‚   β”‚       β”œβ”€β”€ dtos/               # Data Transfer Objects
β”‚   β”‚       β”‚   └── index.ts
β”‚   β”‚       β”œβ”€β”€ services/           # Application services
β”‚   β”‚       β”‚   └── index.ts
β”‚   β”‚       └── use-cases/          # Use cases (business operations)
β”‚   β”‚           β”œβ”€β”€ counter/
β”‚   β”‚           β”‚   β”œβ”€β”€ get-counter.use-case.ts
β”‚   β”‚           β”‚   β”œβ”€β”€ increment-counter.use-case.ts
β”‚   β”‚           β”‚   └── index.ts
β”‚   β”‚           └── index.ts
β”‚   β”œβ”€β”€ infrastructure/             # 🟩 Infrastructure Layer
β”‚   β”‚   β”œβ”€β”€ di/                     # Dependency Injection
β”‚   β”‚   β”‚   β”œβ”€β”€ container.ts        # DI container
β”‚   β”‚   β”‚   └── index.ts
β”‚   β”‚   └── repositories/           # Repository implementations
β”‚   β”‚       β”œβ”€β”€ prisma-counter.repository.ts
β”‚   β”‚       └── index.ts
β”‚   β”œβ”€β”€ presentation/               # πŸŸͺ Presentation Layer
β”‚   β”‚   └── controllers/            # HTTP request handlers
β”‚   β”‚       β”œβ”€β”€ counter.controller.ts
β”‚   β”‚       └── index.ts
β”‚   β”œβ”€β”€ components/                 # React UI components
β”‚   β”‚   β”œβ”€β”€ theme-provider.tsx
β”‚   β”‚   └── ui/                     # shadcn/ui components
β”‚   β”‚       └── button.tsx
β”‚   β”œβ”€β”€ lib/                        # Utility functions
β”‚   β”‚   └── utils.ts
β”‚   β”œβ”€β”€ routes/                     # File-based routing (TanStack Router)
β”‚   β”‚   β”œβ”€β”€ __root.tsx              # Root layout
β”‚   β”‚   └── index.tsx               # Home page
β”‚   β”œβ”€β”€ styles/                     # Global styles
β”‚   β”‚   └── app.css
β”‚   β”œβ”€β”€ tests/                      # Test files organized by layer
β”‚   β”‚   β”œβ”€β”€ application/
β”‚   β”‚   β”‚   └── use-cases/
β”‚   β”‚   β”‚       └── get-counter.use-case.test.ts
β”‚   β”‚   β”œβ”€β”€ domain/
β”‚   β”‚   β”‚   └── entities/
β”‚   β”‚   β”‚       └── counter.entity.test.ts
β”‚   β”‚   └── setup.ts
β”‚   β”œβ”€β”€ router.tsx                  # Router configuration
β”‚   └── routeTree.gen.ts            # Generated route tree
β”œβ”€β”€ components.json                 # shadcn/ui configuration
β”œβ”€β”€ package.json
β”œβ”€β”€ tsconfig.json                   # TypeScript configuration
β”œβ”€β”€ vite.config.ts                  # Vite configuration
β”œβ”€β”€ eslint.config.mjs               # ESLint configuration
β”œβ”€β”€ CLEAN_ARCHITECTURE.md           # Detailed architecture documentation
└── README.md

🧱 Architecture Layers

🟦 Domain Layer (src/core/domain/)

The innermost layer containing pure business logic:

  • Entities: Core business objects with domain rules (e.g., Counter)
  • Repository Interfaces: Contracts for data access
  • Domain Events: Business events within the domain
  • Value Objects: Immutable domain concepts

🟨 Application Layer (src/core/application/)

Orchestrates business operations:

  • Use Cases: Application-specific business rules
  • DTOs: Data transfer objects for layer communication
  • Services: Application services coordinating domain objects

🟩 Infrastructure Layer (src/infrastructure/)

Handles external concerns:

  • Repository Implementations: Concrete data access implementations
  • Dependency Injection: DI container for managing dependencies
  • External Services: Third-party integrations

πŸŸͺ Presentation Layer (src/presentation/)

User interface and API endpoints:

  • Controllers: HTTP request/response handlers using TanStack Start
  • Routes: Application routing with TanStack Router
  • Components: React UI components

πŸ§ͺ Testing Strategy

The project includes comprehensive testing organized by architecture layer:

src/tests/
β”œβ”€β”€ application/        # Application layer tests
β”œβ”€β”€ domain/            # Domain layer tests
β”œβ”€β”€ infrastructure/    # Infrastructure layer tests
└── presentation/      # Presentation layer tests

Test Types

  • Unit Tests: Testing individual components and business logic
  • Integration Tests: Testing layer interactions
  • End-to-End Tests: Testing complete user workflows

πŸ—„οΈ Database

This project uses SQLite with Prisma for data persistence.

Database Schema

The application uses a simple Counter table with the following structure:

model Counter {
  id        String   @id
  value     Int      @default(0)
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

Repository Implementation

The counter persistence uses database storage (PrismaCounterRepository):

  • Implements the CounterRepository interface
  • Uses SQLite for data persistence
  • Supports the default counter with automatic creation
  • Handles upsert operations for counter updates
  • Maintains full compatibility with existing use cases

Note: The Prisma client is generated to the standard location (node_modules/@prisma/client) for better ES module compatibility with Vite/TanStack Start.

⚑ State Management with TanStack Query

This project uses TanStack Query for all client-server state synchronization and UI data fetching. Benefits include:

  • Automatic caching and background updates
  • Optimistic UI for instant feedback on mutations
  • Error handling and retry logic out of the box
  • DevTools for query/mutation debugging

Query Setup

Custom Hooks

  • useCounter() β€” Fetches the current counter value
  • useIncrementCounter() β€” Increments the counter (with optimistic update)

See src/hooks/use-counter.ts for implementation details.

Example Usage (Home Page)

The home page demonstrates:

  • Live counter value with auto-refresh
  • Increment button with instant UI feedback
  • Loading and error states
  • Optimistic updates for a snappy user experience

πŸ†• Counter Feature Demo

  • Increment the counter with instant feedback
  • UI disables button during loading/mutation
  • Error messages and retry options for failed requests
  • Powered by TanStack Query hooks and server functions

🎯 Features

This boilerplate includes:

  • βœ… Clean Architecture implementation
  • βœ… Type-safe routing with TanStack Router
  • βœ… Server-side rendering with TanStack Start
  • βœ… Database integration with Prisma + SQLite
  • βœ… UI components with shadcn/ui
  • βœ… Testing setup with Vitest
  • βœ… Code quality with ESLint and Prettier
  • βœ… Dependency injection container
  • βœ… Example counter feature demonstrating architecture
  • βœ… State management with TanStack Query (caching, mutations, optimistic updates)
  • βœ… React Query DevTools for development
  • βœ… Increment counter with optimistic UI

πŸ“š Learn More

🀝 Contributing

Contributions are welcome! Please read our contributing guidelines and submit pull requests for any improvements.

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • Clean Architecture principles by Robert C. Martin
  • TanStack team for amazing React tools
  • shadcn for the beautiful UI components
  • The open-source community for inspiration and tools

About

A TanStack Start boilerplate implementing Clean Architecture principles for maintainable, testable, and scalable React applications.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published