Development Workflow
Learn the day-to-day commands, QA expectations, and collaboration practices for Raypx.
Environment Setup
Initial Setup
-
Install dependencies
pnpm install -
Configure environment variables
cp .env.example .envEdit
.envwith required values:DATABASE_URL- PostgreSQL connection stringBETTER_AUTH_SECRET- Min 32 characters for auth encryptionAUTH_URL- Your app URL (http://localhost:3000 for dev)- Optional: Redis, OAuth, Analytics, AI services (137+ env vars available)
-
Setup database
pnpm --filter @raypx/database migrate -
Start development
pnpm dev # All apps (web + docs) # or pnpm dev:web # Just web app
Environment Variables
The project uses type-safe environment variables via @raypx/config:
- Validation: All env vars validated with Zod schemas
- Organization: Grouped by category (app, feature flags, database, auth, etc.)
- Type safety: Full TypeScript support in code
- Examples: See
.env.examplefor all 137+ available variables
Common Scripts
| Command | Description |
|---|---|
pnpm dev | Start all apps (web + docs) with hot reload |
pnpm dev:web | Just the TanStack Start web app |
pnpm dev:docs | Just the Fumadocs documentation site |
pnpm dev:email | Email template preview server |
pnpm build | Production build of all apps (validates everything) |
pnpm build:pkg | Build packages only |
pnpm start:web | Start production web server |
pnpm typecheck | TypeScript validation across workspace |
pnpm check | Biome linting and formatting check |
pnpm format | Auto-format all code with Biome |
pnpm test | Run Vitest unit tests |
pnpm coverage | Generate HTML coverage reports |
pnpm clean | Remove build artifacts and caches |
pnpm db | Database commands |
pnpm shadcn | Add shadcn/ui components to @raypx/design-system |
pnpm bump-ui | Update all UI components |
pnpm knip | Find unused code |
Coding Standards
TypeScript
- Strict mode enabled: All projects use strict TypeScript settings
- Explicit types: Prefer explicit return types in shared packages
- Type over interface: Use
typeoverinterfacefor consistency - Avoid
any: Useunknowninstead and narrow with type guards
Code Style
- Formatting: Biome handles all formatting (replaces Prettier)
- Linting: Biome enforces code quality rules (replaces ESLint)
- Pre-commit hooks: Lefthook runs
pnpm formatbefore commits - Variable names: Use clear, descriptive names over short abbreviations
Project Structure
- Tests: Co-locate tests next to modules (
*.test.ts[x]) or in__tests__/ - Routes: TanStack Start file-based routing in
apps/web/src/routes/ - Components: React components in
apps/web/src/components/ - No build for packages: All packages consumed as TypeScript source
Git Practices
Commit Convention
Follow Conventional Commits format:
<type>(<scope>): <description>
[optional body]Types: feat, fix, docs, refactor, perf, test, chore, ci
Examples:
git commit -m "feat(auth): add OAuth providers"
git commit -m "fix(ui): resolve button hover state"
git commit -m "docs: update environment setup guide"
git commit -m "feat(web,auth): add login flow"Pre-push Checklist
Always run before pushing:
pnpm typecheck # TypeScript validation
pnpm check # Linting
pnpm test # Unit tests
pnpm build # Verify production buildBuild time is only 10-15 seconds, so always build before commits.
Branch Strategy
- Work on feature branches (
feature/add-oauth) - Avoid force-pushing shared branches
- Use
git push --force-with-leaseif necessary (coordinate with team)
Testing
Current State
⚠️ Testing is a critical gap (15% coverage):
- ✅ Vitest framework configured
- ✅ CI runs tests automatically
- ✅ E2E tests with Playwright configured
- ❌ Minimal test coverage
Testing Guidelines
When adding tests:
-
Unit tests: Test business logic and utilities
// packages/shared/__tests__/utils.test.ts import { describe, it, expect } from 'vitest' import { yourFunction } from '../utils' describe('yourFunction', () => { it('should handle valid input', () => { expect(yourFunction('test')).toBe('expected') }) }) -
Integration tests: Test API endpoints, database operations
Running Tests
# Unit and integration tests
pnpm test # All tests
pnpm test --watch # Watch mode
pnpm coverage # Generate coverage reportCoverage reports are uploaded to Codecov in CI.
Database Development
Workflow
- Modify schema in
packages/database/src/schemas/pg/ - Generate migration:
pnpm --filter @raypx/database generate - Review migration in
packages/database/migrations/pg/ - Apply migration:
pnpm --filter @raypx/database migrate - Verify in Drizzle Studio:
pnpm db studio
Database Tips
- Use Drizzle's type-safe query builder
- Leverage PostgreSQL features (JSONB, arrays, etc.)
- Add indexes for frequently queried columns
- Use migrations for all schema changes (never manual ALTER TABLE)
📘 Production Setup: See Database Hosting Guide for setting up PostgreSQL in production environments (Neon, Supabase, Railway, etc.)
Working with Documentation
- Documentation lives in
apps/docs/content/docs/ - Write documentation in MDX format (Markdown + JSX)
- Run
pnpm dev:docsto preview docs at http://localhost:3001 - Fumadocs auto-generates navigation from file structure and frontmatter
Troubleshooting
Build Issues
# Clear all caches and rebuild
pnpm clean
rm -rf node_modules .turbo
pnpm install
pnpm buildTypeScript Errors
- Restart TypeScript server (VS Code: Cmd+Shift+P → "Restart TS Server")
- Clear TypeScript cache:
rm -rf tsconfig.tsbuildinfo - Reinstall dependencies:
pnpm install
Common Errors
- "Cannot find module '@raypx/...'" → Run
pnpm install - "Port 3000 in use" → Kill process:
lsof -ti:3000 | xargs kill -9 - "Type error in node_modules" → Delete
node_modulesand reinstall - Biome errors → Run
pnpm formatto auto-fix