React mı Vue mı: 2025 Yılında Frontend Framework Seçimi

Geçen ay bir startup müşterimiz bana geldi ve “Hocam, yeni projemize başlıyoruz, React mi kullansak Vue mu?” diye sordu. Saatler süren bir toplantı yerine, ona şunu söyledim: “Bana projenin ölçeğini, ekibini ve zaman çizelgesini anlat, gerisini konuşuruz.” Çünkü bu sorunun tek bir doğru cevabı yok, ama her proje için doğru bir cevap var.

2025 yılında bu tartışma hâlâ devam ediyor ve doğrusu, bunun devam etmesi gerekiyor. İki framework de olgunlaştı, ikisi de production-ready, ikisi de büyük ölçekli projelerde kullanılıyor. Peki sistem yöneticisi veya DevOps mühendisi olarak biz bu tartışmada neredeyiz? Çok daha merkezi bir yerdeyiz aslında: CI/CD pipeline’larını kuran, build süreçlerini optimize eden, deployment stratejilerini belirleyen biziz. Framework seçimi bizim işimizi doğrudan etkiliyor.

Neden Bu Konuşmayı Bir Sysadmin Yapıyor?

Frontend framework seçimi sadece geliştiricilerin meselesi değil. Build artifact boyutları, Docker image stratejileri, CDN konfigürasyonları, environment variable yönetimi, server-side rendering kararları… Bunların hepsi ops tarafını doğrudan ilgilendiriyor.

React ve Vue’nun production davranışlarını, build çıktılarını ve deployment gereksinimlerini yakından tanıyan biri olarak konuşuyorum. Her iki framework ile de production ortamlarında ciddi süre geçirdim. Şimdi somut deneyimlere dayanarak aktarayım.

Build Süreci ve Artifact Yönetimi

İki framework’ün de 2025 itibarıyla build tooling tarafı oldukça gelişti. React tarafında Vite artık Create React App’in yerini fiilen aldı. Vue zaten Vite’ı çok daha erken benimsedi çünkü ikisi de aynı ekipten çıkıyor (Evan You hem Vue’nun hem Vite’ın yaratıcısı).

Tipik bir React projesi için Vite tabanlı build konfigürasyonu:

# React projesi oluşturma (Vite ile)
npm create vite@latest my-react-app -- --template react-ts
cd my-react-app
npm install
npm run build

# Build çıktısını incele
ls -lah dist/
du -sh dist/assets/

Vue tarafında durum benzer:

# Vue projesi oluşturma
npm create vue@latest my-vue-app
cd my-vue-app
npm install
npm run build

# Build çıktısını incele
ls -lah dist/
find dist -name "*.js" | xargs wc -c | sort -n

Burada dikkat etmem gereken nokta chunk splitting stratejisi. Büyük projelerde Vue’nun Single File Component yapısı, tree-shaking açısından biraz daha avantajlı sonuçlar verebiliyor. React’ta aynı sonucu elde etmek için biraz daha manuel konfigürasyon gerekebiliyor.

# Vite konfigürasyonu ile manuel chunk splitting (React)
cat > vite.config.ts << 'EOF'
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          vendor: ['react', 'react-dom'],
          router: ['react-router-dom'],
        }
      }
    },
    chunkSizeWarningLimit: 500
  }
})
EOF

Docker ve Container Stratejileri

İki framework için de multi-stage Docker build kullanıyorum. Ama aralarında ince farklar var.

React için tipik bir production Dockerfile:

# React için multi-stage Dockerfile
cat > Dockerfile << 'EOF'
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production=false
COPY . .
RUN npm run build

FROM nginx:alpine AS runner
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
EOF

# Image boyutunu kontrol et
docker build -t react-app:latest .
docker images react-app:latest --format "table {{.Repository}}t{{.Tag}}t{{.Size}}"

Vue için pratik olarak aynı Dockerfile işe yarıyor çünkü her ikisi de statik dosyalar üretiyor. Fark nerede peki? SSR (Server-Side Rendering) kullandığınızda.

Vue’nun Nuxt.js ile SSR deployment’ı:

# Nuxt.js için Node.js tabanlı Dockerfile
cat > Dockerfile.nuxt << 'EOF'
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/.output ./
EXPOSE 3000
CMD ["node", "server/index.mjs"]
EOF

React tarafında Next.js ile benzer bir yapı kurulabiliyor. 2025’te her iki ekosistem de bu konuda birbirine yakınsadı. Nuxt 3 ve Next.js 14+ arasındaki deployment kompleksitesi açısından artık çok büyük fark yok.

CI/CD Pipeline Entegrasyonu

GitHub Actions ile iki framework’ü de build eden, test eden ve deploy eden pipeline’lar kuruyoruz. Burada dikkat ettiğim birkaç nokta var.

Cache stratejisi kritik. Node modules cache’lenmezse her build 2-3 dakika uzuyor. Her iki framework için aynı yaklaşım geçerli:

# GitHub Actions workflow örneği
cat > .github/workflows/deploy.yml << 'EOF'
name: Build and Deploy

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Run tests
        run: npm run test -- --coverage --watchAll=false
      
      - name: Build
        run: npm run build
        env:
          VITE_API_URL: ${{ secrets.API_URL }}
          VITE_ENV: production
      
      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: dist
          path: dist/
          retention-days: 7
EOF

Burada önemli bir nokta: React ve Vue’da environment variable isimlendirme farklı. React’ta REACT_APP_ prefix’i kullanılırken (Create React App için), Vite tabanlı projelerde her iki framework de VITE_ prefix’ini kullanıyor. Bu pipeline’larınızı standarize ederken işinizi kolaylaştırıyor.

Nginx Konfigürasyonu ve SPA Routing

Her iki framework de SPA (Single Page Application) olarak kullanıldığında aynı Nginx konfigürasyonuna ihtiyaç duyuyor. Bu konfigürasyonu doğru yapmazsanız, kullanıcılar doğrudan bir URL’e gittiğinde 404 alıyor.

cat > nginx.conf << 'EOF'
events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css application/json 
               application/javascript text/xml 
               application/xml text/javascript;

    server {
        listen 80;
        root /usr/share/nginx/html;
        index index.html;

        # Static asset caching
        location ~* .(js|css|png|jpg|jpeg|gif|ico|svg|woff2)$ {
            expires 1y;
            add_header Cache-Control "public, immutable";
        }

        # SPA routing - her iki framework için aynı
        location / {
            try_files $uri $uri/ /index.html;
        }

        # Security headers
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    }
}
EOF

Bu konfigürasyon hem React hem Vue SPA projeleri için birebir aynı çalışıyor. Ops açısından framework farkı burada sıfıra iniyor.

Ekip Dinamikleri ve Öğrenme Eğrisi: Gerçekçi Bir Değerlendirme

Teknik konuların dışında, insan faktörünü de ele almak gerekiyor. Çünkü en iyi framework, ekibinizin hızla adapte olabildiği ve üretken olabildiği framework’tür.

Vue’nun öğrenme eğrisi genellikle daha düz. Özellikle jQuery veya vanilla JavaScript geçmişi olan geliştiriciler Vue’ya çok daha hızlı adapte oluyor. Türkiye’deki birçok ajans ve küçük-orta ölçekli şirketin Vue’ya yönelmesinin temel sebebi bu bence. Template syntax’ı HTML’e daha yakın, Composition API ise modern JavaScript geliştirmecilerine çok tanıdık geliyor.

React’ın ekosistemi ise tartışmasız daha geniş. npm’de React için yazılmış kütüphane sayısı Vue’nun birkaç katı. İş ilanlarına bakıldığında da React baskın. Özellikle büyük şirketlerde, fintech’te, e-ticarette React hakimiyeti devam ediyor.

Bir karşılaştırma yapalım. Aynı form validation mantığını her iki framework’te nasıl kuruyoruz:

# Vue 3 Composition API ile form validation
cat > FormComponent.vue << 'EOF'
<script setup>
import { ref, computed } from 'vue'

const email = ref('')
const password = ref('')

const isEmailValid = computed(() => 
  /^[^s@]+@[^s@]+.[^s@]+$/.test(email.value)
)

const isFormValid = computed(() => 
  isEmailValid.value && password.value.length >= 8
)

const handleSubmit = async () => {
  if (!isFormValid.value) return
  // API call
}
</script>

<template>
  <form @submit.prevent="handleSubmit">
    <input v-model="email" type="email" />
    <span v-if="!isEmailValid && email">Geçersiz email</span>
    <input v-model="password" type="password" />
    <button :disabled="!isFormValid" type="submit">
      Giriş Yap
    </button>
  </form>
</template>
EOF
# React ile aynı form validation
cat > FormComponent.tsx << 'EOF'
import { useState, useMemo } from 'react'

export function LoginForm() {
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')

  const isEmailValid = useMemo(() => 
    /^[^s@]+@[^s@]+.[^s@]+$/.test(email), [email]
  )

  const isFormValid = isEmailValid && password.length >= 8

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    if (!isFormValid) return
    // API call
  }

  return (
    <form onSubmit={handleSubmit}>
      <input value={email} onChange={e => setEmail(e.target.value)} 
             type="email" />
      {!isEmailValid && email && <span>Geçersiz email</span>}
      <input value={password} 
             onChange={e => setPassword(e.target.value)} 
             type="password" />
      <button disabled={!isFormValid} type="submit">
        Giriş Yap
      </button>
    </form>
  )
}
EOF

Gördüğünüz gibi mantıksal olarak neredeyse aynı iki yaklaşım. Vue biraz daha az boilerplate içeriyor (v-model sayesinde), React ise daha explicit. Hangisi daha iyi? Bu sorunun cevabı ekibinizin tercihine ve alışkanlıklarına göre değişiyor.

Performance Monitoring ve Production Gözlemleri

Production’da her iki framework’ü de izlerken dikkat ettiğim metrikler var. Core Web Vitals özellikle önemli.

# Lighthouse CI ile performance test
npm install -g @lhci/cli

# lighthouserc.js oluştur
cat > lighthouserc.js << 'EOF'
module.exports = {
  ci: {
    collect: {
      url: ['http://localhost:3000', 'http://localhost:3000/dashboard'],
      startServerCommand: 'npm run preview',
      numberOfRuns: 3,
    },
    assert: {
      assertions: {
        'categories:performance': ['error', { minScore: 0.8 }],
        'categories:accessibility': ['warn', { minScore: 0.9 }],
        'first-contentful-paint': ['warn', { maxNumericValue: 2000 }],
        'largest-contentful-paint': ['error', { maxNumericValue: 3000 }],
      },
    },
    upload: {
      target: 'temporary-public-storage',
    },
  },
}
EOF

# CI pipeline'ına ekle
lhci autorun

Deneyimlerimden şunu söyleyebilirim: İyi yazılmış bir Vue uygulaması ile iyi yazılmış bir React uygulaması arasında production’da anlamlı bir performance farkı göremedim. Fark varsa genellikle framework seçiminden değil, kodun kalitesinden ve mimariden kaynaklanıyor.

Bundle size açısından Vue 3 runtime’ı React + ReactDOM’dan biraz daha küçük. Ama bu fark pratikte çok da belirleyici değil, özellikle gzip ile birlikte düşününce.

2025’te Gerçek Dünya Senaryoları: Hangi Durumda Hangisi?

Teoride her şey güzel görünüyor. Pratik deneyimlerime dayanarak birkaç senaryo çizelim.

Senaryo 1: Kurumsal bir şirketin iç kullanım portali

Ekip 3-5 kişi, PHP/jQuery geçmişi var, deadline sıkı. Burada Vue’yu tercih ederim. Öğrenme eğrisi düşük, Options API ile JQuery mantığına alışkın birine bile Vue anlatılabilir, hızlı geliştirme sağlanır.

Senaryo 2: Büyük ölçekli e-ticaret platformu

10+ geliştirici, uzun vadeli proje, React ekosisteminden kütüphanelere ihtiyaç var. Burada React. Daha geniş kütüphane ekosistemi, daha kolay işe alım, daha fazla kaynak.

Senaryo 3: İçerik odaklı platform (blog, haber sitesi)

SEO kritik, hız kritik. Burada framework’ten önce SSR kararı önemli. Next.js (React) veya Nuxt.js (Vue) arasında seçim yaparken ekibin hangisini bildiğine bakın. Her ikisi de bu senaryo için mükemmel çözümler sunuyor.

Senaryo 4: Startup MVP

Hız kritik, ekip küçük. Burada kim ne biliyorsa onu kullanın. Gerçekten. MVP aşamasında framework tartışması vakit kaybı.

State Management: Pinia vs Zustand

2025’te her iki framework’ün state management çözümleri de olgunlaştı.

Vue tarafında Pinia artık Vuex’in yerini tamamen aldı ve gerçekten çok daha temiz bir API sunuyor.

React tarafında Zustand ve Jotai gibi hafif çözümler Redux’un yerini büyük ölçüde aldı. Redux hâlâ büyük projelerde kullanılıyor ama yeni projelerde artık ilk tercih değil.

Her iki çözüm de DevTools entegrasyonu, TypeScript desteği ve minimal boilerplate açısından benzer konumda. Bu konuda da framework seçimini etkileyecek büyük bir fark yok.

DevOps Ekipleri İçin Pratik Öneri Listesi

Framework’ü seçerken ops ekibinin dikkat etmesi gereken maddeler:

  • Build süresi: Her iki framework Vite kullandığında yakın. Cold build için benchmark alın.
  • Output format: Static export, SSR, SSG seçeneklerini değerlendirin, bunlar deployment stratejinizi belirleyecek.
  • Environment variable yönetimi: Vite tabanlı her iki framework de .env dosyalarını aynı şekilde işliyor.
  • Health check endpoint’leri: SSR kullanıyorsanız Node.js process yönetimi için PM2 veya systemd konfigürasyonu gerekiyor.
  • Image boyutu: Static site için nginx:alpine yeterli, SSR için node:alpine gerekiyor.
  • Memory kullanımı: SSR uygulamalarda Node.js process’in memory limitlerini K8s veya Docker’da tanımlayın.
# Kubernetes deployment için resource limits örneği (SSR uygulama)
cat > k8s-deployment.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend-app
spec:
  replicas: 3
  template:
    spec:
      containers:
        - name: app
          image: myapp:latest
          ports:
            - containerPort: 3000
          resources:
            requests:
              memory: "128Mi"
              cpu: "100m"
            limits:
              memory: "256Mi"
              cpu: "500m"
          livenessProbe:
            httpGet:
              path: /health
              port: 3000
            initialDelaySeconds: 10
            periodSeconds: 30
          readinessProbe:
            httpGet:
              path: /ready
              port: 3000
            initialDelaySeconds: 5
            periodSeconds: 10
EOF

Sonuç

“React mi Vue mu?” sorusuna 2025’te verilecek dürüst cevap şu: İkisi de harika, ikisi de production-ready, ikisi de yeterince olgun.

Ops ve DevOps perspektifinden bakıldığında fark daha da azalıyor. Her iki framework de Vite ile build ediliyor, her ikisi de Docker ile containerize ediliyor, her ikisi de aynı CI/CD araçlarıyla deploy ediliyor. Nginx konfigürasyonu neredeyse aynı, monitoring yaklaşımı aynı, environment variable yönetimi aynı.

Seçim kriteri şunlar olmalı: Ekibin mevcut bilgisi (bunu küçümsemeyin, en kritik faktör bu), projenin ölçeği ve ömrü, ekosistem ihtiyaçları ve işe alım pazarı (uzun vadeli projeler için önemli).

Eğer ekibinizde bu konuda fikir birliği oluşamıyorsa, şunu söylerim: Vue ile başlayın. Öğrenmesi daha kolay, daha az opinionated, ve eğer bir gün React’a geçmek zorunda kalırsanız, Composition API ile edindiğiniz alışkanlıklar React Hooks’a çok benziyor. Geçiş o kadar da zor olmaz.

Framework savaşlarına zaman harcamak yerine, iyi bir mimariye, sağlam test altyapısına ve düzgün CI/CD pipeline’larına yatırım yapın. İşte asıl fark yaratan bunlar.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir