han-stack-archive
han-stack-archive copied to clipboard
Modern Saas fullstack framework template using Tanstack Start, orpc
Han Stack - Modern SaaS Template
[!WARNING] This repository is no longer actively maintained.
I highly recommend checking out create-better-t-stack as a more robust and actively developed alternative for similar functionalities.
A powerful, full-stack SaaS starter template built with modern technologies. This template provides a solid foundation for building scalable SaaS applications with best practices and industry-standard tools.
Features
- 🚀 Full-Stack TypeScript - End-to-end type safety
- ⚡ High Performance - Built with performance in mind using Vite
- 🔄 Modern Data Fetching - Powered by TanStack Query
- 🛣️ Type-Safe Routing - Using TanStack Router
- 🔒 Type-Safe RPC - End-to-end type safety with ORPC
- ✨ Best Practices - Following modern development standards
- 🎨 Component Architecture - Well-organized and scalable component structure
- 🛠️ Developer Experience - Enhanced with Biome configurations
- 📊 Reusable Data Tables - Common DataTable component with sorting, filtering, and pagination
- 👥 User Management - Built-in user administration features
Tech Stack
Frontend
- React - UI Library (v19.1)
- TanStack Router - Type-safe routing
- TanStack Query - Data synchronization
- Tailwind CSS v4 - Utility-first CSS framework
- Radix UI - Headless UI components
- shadcn/ui - Re-usable components built on Radix UI
- Vite - Build tool and dev server
Backend & API
- TanStack Start - Full-stack framework (Beta)
- ORPC - Type-safe RPC for end-to-end type safety
- Prisma - Modern database ORM
- Better Auth - Authentication framework
Development & Tooling
- TypeScript - Type safety throughout
- Biome - Fast formatter and linter
- Zod - Runtime type validation
- Zod Prisma Types - Auto-generated Zod schemas
- React Hook Form - Performant forms with validation
Getting Started
Prerequisites
- Node.js 20+
- pnpm
Installation
- Clone the repository
git clone https://github.com/Insik-Han/han-stack.git
cd han-stack
- Create .env
cp .env.example .env
- Install dependencies
pnpm install
- Setup development environment
pnpm run setup
- Start the development server
pnpm run dev
Development
Project Structure
src/
├── components/ # Reusable UI components
│ ├── ui/ # Atomic/molecular UI components
│ ├── layout/ # Layout-related components
│ ├── errors/ # Error handling components
│ ├── data-table/ # Reusable data table components
│ └── ... # Other shared components
├── constants/ # Application constants
├── features/ # Feature modules
│ ├── auth/ # Authentication features
│ ├── global-search/ # Global search features
│ ├── settings/ # Settings features
│ ├── tasks/ # Task management features
│ ├── users/ # User management features
│ └── theme/ # Theme features
├── hooks/ # Custom React hooks
├── lib/ # Shared libraries and helpers
├── routes/ # Application routes and pages
│ ├── _admin-console/ # Admin console routes
│ ├── api/ # API routes
│ ├── (auth)/ # Auth-related routes
│ ├── (errors)/ # Error pages
│ └── __root.tsx # Root route entry
├── server/ # Backend/server logic
│ ├── api/ # API endpoints
│ │ ├── routes/ # API route handlers
│ │ └── router.ts # API router
│ ├── handler.ts # RPC handler
│ └── db.ts # Database connection
├── styles/ # Global and component styles
├── utils/ # Utility functions
├── router.tsx # Client router
├── routeTree.gen.ts # Auto-generated route tree
└── ...
public/ # Static files (images, favicon, etc.)
├── assets/ # Static assets (e.g., logo)
├── favicon.ico # Favicon
prisma/ # Prisma schema and seed data
├── schema.prisma # Prisma DB schema
├── seed.ts # Seed data script (uses faker.js for test data)
Other key files:
- package.json # Project metadata and dependencies
- tsconfig.json # TypeScript configuration
- biome.jsonc # Biome (formatter/linter) configuration
- CLAUDE.md # Guidelines for Claude AI assistant
Refer to the code and comments for more details on each directory and file.
Scripts
Development
pnpm run dev- Start development server on port 3000pnpm run build- Build for productionpnpm run start- Start production server
Database
pnpm run generate- Generate Prisma client and Zod typespnpm run prisma:studio- Open Prisma Studio GUIpnpm run db:seed- Seed database with test datapnpm run db:reset- Reset database and migrationspnpm run migrate:dev- Run Prisma migrations in developmentpnpm run migrate- Deploy migrations to production
Code Quality
pnpm run biome- Format and lint code with Biomepnpm run tsc- Run TypeScript type checking
Testing
pnpm run test- Run all testspnpm run test:unit- Run unit testspnpm run test:ui- Run UI testspnpm run test:e2e- Run E2E tests with Playwrightpnpm run test:e2e:ui- Run E2E tests with Playwright UI modepnpm run coverage- Run tests with coverage report
Testing
The project uses different testing approaches based on the testing scope:
- Unit Tests (
*.unit.spec.ts) - Fast, isolated tests running in Node.js environment - UI Tests (
*.ui.spec.ts) - Component tests running in a real browser environment - E2E Tests (
*.test.ts) - End-to-end tests using Playwright
Test Configuration
Vitest Configuration
The project uses Vitest with two separate test projects configured in vite.config.ts:
test: {
projects: [
{
test: {
name: 'unit',
include: ['src/**/*.unit.spec.{ts,tsx}'],
},
},
{
test: {
name: 'ui',
include: ['src/**/*.ui.spec.{ts,tsx}'],
browser: {
enabled: true,
provider: 'playwright',
instances: [{ browser: 'chromium' }],
headless: true,
},
},
},
],
}
Playwright Configuration
E2E tests are configured in playwright.config.ts with:
- Test directory:
./tests/e2e - Base URL:
http://localhost:3000 - Browsers: Chromium and WebKit
- Automatic dev server startup
Running Tests
Unit Tests
# Run all unit tests
pnpm run test:unit
# Run tests in watch mode
pnpm run test:unit --watch
# Run specific test file
pnpm run test src/schemas/upload.unit.spec.ts
UI Tests
# Run all UI tests
pnpm run test:ui
# Run in watch mode
pnpm run test:ui --watch
E2E Tests
# Run all E2E tests
pnpm run test:e2e
# Run specific test
pnpm exec playwright test tests/e2e/example.test.ts
# Run with UI mode for debugging
pnpm run test:e2e:ui
Writing Tests
Unit Tests
Unit tests are for testing pure logic, utilities, and server-side code:
// src/schemas/upload.unit.spec.ts
import { describe, expect, it } from "vitest";
import { fileSchema } from "./upload";
describe("fileSchema", () => {
it("should accept any value in Node.js environment", () => {
expect(fileSchema.safeParse("string").success).toBe(true);
});
});
UI Tests
UI tests are for testing React components with DOM interactions:
// src/hooks/use-mobile.ui.spec.ts
import { renderHook } from "vitest-browser-react";
import { expect, test } from "vitest";
import { useMobile } from "./use-mobile";
test("should detect mobile viewport", () => {
const { result } = renderHook(() => useMobile());
expect(result.current).toBe(false);
});
E2E Tests
E2E tests simulate real user interactions:
// tests/e2e/example.test.ts
import { expect, test } from "@playwright/test";
test("Go to sign-in", async ({ page }) => {
await page.goto("/sign-in");
await expect(page.locator('[data-slot="card-title"]')).toHaveText("Login");
await expect(page.getByRole("button", { name: "Login" })).toBeVisible();
});
CI/CD Integration
The project uses GitHub Actions for continuous integration with optimized workflows using reusable actions:
Reusable Actions
Located in .github/actions/:
- setup-pnpm - Installs pnpm and project dependencies
- setup-database - Sets up test database with migrations
CI Workflow
The CI workflow (.github/workflows/ci.yml) runs on pull requests and includes:
- Biome - Code formatting and linting
- TypeScript - Type checking
- Vitest - Unit and UI tests with coverage reporting
- Playwright - E2E tests with artifact uploads
Best Practices
Test Organization
- Place unit tests next to the code they test (e.g.,
schema.ts→schema.unit.spec.ts) - Keep UI tests close to components they test
- Group E2E tests by feature or user flow
Test Naming
- Use descriptive test names that explain what is being tested
- Follow the pattern: "should [expected behavior] when [condition]"
- Group related tests using
describeblocks
Test Data
- Use factories or builders for complex test data
- Keep test data minimal but realistic
- Clean up test data after tests when necessary
Assertions
- Use specific assertions rather than generic ones
- Test both positive and negative cases
- Include edge cases in your tests
Environment Considerations
Server-Side vs Client-Side
Be aware of environment differences when writing tests:
- Server-side tests run in Node.js (no DOM, no browser APIs)
- Client-side tests need browser environment for DOM manipulation
- Some schemas/utilities may behave differently based on environment
Example from upload.ts:
export const fileSchema = (
typeof window === "undefined" ? z.any() : z.instanceof(FileList)
) as z.ZodType<FileList>;
Test Database
- Tests use SQLite database (configured via
.env.example) - Database is reset between test runs if needed
- Use
pnpm run db:seedto populate test data
Debugging Tests
Vitest
- Use
console.logfor quick debugging - Use VS Code's debugger with breakpoints
- Run tests in UI mode:
pnpm exec vitest --ui
Playwright
- Use
--debugflag:pnpm exec playwright test --debug - Use
page.pause()to pause execution - View traces:
pnpm exec playwright show-trace - Take screenshots:
await page.screenshot({ path: 'debug.png' })
Coverage
The project aims for good test coverage. View coverage reports:
# Generate coverage report
pnpm run coverage
# Coverage is also reported in PR comments via GitHub Actions
Troubleshooting
Common Issues
-
"DataTransfer is not defined" - This API is not available in Node.js. Use UI tests for browser-specific APIs.
-
"Element not found" - Check selectors, ensure the page has loaded, use
page.waitForSelector(). -
Type errors in tests - Ensure proper TypeScript configuration and that test types are installed.
Tips
- Run tests locally before pushing
- Check CI logs for detailed error messages
- Use appropriate test type for what you're testing
- Keep tests fast and focused
Resources
Deployment
The application can be deployed to any Node.js hosting platform. After building the project with pnpm run build, you can start the production server with pnpm run start.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
If you find this template helpful, please consider giving it a star ⭐️
Inspiration
This project draws inspiration from the following amazing repositories:
Built with ❤️ by Insik-Han