This document outlines the contribution philosophy, conventions, and processes for this repository.
This template prioritizes:
- Simplicity: Keep the starter minimal and focused
- Type safety: Maintain strict TypeScript configuration
- Code quality: Enforce consistent formatting and linting
- Developer experience: Provide excellent tooling and clear patterns
Contributions should align with these principles. When in doubt, prefer explicit, type-safe solutions over clever abstractions.
This repository uses a simple branching model:
main: Production-ready code- Feature branches:
feature/descriptionorfix/description - No long-lived development branches
Use kebab-case with a prefix:
feature/add-new-componentfix/routing-issuedocs/update-readme
This project uses Conventional Commits enforced by Commitlint.
<type>(<scope>): <subject>
[optional body]
[optional footer]
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changes (formatting, missing semicolons, etc.)refactor: Code refactoringtest: Adding or updating testschore: Maintenance tasks (dependencies, config, etc.)perf: Performance improvements
Valid scopes (enforced by Commitlint):
componentslayoutroutesstylesutilshooks
feat(components): add theme toggle component
fix(routes): resolve 404 page routing issue
docs(readme): update installation instructions
chore(deps): update vite to latest versionCommit messages are validated via Husky hook (.husky/commit-msg). Invalid messages will be rejected.
This project uses Biome for linting and formatting (replaces ESLint and Prettier).
Key Rules:
- Single quotes for strings
- 2-space indentation
- Kebab-case for filenames (except route files)
- No default exports (except route files and page
index.tsx) - No barrel files (
index.tsre-exports) - No console statements (except
console.errorandconsole.info)
Biome automatically formats code on commit via lint-staged. Manual formatting:
pnpm biome:fix- Components:
kebab-case.tsx(e.g.,theme-toggle.tsx) - Routes: Follow TanStack Router conventions (e.g.,
__root.tsx,index.tsx) - Pages:
kebab-case/index.tsx(e.g.,home/index.tsx) - Utils:
kebab-case.ts(e.g.,sample.ts)
Biome automatically organizes imports with this grouping:
- External packages (URL, Node, npm packages)
- Blank line
- Path aliases (
@/*) - Blank line
- Relative paths
- Strict mode: Enabled (
strict: true,strictNullChecks: true) - No unused variables/parameters: Enforced at compile time
- Explicit return types: Not required but recommended for public APIs
- Type imports: Use
import typefor type-only imports when appropriate
- Functional components: Use function declarations or arrow functions
- Hooks: Must be called at top level (enforced by linter)
- Props: Use TypeScript interfaces or types, not PropTypes
- Default exports: Only for route files and page
index.tsxfiles
- Utils: Should have comprehensive test coverage
- Components: Test user interactions and edge cases
- Pages: Test rendering and routing behavior
Tests use Vitest and React Testing Library:
import { describe, expect, test } from 'vitest';
import { render, screen } from '@testing-library/react';
describe('ComponentName', () => {
test('should render correctly', () => {
render(<ComponentName />);
expect(screen.getByText('Expected Text')).toBeInTheDocument();
});
});pnpm test # Run once
pnpm test:ui # Interactive UI
pnpm test:coverage # With coverage report- Co-locate with source:
utils/sample.test.tsnext toutils/sample.ts - Or in
__tests__/directories if preferred
-
Run checks locally:
pnpm check:turbo
-
Ensure all tests pass:
pnpm test -
Verify type checking:
pnpm type:check
-
Check for unused code:
pnpm knip
- Title: Use conventional commit format
- Description: Explain what and why, not just how
- Size: Prefer smaller, focused PRs
- Breaking changes: Clearly document in description
- Tests: Include tests for new features
- Documentation: Update docs if behavior changes
Reviewers should verify:
- Code follows style guidelines
- TypeScript types are correct
- Tests are included and passing
- No console errors or warnings
- Documentation is updated if needed
- No breaking changes (or clearly documented)
Husky runs the following hooks automatically:
Runs lint-staged, which executes:
- Biome formatting and linting on staged files
Validates commit message format using Commitlint.
Runs pnpm check:turbo, which executes:
- Biome check
- TypeScript type checking
- Test suite
Note: These hooks can be bypassed with --no-verify, but this is discouraged.
- Create component in
src/lib/components/ - Follow naming convention:
kebab-case.tsx - Export as named export (not default)
- Add tests if component has logic
- Document props with TypeScript types
- Create route file in
src/routes/ - Follow TanStack Router file-based routing conventions
- Create corresponding page component in
src/lib/pages/ - Route tree auto-generates on dev server start
- Create function in
src/lib/utils/ - Export as named export
- Must include tests (coverage enforced)
- Keep functions pure when possible
- Prefer Tailwind utility classes
- For custom styles, add to
src/lib/styles/globals.css - Use CSS custom properties for theme values
- Follow Tailwind v4 conventions
- Use
pnpm add <package>for production dependencies - Use
pnpm add -D <package>for dev dependencies - Update
package.jsondirectly if needed, then runpnpm install
pnpm up-interactive # Interactive update
pnpm up-latest # Update to latest versions- Prefer well-maintained packages
- Check bundle size impact
- Verify TypeScript support
- Review security advisories
If Husky hooks aren't executing:
pnpm prepare # Reinstall hookspnpm type:check # Verify types
# Delete tsconfig.tsbuildinfo if issues persistpnpm biome:fix # Auto-fix issuesRestart the dev server. The route tree regenerates on server start.
- Check existing documentation (README.md, SPEC.md, AGENTS.md)
- Review similar code in the repository
- Open an issue for clarification