EAS Update 2026: React Native için OTA Güncellemeler, Rollout ve Rollback Rehberi
EAS Update ile React Native uygulamanıza kademeli rollout, tek tıkla rollback ve code signing uygulayın. Channel/branch/runtime version modeli, CI/CD ve üretim disiplini için 2026 rehberi.
EAS Update, React Native uygulamanızın JavaScript bundle'ını ve varlıklarını App Store veya Google Play incelemesini beklemeden doğrudan kullanıcıların cihazına gönderen Expo'nun over-the-air (OTA) güncelleme sistemidir. Fintech'te platform ekibi kurarken bu akışı üç yıldır günlük olarak kullanıyorum: 60 saniyede yayına giren bir düzeltme ile 7 gün mağaza incelemesi arasındaki fark, çoğu ekip için tek başına migrasyonu haklı çıkarıyor. Bu rehberde EAS Update'in mimarisini, kademeli rollout stratejisini, tek tıkla rollback'i ve CI/CD entegrasyonunu üretim ortamı disiplinine uygun şekilde ele alıyorum.
EAS Update yalnızca JavaScript, stil ve varlıkları yayınlar; native kod değişiklikleri hâlâ mağaza inceleme sürecinden geçer.
Channel + branch + runtime version üçlüsü, hangi build'in hangi bundle'ı alacağını belirleyen çekirdek yönlendirme modelidir.
Runtime version, native yüzey değiştiğinde appVersion ile değil; fingerprint policy ile otomatik türetilmeli.
Üretimde her güncelleme %5 → %25 → %100 kademeli rollout ile yayınlanır; hataya karşı Sentry'de updateId etiketi zorunludur.
Rollback bir "geri alma" değil, önceki iyi bundle'ı yeni bir yayın olarak tekrar publish etmektir.
EAS Update Production ve Enterprise planlarında code signing ile "trustless" hale gelir; CDN ele geçirilse bile imzasız bundle reddedilir.
EAS Update nedir ve neden önemli?
EAS Update, Expo'nun sunduğu ve React Native uygulamalarının JS bundle'ını, stil dosyalarını ve statik varlıklarını binary'yi yeniden derlemeden değiştirmenizi sağlayan yönetilen bir CDN katmanıdır. Uygulama açıldığında expo-updates istemcisi EAS sunucusuna hangi kanalda, hangi runtime version'da olduğunu bildirir; sunucu uygun bir güncelleme bulursa bundle'ı indirir ve bir sonraki açılışta uygular. Kullanıcı ne mağazayı ziyaret eder ne de yeniden yükleme yapar.
Fintech ürününde bunu neden hayati bulduğumu somut bir örnekle açıklayayım: geçen çeyrekte bir para transferi ekranında yanlış para birimi formatlaması ile production'a çıktık. Store hotfix rotası: yeni build, EAS Submit, Apple review kuyruğu — en iyi ihtimalle 24 saat. Bunun yerine eas update --channel production --rollout-percentage 5 çalıştırdık; 15 dakikada %5 kullanıcıda doğruladık, 40 dakikada %100'e çıktık. Kritik bir müşteri sözleşmesinde SLA'yı ihlal etmeden kapattık. Native mimari değişikliklerinden bahsetmek istiyorsanız React Native Yeni Mimari geçiş rehberimizi okumanızı öneririm; ancak günlük ürün operasyonunda hız kazandıran şey EAS Update'tir.
Sınır çok net: EAS Update native kod göndermez. ios/ veya android/ altındaki hiçbir şeyi değiştiremez, Expo SDK sürümünü yükseltemez, yeni bir native modül ekleyemez. Bu değişiklikler için yeni bir binary derlemek ve mağaza kuyruğuna girmek gerekir. Sağlıklı bir platform ekibi, hangi değişikliğin OTA ile gidebileceğine karar veren bir "release rota" politikası tanımlar.
Channel, branch ve runtime version: üçlü yönlendirme
EAS Update, üç adet birbirinden bağımsız kavramla çalışır ve çoğu ekip bunları karıştırdığı için ilk hafta ayaklarına takılır. Zihinsel modeli net kurarsanız gerisi otomatik gelir.
Channel
Channel, binary'ye derleme zamanında yazılan bir etikettir. eas.json içinde build profile'ınıza yazılır ve bir kere yazıldıktan sonra o binary ömür boyu o kanalı dinler. Standart üçlü development, preview, production'dır. Channel bir "dinleme frekansı"dır; bundle'ları kendisi taşımaz.
Branch
Branch, sunucu tarafında bir güncelleme akışıdır — Git branch'ine çok benzer, her yayınladığınız eas update komutu bu akışa yeni bir "commit" ekler. Bir channel, herhangi bir branch'e bağlanabilir. Bu ayrım güçlüdür: production channel'ını önce production-v2.5 branch'ine bağlarsınız; sonra v2.6 branch'ini oluşturup test edersiniz; hazır olduğunda channel'ın branch bağlantısını değiştirir, tek bir bundle bile yeniden publish etmezsiniz.
Runtime version
Runtime version, native binary ile JS bundle'ın uyumluluğunu garanti eden bir kontrat etiketidir. Update policy şudur: platform (iOS/Android) ve runtime version tam eşleşme gerektirir. Native tarafta bir şey değişirse (Expo SDK 55'ten 56'ya geçtiniz, yeni bir C++ modül eklediniz), runtime version bump'lanmalıdır, aksi halde eski binary yeni bundle'ı yükleyip anında crash eder.
Sıfırdan EAS Update kurulum adımları
Aşağıdaki adımlar Expo SDK 55+ ile çalışan yeni ve mevcut projeler için geçerlidir. Bare React Native projelerinde de aynı akış, sadece config değişiklikleri manuel yapılır.
1. expo-updates ve eas-cli kurulumu
npx expo install expo-updates
npm install -g eas-cli
eas login
eas update:configure
eas update:configure komutu app.json dosyanıza güncellemeler için gereken updates.url, runtimeVersion ve platform-specific ayarları enjekte eder. Configure sonrası dosya şuna benzer:
Build profile ile channel arasındaki bu bağlama, üretilen her binary'nin hangi güncelleme akışını dinleyeceğini belirler.
3. İlk güncellemeyi yayınlama
# Önce production kanalı için bir build alın
eas build --platform all --profile production
# Sonra JS-only bir düzeltme yapıp yayınlayın
eas update --channel production --message "Havale ekranında para formatı düzeltmesi"
Kullanıcı bir sonraki açılışta güncellemeyi indirir; checkAutomatically: "ON_LOAD" ayarı sayesinde bundle uygulamanın açılışında sessizce kontrol edilir. Zorunlu güncellemeler için expo-updates API'sini kullanarak uygulamayı restart edebilirsiniz.
4. İstemci tarafında programatik güncelleme kontrolü
import * as Updates from 'expo-updates';
import { useEffect } from 'react';
import { Alert } from 'react-native';
export function useForcedUpdateCheck() {
useEffect(() => {
async function check() {
try {
const result = await Updates.checkForUpdateAsync();
if (result.isAvailable) {
await Updates.fetchUpdateAsync();
Alert.alert(
'Güncelleme hazır',
'Uygulamayı yeniden başlatmak ister misiniz?',
[
{ text: 'Sonra', style: 'cancel' },
{ text: 'Yeniden başlat', onPress: () => Updates.reloadAsync() },
],
);
}
} catch (error) {
console.warn('Update check failed', error);
}
}
check();
}, []);
}
Runtime version stratejisi: appVersion vs fingerprint
Runtime version policy'sini seçmek, OTA operasyonunuzun en kritik mimari kararıdır. İki temel policy vardır.
appVersion policy
Runtime version doğrudan app.json içindeki version alanından türetilir. 2.5.0 ve 2.5.1 aynı runtime'ı paylaşır; 2.6.0 paylaşmaz. Basit ekipler için okunabilir ama disiplin gerektirir: patch versiyonunda native dependency eklerseniz sistem sizi durdurmaz, kullanıcılarınız crash almaya başlar.
fingerprint policy (önerilen)
Expo, native yüzeyinizi (yüklü modüller, iOS/Android ayarları, config plugin'ler) hash'ler ve bunu runtime version olarak kullanır. Native bir şey değiştiğinde fingerprint otomatik değişir; JS-only değişiklik yaptığınızda aynı kalır. Fintech ekibimde son bir yıldır yalnızca fingerprint policy kullanıyoruz — insan hatasını sistemin kendisiyle değiştirdiğimiz için üretim crash oranımız ölçülebilir şekilde düştü.
Kademeli rollout ile güvenli yayınlama
Bir güncelleme yayınladığınızda tüm production kullanıcılara aynı anda göndermek, üretim disiplini olan hiçbir ekibin yapmadığı bir şeydir. EAS'in per-update rollout mekanizması, bir bundle'ı önce kullanıcıların bir yüzdesine göstermenizi ve metriklere bakarak yavaşça artırmanızı sağlar.
# %5 ile başlat
eas update --channel production \
--message "TransferButton crash düzeltmesi" \
--rollout-percentage 5
# Yayın kimliğini not et: örneğin update-id: 4b2a1f8c...
# 1 saat sonra Sentry'de crash oranı ok'se %25'e çıkar
eas update:edit --rollout-percentage 25 --id 4b2a1f8c...
# 4 saat sonra %100
eas update:edit --rollout-percentage 100 --id 4b2a1f8c...
Fintech'te uyguladığımız cadence şöyle: %5 x 1 saat (boot-loop, missing asset gibi bariz sorunları yakalar), %25 x 4 saat (locale ve OS versiyonuna bağlı hataları çıkarır), %100. Bu üç aşamalı yaklaşım son 18 ayda tek bir global regresyon yaşamamıza engel oldu.
Rollout metriklerini takip ederken her crash raporuna Updates.updateId, Updates.channel ve Updates.runtimeVersion alanlarını Sentry etiketi olarak eklemek zorunludur. Aksi halde "hangi bundle patladı" sorusuna cevap veremezsiniz. Örnek entegrasyon için React Native DevTools rehberimizdeki monitoring bölümüne bakabilirsiniz.
Bozuk bir OTA güncellemesi nasıl geri alınır?
Bu, EAS Update ile ilgili en yaygın yanlış anlamadır: rollback bir "geri alma" değildir. Kullanıcının cihazındaki expo-updates istemcisi yalnızca daha yeni bir bundle görürse yükler. Dolayısıyla "bozuk update'i sil"in bir etkisi olmaz; kullanıcı zaten indirmiş ve çalıştırıyor olabilir.
Doğru rollback stratejisi şudur: önceki iyi bundle'ı, aynı kanala yeni bir güncelleme olarak tekrar yayınlarsınız.
# Son iyi bilinen güncellemenin id'sini bul
eas update:list --branch production --limit 10
# İyi olan bundle'ı, mesaj değiştirerek republish et
eas update:republish --group <iyi-update-group-id> \
--message "Rollback: TransferButton crash düzeltmesi geri alındı"
update:republish komutu, seçtiğiniz eski bundle'ı sanki yeni bir yayınmış gibi kanala ekler ve tüm kullanıcılara bir sonraki açılışta gönderilir. Fintech'te bir rollback prosedürünü oncall runbook'ta üç satır olarak yazılı tutuyoruz; panik anında karar vermek istemezsiniz.
Code signing ile trustless OTA
OTA güncellemeler, mimari açıdan güçlü bir tedarik zinciri saldırı yüzeyi oluşturur: EAS sunucusu veya CDN ele geçirilirse, saldırgan tüm kullanıcılarınıza kötü niyetli JS enjekte edebilir. Kod imzalama tam bu nedenle var: yayınlanan her bundle özel anahtarınızla imzalanır; binary'nin içine gömülü olan public key, cihazda imzayı doğrular. Eşleşmezse güncelleme reddedilir ve önceki güvenilir sürüm çalışmaya devam eder.
Sonrasında eas update komutları imzalanmış bundle'lar yayınlar. Kod imzalama EAS Production ve Enterprise planlarında bulunur; fintech gibi düzenlenmiş sektörlerde yalnızca "iyi olur" değil, denetim gerekliliğidir. Detay için Expo Code Signing dokümantasyonuna göz atın.
GitHub Actions ve EAS Workflows ile CI/CD
Manuel eas update komutu bir mühendisin laptopunda çalışmak zorunda değil; çalışmamalı da. Üretim sürecinde her production merge'ün otomatik olarak OTA yayınlaması hem hızı hem de denetlenebilirliği artırır.
EXPO_TOKEN repo secret'ı olarak eklenmelidir. --rollout-percentage 5 ile yayının otomatik olarak %5'ten başlamasını garanti ediyoruz; yüzdenin artırılması insan onayı ile eas update:edit aracılığıyla yapılır.
EAS Workflows alternatifi
Expo'nun kendi Workflows sistemi 2026'da olgunlaştı ve GitHub Actions'a bağımlılık istemeyen ekipler için doğrudan .eas/workflows/*.yml dosyalarında pipeline tanımlamanıza izin verir. Native build, submit ve update job'larını tek bir YAML içinde zincirleyebilir; ayrıca Expo'nun cache'inden faydalanarak build sürelerini kısaltabilirsiniz.
EAS Update vs CodePush: 2026 karşılaştırması
Microsoft App Center CodePush hizmetinin sonlandırılması ile birlikte 2026'da hiçbir ekibin CodePush'ta kalması için pratik bir sebep kalmadı. Yine de karşılaştırma tablosu ve migrasyon soruları hâlâ sık geliyor.
Özellik
EAS Update
CodePush (sonlandırıldı)
Durum (2026)
Aktif, resmi Expo ürünü
15 Mart 2025'te sonlandırıldı
Yeni Mimari desteği
Tam (Fabric, TurboModules, Bridgeless)
Yok
Runtime version modeli
appVersion, sdkVersion veya fingerprint
appVersion yalnızca manuel
Kademeli rollout
Per-update yüzde, dashboard'dan düzenlenebilir
Sınırlı, deployment key başına
Rollback
republish veya roll-back-to-embedded
Manuel dashboard işlemi
Code signing
Yerleşik (Production+ planlar)
Sertifika pinning'e dayalı
Expo entegrasyonu
Doğal, tek CLI
Ayrı entegrasyon adımları
Fiyat modeli
Aylık aktif kullanıcı bazlı
Kapalı
Migrasyon rehberi için Expo'nun resmi CodePush-to-EAS-Update dokümantasyonuna bakabilirsiniz. Bare React Native projelerinde bile expo-updates paketi tek başına çalışır; Expo prebuild veya Config Plugins kullanmanız zorunlu değildir.
Üretimde en sık yapılan altı hata
Son üç yılda hem kendi ekibimde hem de review yaptığım fintech projelerinde tekrar tekrar gördüğüm hatalar:
Runtime version'ı unutmak. Native bir modül eklediniz, appVersion policy kullanıyorsunuz, bundle'ı yayınladınız, production crash sağanağı geliyor. Çözüm: fingerprint policy'ye geçin.
Rollout yüzdesi kullanmadan direkt %100 yayınlamak. Boot-loop bir bundle 5 dakikada tüm kullanıcı tabanınıza yayılır. Çözüm: CI'da varsayılan --rollout-percentage 5.
Update meta verisini crash raporlarına eklememek. Sentry olay listesinde "hangi bundle" sorusunu yanıtlayamazsanız rollback kararı veremezsiniz. Çözüm: Sentry.setTags ile updateId, channel, runtimeVersion.
EAS Update ile "yeni feature" ekleyip Apple'ın 3.3.1 kuralını ihlal etmek. Bug düzeltme ve minör metin/layout değişiklikleri OK'dir; tamamen yeni bir feature'ı remote flag arkasında saklayıp bir hafta sonra açmak App Store politikasına aykırıdır. Çözüm: OTA'yı yalnızca hotfix ve minör iterasyonlar için kullanın.
Development kanalını üretim binary'sine karıştırmak. QA cihazına yanlış channel ile build atmak, üretim güncellemesinin geliştirme ortamına gitmesine yol açar. Çözüm: eas.json'da build profile → channel eşlemelerini asla el ile bozmayın.
Rollback için "önceki güncellemeyi silmek." Kullanıcı zaten cihazına indirdi. Çözüm: her zaman republish veya roll-back-to-embedded kullanın.
Expo Router ile birlikte kullanan ekipler için Expo Router v4 rehberimizde ele aldığımız route-level test yaklaşımı, OTA öncesi smoke test'lerinizi hızlandırır. EAS Build tarafında güncel bilgi için EAS Update resmi dokümantasyonu her zaman ana kaynağınız olsun.
Sıkça Sorulan Sorular
EAS Update tamamen ücretsiz mi?
Free planda ayda 1.000 aktif kullanıcıya kadar dahildir. Üretim projeleri için Production plan gereklidir; fiyat aylık aktif kullanıcı (MAU) bazında ölçeklenir. Code signing yalnızca Production ve Enterprise planlarında bulunur.
EAS Update ile yeni bir feature ekleyebilir miyim?
Teknik olarak evet, ancak Apple'ın 3.3.1 yönergesine göre uygulamanın amacını veya büyük özelliklerini OTA ile değiştiremezsiniz. Bug düzeltmeleri, kopya ve düzen değişiklikleri, feature flag toggle'ları güvenlidir; tamamen yeni ekranlar için mağaza sürümü yapın.
Kullanıcı bir güncellemeyi ne zaman görür?
Varsayılan olarak uygulamanın bir sonraki soğuk başlatmasında (cold start) kontrol edilir ve indirilir; sonrasında bir sonraki açılışta uygulanır. Updates.reloadAsync() ile aynı oturumda anında uygulayabilirsiniz.
Bare React Native projesinde EAS Update kullanabilir miyim?
Evet. expo-updates paketi bare projelerde de çalışır; Expo prebuild veya Config Plugins zorunluluğu yoktur. iOS ve Android tarafında manuel bir kez native integration adımlarını uygulamanız gerekir; sonrasında akış Expo projeleriyle aynıdır.
Runtime version fingerprint policy hangi durumda değişir?
Native yüzeyinizi etkileyen her değişiklikte: yeni bir native package eklendiğinde, Expo SDK yükseltildiğinde, ios/ veya android/ altında elle bir düzenleme yapıldığında, bir config plugin'in native çıktısı değiştiğinde. Sadece JS/TS/asset değişikliği fingerprint'i değiştirmez.
CodePush'tan EAS Update'e migrasyon ne kadar sürer?
Orta boy bir bare React Native projesi için tipik olarak 1-2 gün: expo-updates kurulumu, native entegrasyonun sökülmesi/yeniden kurulması, runtime version stratejisinin seçimi ve CI script'lerinin güncellenmesi. Feature flag ve rollout mantığınızın taşınması ayrıca yarım gün alır.
Expo Router v4 ile dosya tabanlı yönlendirmeyi sıfırdan öğrenin: kurulum, dinamik rotalar, typed routes, iç içe layout'lar, deep linking ve API rotaları — 2026 kapsamlı rehber, gerçek kod örnekleriyle.
Expo SDK 55 ile gelen expo-widgets kütüphanesini kullanarak iOS ana ekran widget'ları ve Live Activities oluşturmayı adım adım öğrenin. Swift bilmeden, React bileşenleriyle widget geliştirin.