Exploring Infinite Possibilities on FrontEnd 🚀
Burak Sağlık
Search...

Fri Aug 14 2026

HTMX vs React: Projeniz İçin Hangisini Seçmelisiniz?

HTMX vs React: Projeniz İçin Hangisini Seçmelisiniz?

Giriş: Neden Bu Karar Önemli?

Ben de bir zamanlar HTMX mi, React mi? diye gece yarısı GitHub issue'ları okuyup, Reddit thread'lerinde kaybolmuşum. İkisi de "modern web" diyor ama felsefeleri tam ters köşelerde duruyor.

Kısaca özetlemek gerekirse:

  • Reactİstemci odaklı (Client-first): Tarayıcıda bir "uygulama" çalıştırıyorsun. State, routing, rendering hepsi senin makinede. Sunucu daha çok JSON API görevinde.
  • HTMXSunucu odaklı (Server-first): Mantık, template'ler, veritabanı erişimi sunucuda kalıyor. Tarayıcı sadece hypermedia (HTML) alıyor ve yerleştiriyor.

Bu fark sadece "hangi kütüphane" değil; takım yapınızı, deploy stratejinizi, hatta debugging alışkanlıklarınızı değiştiriyor.


Bu yazıdan ne kazanacaksın?

  • Projen içerik ağırlıklı mı, yoksa etkileşim yoğun mu? → Hangi tarafı tercih etmen gerektiği
  • Takımın backend-heavy mi, full-stack mi, frontend-heavy mi? → Hangi araçla daha hızlı gidersin
  • SEO, ilk yük hızı, offline destek gibi kriterlerde hangi trade-off'ları kabul edersin

Hazırsan hadi derinlemesine inceleyelim — karar senin, rehber benim.


HTMX Nedir? Sunucu Odaklı Hypermedia Yaklaşımı

HTMX, HTML’i bir hipermedya motoru gibi kullanmamızı sağlayan hafif bir JavaScript kütüphanesidir. Temel fikir şu: tarayıcıda karmaşık state yönetimi veya sanal DOM yerine, sunucudan hazır HTML parçaları alıp sayfaya doğrudan enjekte edersiniz. Böylece “JavaScript yazmadan dinamiklik” elde edersiniz .

Neden “Hypermedia as the Engine of Application State” (HATEOAS)?

  • Hypermedia = HTML bağlantıları, formlar, butonlar… yani kullanıcıya “sonra ne yapabileceğini” gösteren kontroller.
  • Engine of Application State = Uygulamanın durumu (hangi sayfa, hangi veri, hangi hata) bu hypermedia kontrolleri aracılığıyla ilerler.
  • HTMX bu prensibi tarayıcıya getirir: sunucu HTML döndürür, tarayıcı o HTML’i yerleştirir, kullanıcı tekrar bir hipermedya kontrolüne tıklar → döngü kapanır.

Küçük bir senaryo: “Daha fazla yorum yükle” butonu

  1. Kullanıcı “Daha fazla yorum” butonuna tıklar.
  2. Tarayıcı hx-get ile /comments?page=2 isteği atar.
  3. Sunucu sadece yorum listesinin HTML’ini (ör. <ul>…</ul>) döndürür.
  4. hx-target ve hx-swap sayesinde bu HTML, sayfadaki #comments-list elementinin içine eklenir.
  5. Kullanıcı yeni yorumları görür, sayfa yenilenmez, ekstra JS yazılmaz .
<button 
    hx-get="/comments?page=2" 
    hx-target="#comments-list" 
    hx-swap="beforeend">
    Daha fazla yorum yükle
</button>

<ul id="comments-list">
    <!-- Mevcut yorumlar burada -->
</ul>

Ne oluyor burada?

  • hx-get → hangi URL’den HTML alınacak.
  • hx-target → yanıtın hangi elemente yerleştirileceği (#comments-list).
  • hx-swap="beforeend" → yanıt, hedef elementin sonuna eklenir (içeriği koruyarak).

Bu kadar basit! Sunucu tarafında sadece parçalı HTML (partial) üretiyorsunuz, client tarafında ise HTMX o parçayı yerleştiriyor. Böylece state yönetimi sunucuda kalır, tarayıcı sadece hypermedia kontrollerini takip eder .


React Nedir? İstemci Tarafı Zengin Etkileşim

React, bileşen tabanlı bir kütüphane olarak UI’yi küçük, bağımsız parçalara böler. Her bileşen kendi state’ini yönetir, böylece veri akışı tek yönlü ve öngörülebilir olur.

Neden React?

  • Sanal DOM → Gerçek DOM ile doğrudan oynama yerine, hafif bir kopya üzerinden diff yapar. Sadece değişen kısımlar güncellenir
  • Tek Sayfa Uygulaması (SPA) → Sayfa yenilenmeden geçişler, kullanıcı deneyimini akıcı hale getirir
  • “Her şey JavaScript” felsefesi → JSX, mantık ve markup aynı dosyada. Esneklik artar ama karmaşıklık da beraberinde gelir
  • Zengin ekosistem → State yönetimi (Redux, Zustand), yönlendirme (React Router), UI kütüphaneleri (MUI, Chakra) hazırda durur

Kısaca: İstemci tarafında karmaşık durum, yönlendirme ve interaktif bileşenler gerektiğinde React, bileşen izolasyonu ve sanal DOM sayesinde performanslı ve sürdürülebilir bir yapı sunar.


Pratik bir örnek: Basit bir form bileşeni

Aşağıda useState hook’u ve onSubmit handler’ıyla küçük bir form görebilirsiniz. Kodun akışı şöyle:

  1. name state’i input’taki değeri tutar.
  2. handleSubmit fonksiyonu form gönderildiğinde çalışır, varsayılan davranışı engeller ve mesaj gösterir.
  3. JSX içinde value ve onChange ile controlled component pattern’i uygulanır.
import React, { useState } from 'react';

function SimpleForm() {
  const [name, setName] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault();           // Sayfa yenilenmesini engelle
    alert(`Merhaba, ${name}!`);   // Basit bir geri bildirim
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        İsim:
        <input
          type="text"
          value={name}
          onChange={e => setName(e.target.value)}
        />
      </label>
      <button type="submit">Gönder</button>
    </form>
  );
}

export default SimpleForm;

Ne oluyor burada?

  • useState sayesinde bileşen stateful hale gelir, veri bileşen içinde kalır.
  • onSubmit handler’ı formun doğal gönderimini engelleyip, istemci tarafında işlem yapmamızı sağlar.
  • Controlled input ile veri akışı tek yönlü ve tahmin edilebilir olur .

Bu basit yapı, daha büyük formlarda validation, async submit veya global state entegrasyonu için de temel oluşturur .


Yaygın Yanlış Anlamalar ve Tuzaaklar

Hepimiz bir zamanlar “Bu kütüphane sadece basit siteler için” ya da “React olmadan modern bir uygulama yapamazsın” dedik.
Gerçek hayatta bu mitler projeyi yanlış yola sokabiliyor. Hadi en yaygın yanlışları tek tek irdeleyelim

1 “HTMX sadece basit siteler için”

  • Gerçek: HTMX, sunucu tarafında render edilen HTML parçalarını dinamik hale getirir.
  • Örnek: Bir e‑ticaret sepeti düşünün. Kullanıcı “Sepete Ekle” dediğinde, sunucu sadece sepet özeti partial’ını döner ve HTMX bunu sayfaya yerleştirir.
  • Sonuç: Karmaşık durum yönetimi (stok, indirim, kargo hesaplaması) sunucuda kalır, frontend sadece görünüm sorumluluğu üstlenir.

2 “React her proje için şart”

  • Gerçek: React, büyük, state‑heavy, real‑time arayüzlerde parlar.
  • Örnek: Bir real‑time dashboard (canlı grafikler, WebSocket akışı, çoklu filtre) düşünelim. Burada client‑side state, virtual DOM ve component kompozisyonu büyük avantaj sağlar.
  • Tuşak: Basit bir blog veya statik içerik sitesine React eklemek, bundle boyutunu ve build karmaşıklığını gereksiz yere artırır.

3 “HTMX’de JavaScript yok”

  • Gerçek: HTMX JavaScript’i engellemez, sadece minimum JS yazarak işinizi halletmenizi sağlar.
  • Pratik: Özel bir doğrulama ya da animasyon lazım mı? Küçük bir script etiketiyle veya Alpine.js ile hafif bir dokunuş yeterli.
  • Kazanım: Kod tabanı küçülür, hata yüzeyi azalır.

4 “React performans sorunu yaratır”

  • Gerçek: Yanlış kullanım (gereksiz re‑render, büyük listelerde key eksikliği) performansı düşürür.
  • Çözüm: React.memo, useMemo, useCallback, virtualized list (react‑window) gibi araçlarla kontrollü render yaparsınız.
  • Not: Doğru yapılandırıldığında React, milyonlarca node’u bile sorunsuz yönetebilir.

Hangi senaryoda hangi yanlış iş başa çıkar?

Senaryo Yaygın Yanlış Neden Tuzağı? Doğru Yaklaşım
Basit e‑ticaret sepeti “React şart” Bundle büyür, sunucu‑render avantajı kaybolur HTMX + sunucu partial’ı
Canlı analitik dashboard “HTMX yeterli” WebSocket & client‑state yönetimi zordur React + WebSocket + state lib
Karmaşık form doğrulama “HTMX’de JS yok” Sadece sunucu validasyonu UX’i kötüleştirir HTMX + ufak Alpine.js/JS
Yüksek etkileşimli oyun arayüzü “React yavaş” Virtual DOM optimizasyonu unutulur React + memoization + canvas

Küçük bir hatırlatma

  • Teknoloji seçimi “hangi araç işi en az çabayla çözer?” sorusuyla yapılmalı.
  • Miti test et: Küçük bir prototip yazın, ölçün, sonra karar verin.
  • Karmaşıklığı yönetin: Hem HTMX hem React kendi ekosistemlerinde güçlüdür; onları karıştırıp aynı projede uygun yerlerde kullanmaktan çekinmeyin.

Özet: Yanlış anlamalar projenizi şişirir, bakımı zorlaştırır. Gerçek ihtiyaçlarınızı netleştirin, araçları o ihtiyaçlara göre seçin.


Karar Matrisi: Proje Tipine Göre Seçim Kriterleri

Hadi pratik bir örnek üzerinden anlayalım. Bu matris, projeni HTMX veya React ile başlamak arasında bir karar verebilmen için altı temel kriteri özetliyor. Sadece doğru hücreye parmak at ve gör ne happen! 🎯

İpucu: Tabloyu doldururken, her kriteri kendi projenin gerçek ihtiyaçlarına göre değerlendir. Bu sayede kafan karışmasın ve doğru teknolojiyle başlayabilesin.

| Kriter                     | HTMX uygun mu? | React uygun mu? |
|----------------------------|----------------|-----------------|
| Proje Büyüklüğü            | Evet / Orta / Hayır | Evet / Orta / Hayır |
| SEO Gereksinimi            | Evet / Orta / Hayır | Evet / Orta / Hayır |
| Gerçek Zamanlı İhtiyaç      | Evet / Orta / Hayır | Evet / Orta / Hayır |
| Takımın Backend/Frontend Dağılımı | Evet / Orta / Hayır | Evet / Orta / Hayır |
| Dağıtım Stratejisi (monorepo vs ayrı repo) | Evet / Orta / Hayır | Evet / Orta / Hayır |

Nasıl kullanacağın?

  • Proje Büyüklüğü: Küçük bir prototip ise 🎉 "Evet", büyük bir kurumsal uygulama ise "Hayır".
  • SEO Gereksinimi: Arama motoru dostu bir site mi? SEO açısından "Evet".
  • Gerçek Zamanlı İhtiyaç: WebSocket ile canlı veri akışı mı gerekiyor? Gerçek zamanlıysa "React"e doğru ok yönü. ⛔️
  • Takımın Dağılımı: Hem frontend hem backend uzmanı var mı? Her iki teknoloji de olabilir – kararı proje ihtiyaçlarına göre ver.
  • Dağıtım Stratejisi: Monorepo izliyorsun? HTMX daha basit bir entegrasyon sunabilir; ayrı repo? React ekosistemi daha geniş.

Şimdi senin sırası: tabloyu doldur, ardından hangi teknolojiye yöneleceğine hemen karar ver! ✔️


Takım Yapısı ve Yetkinliklere Göre Değerlendirme

Hazırsan başlayalım! 🎯 Her proje için tek bir teknoloji pilavı olmadığını biliyorum. İnsan faktörü, kimi konuştuğumuza, kime eğittiğimize ve hatta ekibimizin odasının düzenine bağlı olarak değişir. Hadi pratik bir örnek üzerinden anlayalım.

Benim takımım X yapısında, bu yüzden Y'yi tercih ederdim

  • Ekibim tamamen full-stack – herkes hem frontend hem backend ile oynayabiliyor.
  • HTMX kullanıyoruz çünkü JS'te vakit kaybetmeden hızlı prototipler oluşturabiliyoruz.
  • Yazılan test oranı %60 (Jest + Supertest) ve herkes birbirine test süreçlerini anlatıyor.

HTMX'i React yerine tercih etmemizin nedeni 🐱

  • Öğrenme eğrisi daha yavaş. Bir kartlı şirketin 3 haftalık onboardi ile, 1 haftalık HTMX başlangıç süreci neredeyse aynı.
  • Onboarding süresi kısa. Junior geliştiriciler için bile durumlar basit: statik HTML + biraz JavaScript = anında etkileşimli arayüz.
<button hx-get="/data" hx-target="#list">Verileri Göster</button>
<div id="list"></div>

Ne oluyor burada? Butona tıkladığımızda Sunucu ile API isteği yapılır, JSON yanıtı alırız ve aynı DOM içine bir HTML parçası yerleştirilir. JavaScript framework'ü yüklemek ya da bağlamak gerekmez.

Ayrı frontend ekibi varsa, React (veya Vite) neden? 🛠️

  • Farklı bakış açıları – CSS uzmanları, bileşen grafıkları tasarlayanlar.
  • Devam eden entegrasyon – Test süreci, CI, CSS-in-JS entegrasyonu.
  • Büyük ölçek – Herkes bağımsız modül oluşturabilir, bağımsız güncellemeler yapabilir.

Test stratejisi 🎯

  • Birim testleri → Jest + React Testing Library.
  • Entegrasyon testleri → Cypress + gerçek kullanıcı senaryoları.
  • Performans → Lighthouse + gerçek cihazlar üzerinde test.

Kısa bir kıyaslama tablosu

Full-stack (HTMX) Ayrı Frontend (React)
Öğrenme eğrisi Düşük ❗️ Orta
Onboarding Hızlı ✅ Orta
Ekip boyutu Küçük 🏡 Büyük 🎯
Özelleştirilebilirlik Yüksek 🛠️ Yüksek
Performans İyi ✨ İyi

Junior geliştirici yoğunluğu ekip yapınıza nasıl etki eder?

  • HTMX ile görevler daha küçük. Bir geliştirici giriş sayfasından tüm siteye kadar birçok şey halledebilir.
  • React ile görevler daha modüler. Junior geliştiriciler oluşturucu veya yardımcı bileşenlere odaklanabilir, aynı zamanda eğitim süreci daha yapılandırılabilir.

Takımınıza uygun seçimi yapın

  • Full-stack ekip → HTMX (veya Svelte, Alpine.js) ile başlayın. Hızlı prototiplere ve düşük JS yüküna odaklanın.
  • Ayrı frontend ekibiReact, Vue veya Angular ile devam edin. Büyük ölçeklenebilirlik, test edilebilirlik ve tip güvenliğina önem verin.

Sonuç olarak: Benim takımım X yapısında (full-stack, HTMX odaklı) olduğundan, daha fazla kod yazarken daha az geliştiriciye ihtiyaç duyabileceğimizi, ayrıca daha az konuşup daha fazla prototip çıkarabildiğimizi görüyorum. Senin takımın farklı bir yapıdaysa, senin "en sevdiğin" teknoloji de o olabilir. ✅

Nasıl çalışıyor? Teknik seçimi, hızlıca yeni teknolojileri deneyerek ve nihayetinde "ne kadar az infrastruktur, o kadar çok ürün" prensibine bağlı kalarak takımın ihtiyaçlarına göre belirleyin. En önemlisi, o seçimdeki insana güvenin. 🚀


Kod Örneği: Basit Bir Form İşlemi HTMX ile

HTMX ile sayfa yenilemeden form gönderip, sunucudan dönen kısmi HTML’i sayfaya basmak son derece basit. Aşağıda hem istemci tarafı (HTML) hem de sunucu tarafı (Express.js) kodunu tek bir blokta topladım. Her satırın ne yaptığını yorumlarla açıkladım — kopyala, npm i express çalıştır ve node server.js diyerek hemen test edebilirsin

<!-- ==== ISTEMI TARAFI (index.html) ==== -->
<!DOCTYPE html>
<html lang="tr">
<head>
  <meta charset="UTF-8">
  <title>HTMX Form Örneği</title>
  <!-- HTMX kütüphanesini CDN'den çekiyoruz -->
  <script src="https://unpkg.com/htmx.org@1.9.10"></script>
</head>
<body>
  <h1> Basit Mesaj Formu</h1>

  <!--
    hx-post      : Form verisini /api/mesaj endpoint'ine POST eder
    hx-target    : Sunucudan dönen HTML'in yerleştirileceği element (id="sonuc")
    hx-swap      : innerHTML -> mevcut içeriği değiştirir (outerHTML da olabilirdi)
  -->
  <form hx-post="/api/mesaj" hx-target="#sonuc" hx-swap="innerHTML">
    <label for="mesaj">Mesajınız:</label><br>
    <input type="text" id="mesaj" name="mesaj" placeholder="Bir şeyler yazın..." required>
    <button type="submit">Gönder</button>
  </form>

  <!-- Sunucudan gelen cevap bu div'in içine basılacak -->
  <div id="sonuc" style="margin-top:1rem; color:#2c3e50;"></div>
</body>
</html>
// ==== SUNUCU TARAFI (server.js) ====
const express = require('express');
const app = express();

// Gelen form verisini (application/x-www-form-urlencoded) parse etmek için
app.use(express.urlencoded({ extended: true }));

// Statik dosyaları (index.html) sunmak için
app.use(express.static('.'));

// POST /api/mesaj endpoint'i
app.post('/api/mesaj', (req, res) => {
  // 1 Formdan gelen "mesaj" alanını al
  const kullaniciMesaji = req.body.mesaj;

  // 2 Basit bir doğrulama (boş mu?)
  if (!kullaniciMesaji?.trim()) {
    // Hata durumunda kullanıcıya gösterilecek kısmi HTML
    return res.send('<span style="color:red;"> Mesaj boş olamaz!</span>');
  }

  // 3 Normal akış: geri dönen kısmi HTML (HTMX hedefine basılacak)
  //    Burada sadece bir <p> döndürüyoruz, ama isterseniz bir liste, kart vs. de dönebilirsiniz.
  const html = `
    <p> <strong>Sunucu cevabı:</strong> "${kullaniciMesaji}" alındı.</p>
    <small style="color:gray;">(${new Date().toLocaleTimeString('tr-TR')})</small>
  `;

  res.send(html); // HTMX bu HTML'i #sonuc div'inin içine yerleştirir
});

// Sunucuyu 3000 portunda başlat
app.listen(3000, () => {
  console.log(' Sunucu http://localhost:3000 adresinde çalışıyor');
});

Nasıl çalışıyor?

  1. Tarayıcıda index.html açılır.
  2. Kullanıcı mesajını yazar, Gönder butonuna basar.
  3. HTMX, form verisini /api/mesaj adresine POST eder (sayfa yenilenmez).
  4. Express handler:
    • req.body.mesaj ile veriyi okur.
    • Boşsa hata mesajı (kırmızı) döner.
    • Doluysa başarı mesajı (yeşil) + zaman damgası içeren küçük bir HTML parçacığı döner.
  5. HTMX, hx-target="#sonuc" ve hx-swap="innerHTML" sayesinde bu parçacığı #sonuc div'inin içine yerleştirir.
  6. Kullanıcı anında sonucu görür — hiçbir tam sayfa yenileme yok .

İpucu: hx-swap değerini outerHTML, beforeend, afterbegin gibi değiştirerek aynı yanıtı farklı yerleşim stratejileriyle kullanabilirsin. Deneme yanılma yapmak için hx-swap="beforeend" yapıp birden fazla mesajı listeye eklemeyi deneyin


Kod Örneği: Aynı Form React ile

Hadi aynı formu React'te yazalım. HTMX tarafında tek bir HTML dosyası ve birkaç attribute vardı. React tarafında ise... biraz daha "seremoni" var

Ne yapmamız gerekiyor?

  • Form verisini useState ile tutmak
  • onChange handler'ları yazmak (her input için ayrı ayrı )
  • handleSubmit içinde fetch/axios çağrısı
  • Yükleme, hata ve başarı durumlarını ayrı state'lerde yönetmek
  • Kondisyonel render ile UI'ı güncellemek

İşte kod:

import { useState } from 'react';

function ContactForm() {
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    message: ''
  });
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(null);
  const [success, setSuccess] = useState(false);

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData(prev => ({ ...prev, [name]: value }));
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    setIsLoading(true);
    setError(null);
    setSuccess(false);

    try {
      const response = await fetch('/api/contact', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(formData)
      });

      if (!response.ok) throw new Error('Sunucu hatası');
      setSuccess(true);
      setFormData({ name: '', email: '', message: '' });
    } catch (err) {
      setError(err.message);
    } finally {
      setIsLoading(false);
    }
  };

  if (success) {
    return (
      <div className="success-message">
         Mesajınız gönderildi! Teşekkürler.
        <button onClick={() => setSuccess(false)}>Yeni Mesaj</button>
      </div>
    );
  }

  return (
    <form onSubmit={handleSubmit} noValidate>
      <div>
        <label htmlFor="name">İsim</label>
        <input
          id="name"
          name="name"
          value={formData.name}
          onChange={handleChange}
          required
          disabled={isLoading}
        />
      </div>

      <div>
        <label htmlFor="email">E-posta</label>
        <input
          id="email"
          name="email"
          type="email"
          value={formData.email}
          onChange={handleChange}
          required
          disabled={isLoading}
        />
      </div>

      <div>
        <label htmlFor="message">Mesaj</label>
        <textarea
          id="message"
          name="message"
          value={formData.message}
          onChange={handleChange}
          required
          disabled={isLoading}
        />
      </div>

      {error && <div className="error"> {error}</div>}

      <button type="submit" disabled={isLoading}>
        {isLoading ? 'Gönderiliyor...' : 'Gönder'}
      </button>
    </form>
  );
}

export default ContactForm;

Ne oluyor burada?

  • 5 adet useState — form verisi, loading, error, success... hepsi ayrı state
  • handleChange — her input için name attribute'una dayalı generic bir handler (ama yine de yazdık )
  • handleSubmitfetch çağrısı, try/catch/finally, state güncellemeleri... boilerplate festivali
  • Kondisyonel render — başarı durumunda formun tamamını yerine "teşekkürler" mesajı basıyoruz
  • disabled={isLoading} — her input ve buton için tek tek tekrar

HTMX ile yan yana koyalim

Özellik HTMX React
Satır sayısı ~15 ~65
State yönetimi Sunucu tarafında (HTML) 5 ayrı useState
Event handler hx-post, hx-target attribute'leri onChange, onSubmit fonksiyonları
Yükleme/hata/başarı hx-indicator, hx-swap-oob Manuel state + kondisyonel render
Kavramsal yük HTML bilmek yeterli Component lifecycle, hooks, controlled components, event pooling...

İşte bu nedenle küçük formlar için HTMX daha az kod

React harika bir araç — ama her şeye çekiç getirmek bazen çekiçin kendisinden daha ağır gelir. Basit bir iletişim formu için bu kadar boilerplate yazmak... "kill a fly with a sledgehammer" demektir

Not: Tabii ki formunuz karmaşık client-side validasyon, özelleştirilmiş input bileşenleri, optimistic UI veya çok adımlı wizard gerektiriyorsa React'in sunduğu kontrol şart. Ama "basit bir POST atıp mesaj göster" ise? HTMX tam görevi görür.


Geçiş Stratejileri: Mevcut Projelerde Nasıl Değişim Yapılır?

Hadi durun, hepsini bir anda değiştirmeyin . Mevcut bir React projesine HTMX sokmak (veya tersi) "big bang" rewrite demek değil. Aslında en sağlıklı yol kademeli benimseme . Ben bunu "yağmur damlası" stratejisi diyorum: önce bir köşeyi ıslatırsınız, sonra yayarsınız.

1. Küçük başlayın: hx-boost ile test edin

Mevcut sayfanızda zaten çalışan bir <a> veya <form> var mı? Onun üzerine hx-boost ekleyin. Bu, sayfa yenilemesi olmadan navigasyonu HTMX'e devrediyor.

// Mevcut React bileşeninizde minimal değişiklik
export function EskiListe() {
  return (
    <div>
      <a href="/api/urunler" hx-boost="true" hx-target="#liste">
        Ürünleri HTMX ile Getir
      </a>
      <div id="liste">{/* Sunucudan gelecek HTML buraya düşer */}</div>
    </div>
  );
}

Ne oluyor burada?

  • hx-boost="true" → normal link tıklaması HTMX isteğine dönüşür.
  • hx-target="#liste" → gelen HTML, id="liste" olan div'in içine yerleşir.
  • React hiç haberdar olmaz, sadece DOM'a karışır.

2. Island Architecture: "Adalar" yaratıp izole edin

Astro'nun yaptığı gibi, sayfayı izole edilmiş interaktif adalara bölün. React bileşenleriniz "adalar" olur, geri kalanı HTMX (veya sunucu HTML'i) yönetir.

Adak İsmi Sorumluluk Teknoloji
SepetAdasi Sepet toplamı, miktar artı/azalt React (stateful)
UrunListesi Filtreleme, sayfalama, arama HTMX + Sunucu HTML
BildirimAdasi Gerçek zamanlı bildirimler React (WebSocket)

Pratik kural: Sadece gerçekten interaktif olan kısımlar React kalsın. Listeleme, detay, basit formlar → HTMX.


3. Mikro Frontend Yaklaşımı: Paylaşılan durum sorununu çözün

İki dünya bir arada olduğunda en büyük baş belası paylaşılan state. Çözüm? Event-driven iletişim.

// React tarafı: özel event fırlat
function SepetButonu({ urunId }) {
  const ekle = () => {
    window.dispatchEvent(new CustomEvent('sepet:ekle', { detail: { urunId } }));
  };
  return <button onClick={ekle}>Sepete Ekle</button>;
}

// HTMX tarafı: event'i dinle ve isteği tetikle
<div hx-post="/api/sepet" 
     hx-trigger="sepet:ekle from:window" 
     hx-vals='js:{urunId: event.detail.urunId}'>
</div>

Avantaj: React state'i HTMX'e, HTMX yanıtı React'e prop drilling veya context karışıklığı olmadan akar.


4. dangerouslySetInnerHTML Tuzağı

React içinde HTMX snippet'ları render etmek isterseniz bu prop gelir aklınıza. Dikkat!

//  Kötü örnek: XSS riski + HTMX bağlaması kopar
<div dangerouslySetInnerHTML={{ __html: sunucudanGelenHtml }} />

Neden riskli?

  • hx-on:* veya hx-trigger gibi öznitelikler React'in sanal DOM'una bağlanmaz.
  • HTMX hx-swap sonrası yeniden bağlanmayı dener ama React DOM'u yenilediğinde event listener'lar kaybolur.

Güvenli alternatif: HTMX fragment'ını ayrı bir endpoint'ten çekip hx-include / hx-target ile doğrudan DOM'a yerleştirin. React sadece konteynır olsun.


5. Kademeli Yol Haritası

Aşama Ne Yapılır? Risk
0 Mevcut projeyi dokunmaz, yeni sayfalar HTMX ile yazılır Düşük
1 hx-boost ile mevcut link/form'ları yükseltirsiniz Orta (CSS/JS çakışması)
2 Island'ları tanımlayıp React bileşenlerini izole edersiniz Orta
3 Paylaşılan state için event bus / localStorage / URL sync kurarsınız Yüksek (test edin!)
4 Eski React sayfalarını parçalar halinde HTMX'e taşırsınız Düşük (artık alışkınız)

Özetle

  • Küçük adımlarla başlayın (hx-boost harika bir ilk adım).
  • Island architecture ile hangi kısım React, hangisi HTMX kalacağını netleştirin.
  • Paylaşılan durum için CustomEvent veya URL/state sync kullanın; prop drilling'den kaçının.
  • dangerouslySetInnerHTML son çare olsun; HTMX'i DOM'un sahibi yapın, React sadece "ada" olsun.

Hazırsanız bir sonraki bölümde test stratejileri ve CI/CD entegrasyonu üzerine konuşalım.


Son Söz: Hangisini Seçerseniz Seçin, Basitlik Kazanan

Hepimiz "doğru" aracı bulmak isteriz ama gerçek şu: evrensel bir doğru yok. Projenin doğası, takımınızın deneyimi, zaman kısıtlamaları ve hatta şirket kültürü... Hepsi kararınızı etkiler. Dogmaya yer yok, sadece takaslar var.

HTMX size şunları sunar:

  • HTML'e sadık kalma, sunucu tarafında rendering
  • Daha az JavaScript, daha az derleme adımı
  • Küçük ekipler için hızlı prototipleme

React ise şunları getirir:

  • Zengin, stateful etkileşimler (drag-drop, real-time UI)
  • Devasa ekosistem, komponent kütüphaneleri, tooling
  • Büyük takımlarda ölçeklenebilir mimari desenler

Ne yapmalısınız?

  1. Küçük bir pilot yapın — iki hafta, tek bir feature, her iki yaklaşımdan biriyle
  2. Takımınızı dinleyin — kimler hangi stackte rahat? Öğrenme eğrisi ne kadar?
  3. Üretimde hissedin — deploy, debugging, test yazma süreci nasıl gidiyor?

Kod yazmadan karar vermeyin. Deneyim, teoriden her zaman daha çok öğretir.


Siz hangi tarafdasınız? HTMX'in sadelik mi, React'in gücü mü kazandırdı sizi? Ya da belki ikisini de bir arada kullandınız? Yorumlarda deneyimlerinizi paylaşın, birbirimizden öğrenelim.

Bir sonraki yazıda görüşmek üzere — mutlu kodlamalar!


Bu içerik tamamen yapay zeka destekli otomasyon sistemi ile üretilmiştir.

Burak Sağlık

Burak Saglik

©2024 Desing and Developed by @Burak Sağlık

All rights reserved