Feature-Driven Proje Yapısı
React projelerine başlarken genellikle components, hooks ve utils gibi teknik klasörler oluştururuz. Ancak proje büyüdükçe, hangi bileşenin hangi özellikle ilgili olduğunu bulmak zorlaşır ve bu klasörler birer çöplüğe dönüşür. Bu yazıda, kodu teknik türüne göre değil, işlevine göre gruplayan feature-driven (özellik odaklı) mimariyi ele alacağız.

Birlikte Değişen Kodlar, Birlikte Yaşamalı
TkDodo ve Dan Abramov gibi isimlerin sıkça vurguladığı temel bir kural vardır: Birlikte değişen kodlar, birlikte yaşamalıdır. Birçok projede useTheme ile useTodo hook'ları aynı klasörde dururken, useTheme ile ThemeProvider bileşeni ayrı yerlerde bulunur. Bu durum küçük projelerde sorun yaratmasa da, proje büyüdükçe kodun takibini zorlaştırır ve ölçeklenebilirliği düşürür.
Feature-driven yaklaşım, uygulamanın her bir özelliğini kendi içinde bağımsız birer mini-uygulama gibi tasarlar.
src/
├── features/
│ ├── auth/
│ │ ├── api/
│ │ ├── components/
│ │ ├── hooks/
│ │ ├── schemas/
│ │ └── index.ts
│ └── dashboard/
├── components/
│ └── shared/
└── lib/Bu yapı sayesinde, projenin klasörlerine baktığınızda uygulamanın sadece React ile yazıldığını değil, ne işe yaradığını doğrudan anlarsınız.
Sınırlar ve Public API
Bu mimarinin en güçlü yanı sınırları net çizmesidir. Her feature klasöründeki index.ts dosyası, o özelliğin dışarıya açılan kapısıdır (Public API).
// src/features/auth/index.ts
// Sadece dışarıdan erişilmesi gerekenleri dışa aktarıyoruz
export { LoginForm } from "./components/login-form"
export { useAuth } from "./hooks/use-auth"
export { loginSchema } from "./schemas/auth.schema"
// utils/ veya private bileşenler dışa aktarılmaz!Bir feature, başka bir feature'ın içindeki private bir bileşeni doğrudan import edemez. Sadece index.ts üzerinden izin verilen bileşenlere erişilebilir. Bu kural ESLint ile otomatik denetlenerek spagetti kod oluşumu engellenir.
Ortak Kullanılan Kodlar (Shared)
Eğer bir bileşen, hook veya şema birden fazla feature tarafından kullanılmaya başlanırsa, o kod features/ klasöründen çıkarılıp src/components/shared veya src/lib gibi global katmanlara taşınır. Böylece hem kod tekrarı önlenir hem de sınırlar korunur.
Küçük Projeler İçin Uygun Mu?
Her mimari kararın bir bedeli vardır. 3-5 sayfalık basit bir portfolyo veya blog sitesi için her özelliği alt klasörlere bölmek ve index.ts üzerinden dışa aktarmak gereksiz bir iş yükü (boilerplate) yaratır.
Küçük projelerde tip tabanlı basit bir yapı dosyaları bulmak için yeterlidir. Feature-driven yapı, küçük bir projede geliştirme hızını artırmak yerine yavaşlatır. Ölçeklenebilirlik ihtiyacı doğduğunda bu geçişi yapmak daha mantıklıdır.
Kuralları Otomatize Etmek
Feature-driven mimariyi manuel olarak korumak, özellikle kalabalık ekiplerde zordur. Sürekli "bu dosya nereye gidecek" veya "ortak klasöre ne zaman taşınacak" tartışması yaşanır.
Bu noktada, mimari kuralları yapay zekâ asistanlarına (Cursor vb.) otomatik uygulatan ViraStack AI paketini kullanabilirsiniz. Projenizin mimari standartlarını belirler, klasör yapınızı korur ve AI'ın bu kuralların dışına çıkarak projeyi çöplüğe çevirmesini engeller.