Project Organization Best Practices
Learn how to structure your Orchestre projects for maximum efficiency, maintainability, and team collaboration. These patterns have emerged from real-world usage across different project types.
Core Principles
1. Colocate Related Code
Keep related files together rather than separating by file type:
❌ Bad Structure
src/
├── components/
│ ├── UserProfile.tsx
│ ├── UserSettings.tsx
│ └── UserAvatar.tsx
├── hooks/
│ ├── useUser.ts
│ └── useUserSettings.ts
├── utils/
│ └── userValidation.ts
✅ Good Structure
src/
├── features/
│ └── user/
│ ├── components/
│ │ ├── UserProfile.tsx
│ │ ├── UserSettings.tsx
│ │ └── UserAvatar.tsx
│ ├── hooks/
│ │ ├── useUser.ts
│ │ └── useUserSettings.ts
│ ├── utils/
│ │ └── validation.ts
│ └── CLAUDE.md # Feature documentation2. Maintain Clear Boundaries
Each module should have clear responsibilities:
3. Document as You Go
Every significant directory should have a CLAUDE.md file:
feature/
├── CLAUDE.md # What this feature does
├── index.ts # Public API
├── components/ # UI components
├── logic/ # Business logic
└── tests/ # Feature testsRecommended Project Structure
Full-Stack Application
my-app/
├── CLAUDE.md # Project overview
├── .orchestre/ # Orchestre configuration
│ ├── commands/ # Custom commands
│ ├── patterns/ # Discovered patterns
│ └── memory-templates/ # Documentation templates
├── apps/ # Applications (monorepo)
│ ├── web/ # Frontend application
│ │ ├── src/
│ │ └── CLAUDE.md
│ ├── api/ # Backend API
│ │ ├── src/
│ │ └── CLAUDE.md
│ └── mobile/ # Mobile app
│ ├── src/
│ └── CLAUDE.md
├── packages/ # Shared packages
│ ├── ui/ # UI component library
│ ├── core/ # Core business logic
│ └── utils/ # Shared utilities
├── docs/ # Documentation
├── scripts/ # Build and deployment scripts
└── tests/ # End-to-end testsMicroservices Architecture
microservices/
├── CLAUDE.md # System overview
├── .orchestre/
├── services/ # Individual services
│ ├── user-service/
│ │ ├── src/
│ │ ├── Dockerfile
│ │ └── CLAUDE.md
│ ├── order-service/
│ │ ├── src/
│ │ ├── Dockerfile
│ │ └── CLAUDE.md
│ └── payment-service/
│ ├── src/
│ ├── Dockerfile
│ └── CLAUDE.md
├── shared/ # Shared libraries
│ ├── contracts/ # API contracts
│ ├── events/ # Event definitions
│ └── utils/ # Shared utilities
├── infrastructure/ # Infrastructure as code
│ ├── kubernetes/
│ └── terraform/
└── gateway/ # API GatewayTemplate-Specific Organization
MakerKit (SaaS)
saas-app/
├── apps/
│ └── web/
│ ├── app/ # Next.js app directory
│ │ ├── (app)/ # Authenticated routes
│ │ ├── (auth)/ # Auth routes
│ │ └── (marketing)/ # Public routes
│ ├── components/
│ ├── lib/
│ └── server/ # Server-side code
├── packages/
│ ├── database/ # Prisma schema
│ ├── email/ # Email templates
│ └── ui/ # Shared components
└── .orchestre/Cloudflare Workers
edge-api/
├── src/
│ ├── routes/ # API routes
│ ├── middleware/ # Middleware
│ ├── services/ # Business logic
│ └── index.ts # Entry point
├── migrations/ # D1 migrations
├── bindings.d.ts # TypeScript bindings
└── wrangler.toml # Cloudflare configFeature Organization
Feature Folder Structure
Each feature should be self-contained:
features/checkout/
├── CLAUDE.md # Feature documentation
├── index.ts # Public exports
├── components/ # UI components
│ ├── CheckoutForm.tsx
│ ├── PaymentMethod.tsx
│ └── OrderSummary.tsx
├── hooks/ # Feature hooks
│ ├── useCheckout.ts
│ └── usePayment.ts
├── services/ # API/business logic
│ ├── checkout.service.ts
│ └── payment.service.ts
├── types/ # TypeScript types
│ └── checkout.types.ts
├── utils/ # Utilities
│ └── validation.ts
└── __tests__/ # Feature testsNaming Conventions
Files and Folders
- Components: PascalCase (
UserProfile.tsx) - Utilities: camelCase (
formatDate.ts) - Hooks: camelCase with 'use' prefix (
useAuth.ts) - Types: PascalCase with '.types' suffix (
User.types.ts) - Tests: Same as source with '.test' suffix (
useAuth.test.ts)
Code Organization
typescript
// 1. Imports (external, then internal)
import { useState } from 'react'
import { Button } from '@/components/ui'
import { useAuth } from '@/features/auth'
// 2. Types/Interfaces
interface UserProfileProps {
userId: string
}
// 3. Component/Function
export function UserProfile({ userId }: UserProfileProps) {
// Implementation
}
// 4. Subcomponents (if needed)
function ProfileAvatar() {
// Implementation
}
// 5. Utilities (if small and specific)
function formatUserName(user: User) {
// Implementation
}Configuration Management
Environment Variables
.env.example # Template with all variables
.env.local # Local development
.env.test # Test environment
.env.production # Production (usually in CI/CD)Configuration Structure
typescript
// config/index.ts
export const config = {
app: {
name: process.env.NEXT_PUBLIC_APP_NAME,
url: process.env.NEXT_PUBLIC_APP_URL,
},
api: {
url: process.env.API_URL,
timeout: Number(process.env.API_TIMEOUT) || 30000,
},
features: {
enableBeta: process.env.ENABLE_BETA === 'true',
},
}Documentation Standards
CLAUDE.md Files
Every significant module should have documentation:
markdown
# Feature: User Authentication
## Overview
JWT-based authentication with refresh tokens.
## Architecture
- NextAuth.js for session management
- Prisma adapter for database
- Custom JWT strategy
## Key Files
- `auth.config.ts` - NextAuth configuration
- `middleware.ts` - Route protection
- `hooks/useAuth.ts` - Client-side auth
## Environment Variables
- `NEXTAUTH_SECRET` - Session encryption
- `NEXTAUTH_URL` - Callback URL
## Common Tasks
- Add provider: Edit `auth.config.ts`
- Protect route: Add to `middleware.ts`
- Get user: Use `useAuth()` hookCode Comments
typescript
// Use comments to explain "why", not "what"
// ❌ Bad: Obvious comment
// Increment counter by 1
counter++
// ✅ Good: Explains reasoning
// Increment retry counter - we allow 3 attempts
// before locking the account for security
counter++Testing Organization
Test Structure
Mirror your source structure:
src/
├── features/
│ └── auth/
│ ├── components/
│ │ └── LoginForm.tsx
│ └── services/
│ └── auth.service.ts
tests/
├── unit/
│ └── features/
│ └── auth/
│ ├── components/
│ │ └── LoginForm.test.tsx
│ └── services/
│ └── auth.service.test.ts
├── integration/
│ └── auth.integration.test.ts
└── e2e/
└── auth.e2e.test.tsTest Naming
typescript
// describe blocks match file structure
describe('features/auth/services/auth.service', () => {
describe('login', () => {
it('should return user and token on success', () => {})
it('should throw on invalid credentials', () => {})
})
})Import Organization
Path Aliases
Configure in tsconfig.json:
json
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"],
"@/features/*": ["./src/features/*"],
"@/components/*": ["./src/components/*"],
"@/lib/*": ["./src/lib/*"],
"@/utils/*": ["./src/utils/*"]
}
}
}Import Order
typescript
// 1. External dependencies
import React, { useState, useEffect } from 'react'
import { useRouter } from 'next/router'
import { z } from 'zod'
// 2. Internal absolute imports
import { Button } from '@/components/ui'
import { useAuth } from '@/features/auth'
import { api } from '@/lib/api'
// 3. Relative imports
import { UserProfile } from './UserProfile'
import { formatDate } from './utils'
// 4. Types
import type { User } from '@/types'Common Patterns
Barrel Exports
Use index files for clean imports:
typescript
// features/auth/index.ts
export * from './hooks/useAuth'
export * from './components/LoginForm'
export * from './types'
// Usage
import { useAuth, LoginForm } from '@/features/auth'Feature Flags
typescript
// config/features.ts
export const features = {
newCheckout: process.env.NEXT_PUBLIC_FEATURE_NEW_CHECKOUT === 'true',
betaFeatures: process.env.NEXT_PUBLIC_BETA === 'true',
}
// Usage
if (features.newCheckout) {
return <NewCheckout />
}Shared Types
typescript
// types/index.ts
export interface User {
id: string
email: string
name: string
}
// types/api.ts
export interface ApiResponse<T> {
data: T
error?: string
}Anti-Patterns to Avoid
1. Circular Dependencies
typescript
// ❌ Bad: user imports from auth, auth imports from user
// user/index.ts
import { checkAuth } from '@/features/auth'
// auth/index.ts
import { getUser } from '@/features/user'
// ✅ Good: Extract shared logic
// core/auth.ts
export function checkAuth() {}
// Both features import from core2. Deep Nesting
❌ Bad: Too deep
src/features/user/components/profile/settings/privacy/gdpr/consent/ConsentForm.tsx
✅ Good: Flatter structure
src/features/user/components/ConsentForm.tsx3. Mixed Concerns
typescript
// ❌ Bad: UI component with business logic
function UserProfile() {
const calculateSubscriptionCost = () => {
// Complex business logic here
}
}
// ✅ Good: Separate concerns
// services/subscription.service.ts
export function calculateSubscriptionCost() {}
// components/UserProfile.tsx
import { calculateSubscriptionCost } from '@/services/subscription'Maintenance Tips
1. Regular Cleanup
- Remove unused files and dependencies
- Update documentation as you refactor
- Archive old features properly
2. Dependency Management
- Keep dependencies up to date
- Audit for vulnerabilities regularly
- Document why each dependency exists
3. Code Reviews
- Check for consistent structure
- Ensure documentation is updated
- Verify naming conventions
Next Steps
- Review Performance Best Practices
- Learn about Security Guidelines
- Explore Team Collaboration
