
Project Structure Enforcer
- 14 installs
- 213 repo stars
- Updated August 4, 2026
- yonatangross/orchestkit
Helps with ai & agent building tasks.
About
project-structure-enforcer is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- project-structure-enforcer
- AI & Agent Building
- AI-coding skill
Project Structure Enforcer by the numbers
- 14 all-time installs (skills.sh)
- Ranked #11,275 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/yonatangross/orchestkit --skill project-structure-enforcerAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 14 |
|---|---|
| repo stars | ★ 213 |
| Last updated | August 4, 2026 |
| Repository | yonatangross/orchestkit ↗ |
What it does
Helps with ai & agent building tasks.
Files
Enforce 2026 folder structure best practices with BLOCKING validation.
Validation Rules
BLOCKING Rules (exit 1)
| Rule | Check | Example Violation |
|---|---|---|
| Max Nesting | Max 4 levels from src/ or app/ | src/a/b/c/d/e/file.ts |
| No Barrel Files | No index.ts re-exports | src/components/index.ts |
| Component Location | React components in components/ or features/ | src/utils/Button.tsx |
| Hook Location | Custom hooks in hooks/ directory | src/components/useAuth.ts |
| Import Direction | Unidirectional: shared → features → app | features/ importing from app/ |
Expected Folder Structures
React/Next.js (Frontend)
src/
├── app/ # Next.js App Router (pages)
│ ├── (auth)/ # Route groups
│ ├── api/ # API routes
│ └── layout.tsx
├── components/ # Reusable UI components
│ ├── ui/ # Primitive components
│ └── forms/ # Form components
├── features/ # Feature modules (self-contained)
│ ├── auth/
│ │ ├── components/
│ │ ├── hooks/
│ │ ├── services/
│ │ └── types.ts
│ └── dashboard/
├── hooks/ # Global custom hooks
├── lib/ # Third-party integrations
├── services/ # API clients
├── types/ # Global TypeScript types
└── utils/ # Pure utility functionsFastAPI (Backend)
app/
├── routers/ # API route handlers
│ ├── router_users.py
│ ├── router_auth.py
│ └── deps.py # Shared dependencies
├── services/ # Business logic layer
│ ├── user_service.py
│ └── auth_service.py
├── repositories/ # Data access layer
│ ├── user_repository.py
│ └── base_repository.py
├── schemas/ # Pydantic models
│ ├── user_schema.py
│ └── auth_schema.py
├── models/ # SQLAlchemy models
│ ├── user_model.py
│ └── base.py
├── core/ # Config, security, deps
│ ├── config.py
│ ├── security.py
│ └── database.py
└── utils/ # Utility functionsNesting Depth Rules
Maximum 4 levels from src/ or app/:
ALLOWED (4 levels):
src/features/auth/components/LoginForm.tsx
app/routers/v1/users/router_users.py
BLOCKED (5+ levels):
src/features/dashboard/widgets/charts/line/LineChart.tsx
↳ Flatten to: src/features/dashboard/charts/LineChart.tsxNo Barrel Files
Barrel files (index.ts that only re-export) cause tree-shaking issues with Vite/webpack:
// BLOCKED: src/components/index.ts
export { Button } from './Button';
export { Input } from './Input';
export { Modal } from './Modal';
// GOOD: Import directly
import { Button } from '@/components/Button';
import { Input } from '@/components/Input';Why? Barrel files:
- Break tree-shaking (entire barrel is imported)
- Cause circular dependency issues
- Slow down build times
- Make debugging harder
Import Direction (Unidirectional Architecture)
Code must flow in ONE direction:
┌─────────────────────────────────────────────────────────┐
│ │
│ shared/lib → components → features → app │
│ │
│ (lowest) (highest) │
│ │
└─────────────────────────────────────────────────────────┘Allowed Imports
| Layer | Can Import From |
|---|---|
shared/, lib/ | Nothing (base layer) |
components/ | shared/, lib/, utils/ |
features/ | shared/, lib/, components/, utils/ |
app/ | Everything above |
Blocked Imports
// BLOCKED: shared/ importing from features/
// File: src/shared/utils.ts
import { authConfig } from '@/features/auth/config'; // ❌
// BLOCKED: features/ importing from app/
// File: src/features/auth/useAuth.ts
import { RootLayout } from '@/app/layout'; // ❌
// BLOCKED: Cross-feature imports
// File: src/features/auth/useAuth.ts
import { DashboardContext } from '@/features/dashboard/context'; // ❌
// Fix: Extract to shared/ if needed by multiple featuresType-Only Imports (Exception)
Type-only imports across features are allowed:
// ALLOWED: Type-only import from another feature
import type { User } from '@/features/users/types';Component Location Rules
React Components (PascalCase .tsx)
ALLOWED:
src/components/Button.tsx
src/components/ui/Card.tsx
src/features/auth/components/LoginForm.tsx
src/app/dashboard/page.tsx
BLOCKED:
src/utils/Button.tsx # Components not in utils/
src/services/Modal.tsx # Components not in services/
src/hooks/Dropdown.tsx # Components not in hooks/Custom Hooks (useX pattern)
ALLOWED:
src/hooks/useAuth.ts
src/hooks/useLocalStorage.ts
src/features/auth/hooks/useLogin.ts
BLOCKED:
src/components/useAuth.ts # Hooks not in components/
src/utils/useDebounce.ts # Hooks not in utils/
src/services/useFetch.ts # Hooks not in services/Python File Location Rules
Routers
ALLOWED:
app/routers/router_users.py
app/routers/routes_auth.py
app/routers/api_v1.py
BLOCKED:
app/users_router.py # Not in routers/
app/services/router_users.py # Router in services/Services
ALLOWED:
app/services/user_service.py
app/services/auth_service.py
BLOCKED:
app/user_service.py # Not in services/
app/routers/user_service.py # Service in routers/Common Violations
1. Too Deep Nesting
BLOCKED: Max nesting depth exceeded: 5 levels (max: 4)
File: src/features/dashboard/widgets/charts/line/LineChart.tsx
Consider flattening: src/features/dashboard/charts/LineChart.tsx2. Barrel File Created
BLOCKED: Barrel files (index.ts) discouraged - causes tree-shaking issues
File: src/components/index.ts
Import directly from source files instead3. Component in Wrong Location
BLOCKED: React components must be in components/, features/, or app/
File: src/utils/Button.tsx
Move to: src/components/Button.tsx4. Invalid Import Direction
BLOCKED: Import direction violation (unidirectional architecture)
features/ cannot import from app/
Import direction: features -> shared, lib, components
Allowed flow: shared/lib -> components -> features -> app5. Cross-Feature Import
BLOCKED: Cannot import from other features (cross-feature dependency)
File: src/features/auth/useAuth.ts
Import: from '@/features/dashboard/context'
Extract shared code to shared/ or lib/Migration Guide
Flattening Deep Nesting
# Before (5 levels)
src/features/dashboard/widgets/charts/line/LineChart.tsx
src/features/dashboard/widgets/charts/line/LineChartTooltip.tsx
# After (4 levels) - Flatten last two levels
src/features/dashboard/charts/LineChart.tsx
src/features/dashboard/charts/LineChartTooltip.tsxRemoving Barrel Files
# Before
src/components/index.ts # Re-exports everything
import { Button, Input } from '@/components';
# After - Direct imports
import { Button } from '@/components/Button';
import { Input } from '@/components/Input';Fixing Cross-Feature Imports
# Before - Cross-feature dependency
src/features/auth/useAuth.ts imports from src/features/users/types
# After - Extract to shared
src/shared/types/user.ts
src/features/auth/useAuth.ts imports from src/shared/types/user
src/features/users/... imports from src/shared/types/userRelated Skills
backend-architecture-enforcer- FastAPI layer separationclean-architecture- DDD patternstype-safety-validation- TypeScript strictness
Capability Details
folder-structure
Keywords: folder structure, directory structure, project layout, organization Solves:
- Enforce feature-based organization
- Validate proper file placement
- Maintain consistent project structure
nesting-depth
Keywords: nesting, depth, levels, max depth, deep nesting Solves:
- Limit directory nesting to 4 levels
- Prevent overly complex structures
- Improve navigability
import-direction
Keywords: import, unidirectional, circular, dependency direction Solves:
- Enforce unidirectional imports
- Prevent circular dependencies
- Maintain clean architecture
component-location
Keywords: component location, file placement, where to put Solves:
- Validate React component placement
- Enforce hook location rules
- Block barrel files
Project Structure Violations
Reference guide for common folder structure and import direction violations.
---
1. Excessive Nesting Depth
Proper Pattern
src/
├── features/
│ └── dashboard/
│ └── charts/
│ └── LineChart.tsx # 4 levels from src/ - ALLOWED// src/features/dashboard/charts/LineChart.tsx
// Flat structure with co-located components
import { ChartTooltip } from './ChartTooltip';
import { ChartLegend } from './ChartLegend';
import { useChartData } from './useChartData';
export function LineChart({ data }: LineChartProps) {
const { processedData } = useChartData(data);
return (
<div className="chart-container">
<svg>{/* chart rendering */}</svg>
<ChartTooltip />
<ChartLegend />
</div>
);
}Anti-Pattern (VIOLATION)
src/
├── features/
│ └── dashboard/
│ └── widgets/
│ └── charts/
│ └── line/
│ └── LineChart.tsx # 6 levels - VIOLATION!
│ └── components/
│ └── Tooltip.tsx # 7 levels - VIOLATION!// src/features/dashboard/widgets/charts/line/components/Tooltip.tsx
// VIOLATION: 7 levels deep from src/
// Long import paths become unwieldy
import { formatNumber } from '../../../../../../utils/format';
import { theme } from '../../../../../../styles/theme';Why It Matters
- Navigation Difficulty: Deep nesting makes finding files tedious
- Import Complexity: Long relative paths like
../../../../../are error-prone - Mental Overhead: Developers struggle to track deep hierarchies
- IDE Performance: Some IDEs slow down with deeply nested structures
Auto-Fix Suggestion
1. Flatten the structure by combining related levels:
# Before (6 levels)
src/features/dashboard/widgets/charts/line/LineChart.tsx
# After (4 levels)
src/features/dashboard/charts/LineChart.tsx2. Co-locate related files instead of creating sub-directories:
src/features/dashboard/charts/
├── LineChart.tsx
├── LineChartTooltip.tsx
├── LineChartLegend.tsx
└── useLineChartData.ts---
2. Barrel Files (index.ts Re-exports)
Proper Pattern
// Direct imports - each file imported explicitly
// src/app/page.tsx
import { Button } from '@/components/ui/Button';
import { Card } from '@/components/ui/Card';
import { Modal } from '@/components/ui/Modal';
import { useAuth } from '@/hooks/useAuth';
import { useLocalStorage } from '@/hooks/useLocalStorage';Anti-Pattern (VIOLATION)
// VIOLATION: src/components/index.ts (barrel file)
export { Button } from './ui/Button';
export { Card } from './ui/Card';
export { Modal } from './ui/Modal';
export { Input } from './forms/Input';
export { Select } from './forms/Select';
export { Checkbox } from './forms/Checkbox';
// ... 50 more exports
// VIOLATION: src/hooks/index.ts (barrel file)
export { useAuth } from './useAuth';
export { useLocalStorage } from './useLocalStorage';
export { useDebounce } from './useDebounce';
// ... more exports
// Consumer code using barrel imports
// src/app/page.tsx
import { Button, Card } from '@/components'; // Imports ENTIRE barrel
import { useAuth } from '@/hooks'; // Imports ENTIRE barrelWhy It Matters
- Tree-Shaking Failure: Bundlers import the entire barrel, not just used exports
- Bundle Size: Unused components still end up in production bundle
- Build Performance: Barrel files slow down build times significantly
- Circular Dependencies: Barrels create hidden circular import chains
- HMR Slowdown: Hot Module Replacement must process entire barrel on changes
Auto-Fix Suggestion
1. Delete all index.ts files that only re-export 2. Update imports to use direct paths:
// Before (barrel import)
import { Button, Card } from '@/components';
// After (direct imports)
import { Button } from '@/components/ui/Button';
import { Card } from '@/components/ui/Card';3. Configure ESLint to prevent barrel file creation:
// .eslintrc.js
rules: {
'no-restricted-imports': ['error', {
patterns: ['**/index']
}]
}---
3. Invalid Import Direction (Circular Architecture)
Proper Pattern
Import direction flows ONE WAY:
shared/lib --> components --> features --> app
(lowest) (highest)// CORRECT: src/features/auth/LoginForm.tsx
// Feature imports from lower layers only
import { Button } from '@/components/ui/Button'; // components -> features OK
import { Input } from '@/components/forms/Input'; // components -> features OK
import { validateEmail } from '@/lib/validation'; // lib -> features OK
import { useAuth } from './hooks/useAuth'; // same feature OK// CORRECT: src/components/ui/Button.tsx
// Component imports only from shared/lib layer
import { cn } from '@/lib/utils'; // lib -> components OK
import type { ButtonVariant } from '@/types/ui'; // types -> components OKAnti-Pattern (VIOLATION)
// VIOLATION: src/shared/utils.ts
// Shared layer importing from features layer
import { AUTH_CONFIG } from '@/features/auth/config'; // VIOLATION!
import { formatUserName } from '@/features/users/utils'; // VIOLATION!// VIOLATION: src/features/auth/useAuth.ts
// Feature importing from app layer
import { RootLayout } from '@/app/layout'; // VIOLATION!
import { metadata } from '@/app/page'; // VIOLATION!// VIOLATION: src/features/auth/useAuth.ts
// Cross-feature import (features should not import from each other)
import { DashboardContext } from '@/features/dashboard/context'; // VIOLATION!
import { useCart } from '@/features/cart/hooks/useCart'; // VIOLATION!// VIOLATION: src/components/ui/UserAvatar.tsx
// Component importing from features layer
import { useCurrentUser } from '@/features/auth/hooks/useCurrentUser'; // VIOLATION!
import { UserProfile } from '@/features/users/types'; // VIOLATION!Why It Matters
- Circular Dependencies: Bi-directional imports create runtime errors
- Build Failures: Webpack/Vite cannot resolve circular module graphs
- Code Splitting: Circular deps prevent effective code splitting
- Maintainability: Tangled dependencies make refactoring impossible
- Testing: Cannot test components in isolation
Auto-Fix Suggestion
1. For shared/ importing from features/:
- Extract the needed code to
shared/where it belongs
// Move features/auth/config.ts content to shared/config/auth.ts2. For features/ importing from app/:
- App layer should not export utilities; move to appropriate layer
- If needed in feature, it belongs in
shared/orlib/
3. For cross-feature imports:
- Extract shared types/utilities to
shared/:
// Before: features/auth imports from features/users
// After: Extract to shared/types/user.ts
// Both features import from shared/4. For components/ importing from features/:
- Component should receive data as props, not fetch it
- Move hook usage to feature component that uses the UI component
---
4. Components in Wrong Directory
Proper Pattern
src/
├── components/ # Reusable UI components
│ ├── ui/
│ │ ├── Button.tsx
│ │ ├── Card.tsx
│ │ └── Modal.tsx
│ └── forms/
│ ├── Input.tsx
│ └── Select.tsx
├── features/ # Feature-specific components
│ └── auth/
│ └── components/
│ ├── LoginForm.tsx
│ └── RegisterForm.tsx
├── hooks/ # Global custom hooks
│ ├── useAuth.ts
│ └── useLocalStorage.ts
└── app/ # Page components (Next.js)
└── dashboard/
└── page.tsxAnti-Pattern (VIOLATION)
src/
├── utils/
│ ├── Button.tsx # VIOLATION: Component in utils/
│ └── formatDate.ts
├── services/
│ ├── Modal.tsx # VIOLATION: Component in services/
│ └── api.ts
├── lib/
│ └── Dropdown.tsx # VIOLATION: Component in lib/
├── hooks/
│ └── UserAvatar.tsx # VIOLATION: Component in hooks/
└── components/
├── useAuth.ts # VIOLATION: Hook in components/
└── useFetch.ts # VIOLATION: Hook in components/Why It Matters
- Discoverability: Developers expect components in
components/orfeatures/ - Consistency: Mixed purposes in directories creates confusion
- Code Reviews: Harder to enforce patterns with inconsistent structure
- Tooling: File generators and linters rely on predictable locations
Auto-Fix Suggestion
| Current Location | Correct Location |
|---|---|
src/utils/Button.tsx | src/components/ui/Button.tsx |
src/services/Modal.tsx | src/components/ui/Modal.tsx |
src/lib/Dropdown.tsx | src/components/ui/Dropdown.tsx |
src/hooks/UserAvatar.tsx | src/components/UserAvatar.tsx |
src/components/useAuth.ts | src/hooks/useAuth.ts |
src/components/useFetch.ts | src/hooks/useFetch.ts |
Detection Rules:
- Files matching
*.tsxwith PascalCase names are React components - Files matching
use*.tsare custom hooks - Components should be in
components/,features/*/components/, orapp/ - Hooks should be in
hooks/orfeatures/*/hooks/
---
5. Python Files in Wrong Layer Directories
Proper Pattern
app/
├── routers/ # HTTP handlers only
│ ├── router_users.py
│ ├── router_auth.py
│ └── deps.py
├── services/ # Business logic only
│ ├── user_service.py
│ └── auth_service.py
├── repositories/ # Data access only
│ ├── user_repository.py
│ └── base_repository.py
├── schemas/ # Pydantic schemas only
│ ├── user_schema.py
│ └── auth_schema.py
└── models/ # SQLAlchemy models only
├── user_model.py
└── base.pyAnti-Pattern (VIOLATION)
app/
├── router_users.py # VIOLATION: Router not in routers/
├── user_service.py # VIOLATION: Service not in services/
├── routers/
│ ├── user_service.py # VIOLATION: Service in routers/
│ └── user_repository.py # VIOLATION: Repository in routers/
├── services/
│ ├── router_auth.py # VIOLATION: Router in services/
│ └── user_model.py # VIOLATION: Model in services/
└── models/
└── user_schema.py # VIOLATION: Schema in models/Why It Matters
- Architecture Clarity: Each directory represents a distinct layer
- Import Organization: Clear layer boundaries prevent circular imports
- Onboarding: New developers understand the codebase faster
- Refactoring: Layer changes are isolated to specific directories
Auto-Fix Suggestion
| Current Location | Correct Location |
|---|---|
app/router_users.py | app/routers/router_users.py |
app/user_service.py | app/services/user_service.py |
app/routers/user_service.py | app/services/user_service.py |
app/routers/user_repository.py | app/repositories/user_repository.py |
app/services/router_auth.py | app/routers/router_auth.py |
app/services/user_model.py | app/models/user_model.py |
app/models/user_schema.py | app/schemas/user_schema.py |
---
Quick Reference: Structure Rules
| Rule | Frontend (React/Next.js) | Backend (FastAPI) |
|---|---|---|
| Max Nesting | 4 levels from src/ | 4 levels from app/ |
| Components | components/, features/*/components/ | N/A |
| Hooks | hooks/, features/*/hooks/ | N/A |
| Routers | N/A | routers/router_*.py |
| Services | services/ (API clients) | services/*_service.py |
| Repositories | N/A | repositories/*_repository.py |
| Barrel Files | BLOCKED (index.ts) | N/A |
Import Direction Quick Reference
ALLOWED DIRECTIONS:
shared/ -> (nothing)
lib/ -> shared/
utils/ -> shared/, lib/
components/ -> shared/, lib/, utils/
features/ -> shared/, lib/, utils/, components/
app/ -> shared/, lib/, utils/, components/, features/
BLOCKED DIRECTIONS:
shared/ -> components/, features/, app/
lib/ -> components/, features/, app/
components/ -> features/, app/
features/ -> app/, other features/