UI SDK, Base UI ve Radix: shadcn tarzı bileşenler için hangi headless kütüphane?
Vercel’in UI SDK’sı, Base UI ve Radix karşılaştırması: model, framework’ler, kapsam, stil, animasyon, beta durumu, lisans ve ajanlar.
Preet Suthar · · 9 dk okuma
- React
- UI SDK
- Base UI
- Radix
Bu haftaya kadar shadcn/ui tarzı bir bileşen kütüphanesinin altındaki primitive katmanını seçmek, iki seçenek arasında seçim yapmak demekti: Radix ve Base UI. 12 Kasım 2026’da Vercel Labs üçüncüsünü, UI SDK’yı 0.1.0-beta.1 olarak yayınladı. Diğer ikisi gibi headless, ama farklı bir fikir etrafında kurulmuş ve ikisinde de olmayan bir şey sunuyor: AI ajanlarının bileşenleri okumasını ve kullanmasını sağlayan bir köprü.
Karşılaştırmadan önce bir açıklama. HextaUI’ın bileşenleri bugün Base UI üzerine kurulu ve yanına ayrı bir UI SDK sürümü ekliyorum. İkisini de sevmek için nedenlerim var, bu yüzden adil olmaya çalıştım; aşağıdaki her iddia kütüphanelerin dokümanlarından, npm meta verilerinden ya da aynı bileşeni üç kez kurduğum bir deneme uygulamasından geliyor.
Radix’ten Base UI’a geçişi shadcn/ui kodundaki her API değişikliğiyle ayrıntılı istiyorsanız önce shadcn/ui Base UI’a geçti yazısını okuyun. Bu yazı onu tekrarlamıyor. Resme UI SDK’yı ekliyor ve hangisiyle başlanacağını soruyor.
Kısa cevap
- Çalışan bir Radix kod tabanınız varsa, ekibiniz onu biliyorsa ve onda olmayan bir bileşene ihtiyacınız yoksa Radix’i seçin. Kararlı, yalnızca React için ve MIT lisanslı.
- Bu çeyrekte kararlı API’lerle yayınlamak istediğiniz yeni bir React tasarım sistemi için Base UI’ı seçin. Yeni shadcn/ui projelerinin varsayılan altyapısıdır, Radix’ten daha fazla bileşen kapsar ve ekosistemin çoğunun yöneldiği öznitelik modelini kullanır.
- React’ten fazlasına ihtiyacınız varsa, Color Picker, Date Picker ya da Tree gibi bileşenleri ikinci bir kütüphane olmadan istiyorsanız ya da AI ajanlarının arayüzünüzü yapılandırılmış araçlarla kullanmasını istiyorsanız UI SDK’yı seçin. Beta olduğunu kabul edin.
Yazının geri kalanı kanıtlar.
Üçüne genel bakış
| Radix | Base UI | UI SDK | |
|---|---|---|---|
| Paket | radix-ui 1.8.1 | @base-ui/react 1.9.0 | @ui-sdk/react 0.1.0-beta.1 |
| Lisans | MIT | MIT | Apache-2.0 |
| Durum | Kararlı | Kararlı | Beta |
| Framework’ler | React | React | React, Vue, Svelte, Solid, Web Components |
| Açık durum | data-state="open" | data-open | data-open |
| Giriş ve çıkış | data-state üzerinde keyframe’ler | data-starting-style, data-ending-style | data-starting-style, data-ending-style |
Parçalarda data-slot | Hayır | Hayır | Evet |
| Açılır öğe parçaları | Portal, Content | Portal, Positioner, Popup | Top layer’da içerik |
| Ajan köprüsü | Hayır | Hayır | Evet, WebMCP ile |
Üçü de stilsizdir ve odağı, klavyeyi ve ARIA’yı sizin yerinize yönetir. Karşılaştırılan sürümler 13 Kasım 2026 itibarıyla npm’deki en güncel sürümler: radix-ui 1.8.1 (12 Ekim 2026’da yayınlandı), @base-ui/react 1.9.0 (9 Ekim 2026) ve @ui-sdk/react 0.1.0-beta.1 (12 Kasım 2026).
Üç farklı model
Radix her bileşen için bir primitive sunar. Bir Dialog paketi size Root, Trigger, Portal, Overlay, Content, Title, Description ve Close verir ve çalıştığınız birim budur. İçerideki odak hapsetme ve kapatma gibi davranışlar dahilidir. radix-ui paketi hepsini bir arada sunar.
Base UI da aynı yapıya sahip: bir bileşen, birkaç parça. Bunların etrafına useRender ve mergeProps gibi daha fazla public yardımcı ekler; böylece yerleşik parçalar gibi davranan kendi parçalarınızı yazabilirsiniz. Yalnızca React içindir ve Radix, Material UI ve Floating UI üzerinde çalışmış kişiler tarafından geliştirilmiştir.
UI SDK katmanları farklı ayırır. @ui-sdk/core, davranışlardan oluşan bir TypeScript kütüphanesidir: roving focus, typeahead, açılır öğeler, sürükle ve bırak, duyurular ve çok daha fazlası. Bir primitive, definePrimitive aracılığıyla davranışları durum ve adlandırılmış slot’larla birleştirir. @ui-sdk/react içinden import ettiğiniz bileşenler, React adaptörünün render ettiği primitive’lerdir ve aynı primitive’ler kendi adaptörleriyle Vue, Svelte, Solid ve Web Components’te de render edilir. Dokümanları bunu ajanlara yönelik sunuyor: bir ajana test edilmiş davranışlar verin, kütüphanenin sunmadığı bir bileşeni, örneğin bir ikon seçiciyi ya da kanban panosunu kurabilsin.
Pratikteki fark şu: Radix ve Base UI’da ihtiyacınız olan ama onlarda olmayan bir bileşen, sıfırdan sizin sorununuzdur. UI SDK’da onu yerleşik bileşenlerin kullandığı davranışların aynısından kurarsınız ve ajan köprüsüne katılabilir.
Aynı popover, üç anatomi
Bir Vite uygulamasında aynı Tailwind sınıflarıyla bir popover’ı üç kez kurdum. İşte farklı olan parçalara indirgenmiş ağaçlar:
trigger ve panel ortak sınıf string’leridir; Radix sürümü giriş ve çıkışı için iki küçük @keyframes kuralı kullanır. Sonuç üçünde de aynı görünüyor:

Radix
- Popover.Root
- Popover.Trigger
- Popover.Portal
- Popover.Content
Base UI
- Popover.Root
- Popover.Trigger
- Popover.Portal
- Popover.Positioner
- Popover.Popup
UI SDK
- Popover
- PopoverTrigger
- PopoverContentYerinde, top layer’da render edilir
Açılır öğeyi taşımak ya da yerleştirmek için var olan bir parça
Fark, içeriğin nerede yaşadığında. Testimde Radix ve Base UI açık içeriği Portal’ları aracılığıyla <body> öğesinin sonuna taşıdı. UI SDK onu kendi bileşeninin içinde, popover="manual" ile bıraktı ve tarayıcı onu top layer’a yükseltti. Bunun yan etkileri var:
- Katman kavgası yok. Top layer içeriği, yapışkan bir başlığın ya da dönüştürülmüş bir üst öğenin
z-indexdeğeri ne olursa olsun sayfanın üstünde durur. - Olaylar ağacınız boyunca yukarı yayılır. UI SDK dokümanları, bir açılır öğeyi saran tıklama işleyicisinin ya da bağlantının içindeki tıklamaları da alacağı konusunda uyarıyor. Açılır öğeleri tıklanabilir kartların dışında tutun.
- Daha az sarmalayıcı parça.
side,alignvesideOffsetgibi konumlandırma prop’ları bir Positioner’a değil, içeriğe yazılır.
Radix ve Base UI portal’ları yıllardır iyi yönetiyor, bu yüzden ilk madde bir düzeltmeden çok bir sadeleştirme. İkinci madde ise bilmeniz gereken yeni bir davranış.
Stil kancaları
Üçü de durumu data özniteliklerine koyar, ama adlar farklıdır ve yalnızca biri her parçayı adlandırır.
| Hook | Radix | Base UI | UI SDK |
|---|---|---|---|
| Açık durum | data-state="open" | data-open | data-open |
| Parça adı | yok | yok | Her parçada data-slot |
| Dönüşüm orijini | --radix-popover-content-transform-origin | --transform-origin | --transform-origin |
| Anchor genişliği | --radix-popover-trigger-width | --anchor-width | --anchor-width |
| `className` içinde durum | hayır | durumun fonksiyonu | durumun fonksiyonu |
data-slot satırı göründüğünden daha önemli. shadcn/ui kendi sarmalayıcı dosyalarında kendi data-slot özniteliklerini ekler, çünkü Radix ve Base UI bunu üretmez. Deneme uygulamamda Base UI açılır öğesi data-open, data-side ve data-align taşıyordu, data-slot taşımıyordu. UI SDK bunu her parçada kendisi ayarlar, örneğin data-slot="popover-content", ve dokümanlar onu prop’larınızın geçersiz kılamayacağı yönetilen bir öznitelik olarak ele alır. Bu, global CSS’e ve ajanlara her parça için kararlı bir ad verir.
Tailwind ile stil veriyorsanız Base UI’dan UI SDK’ya geçmek çoğunlukla sarmalayıcıları silmektir, çünkü açılır öğe öznitelik adları ortaktır. Radix’ten geçmek, data-[state=open]: varyantlarını ve Radix önekli değişkenleri değiştirmek demektir. UI SDK stil eğitimi, shadcn tarzı token’larla dört bileşeni adım adım anlatıyor.
Animasyon
Radix, mount ve unmount’u data-state üzerindeki CSS animasyonlarıyla canlandırır. Dokümanları, çıkış animasyonu oynarken unmount’u beklettiğini söylüyor. JavaScript animasyon kütüphaneleri için pek çok parça forceMount kabul eder; böylece alt öğelerin ne zaman mount edileceğine kütüphane karar verir.
Base UI data-starting-style ve data-ending-style ekler; böylece yalnızca keyframe’ler değil, CSS geçişleri de iki yönde çalışır. Açılır öğe animasyon bitene kadar sayfada kalır, sonra kaldırılır ya da Portal’da keepMounted varsa gizlenir. Animasyon kılavuzu Motion’ı da kapsar ve opacity içeren Motion animasyonlarını algıladığını söyler.
UI SDK aynı iki özniteliği aynı anlamla kullanır. İçerik çıkış geçişi ya da animasyonu bitene kadar sayfada kalır, keepMounted kapalı içeriği sayfada tutar ve onOpenChangeComplete açılma ya da kapanma bittiğinde çalışır. UI SDK dokümanlarında henüz Motion kılavuzu yok; yalnızca bir animasyon kütüphanesi kapalı içeriğin DOM’da kalmasını istediğinde keepMounted kullanılmasını söyleyen bir not var.
Yalnızca CSS ile animasyonda Base UI ve UI SDK fiilen aynıdır. Motion ağırlıklı arayüzlerde Base UI’ın bugün dokümante edilmiş desenleri var, UI SDK’nın yok.
Bileşen kapsamı
Kütüphaneler arasında bileşen saymak kaba bir iştir, çünkü her biri şeyleri farklı böler ve adlandırır. Fikir vermesi için:
- Radix:
radix-ui1.8.1’de Accordion’dan Tooltip’e 30 primitive paketi, artı Slot, Portal ve Visually Hidden gibi yardımcılar. - Base UI: doküman dizininde 37 bileşen; aralarında Radix’te olmayan Combobox, Autocomplete, Number Field, OTP Field, Drawer, Toast ve Preview Card de var.
- UI SDK: 0.1.0-beta.1 ile gelen dokümanlarda 55 bileşen ve iki hook.
Çoğu Base UI bileşeninin bir UI SDK karşılığı var, bazen başka bir adla: Number Field, Number Input; Preview Card, Hover Card; OTP Field, OTP Input olarak geçiyor. UI SDK ayrıca diğer ikisinde olmayan bileşenler de sunuyor; aralarında Calendar, Date Picker, Date Input, Time Input, Color Picker, Rating, Tree, Command, Carousel, Resizable, Image Cropper, File Input, Token Input, Trigger Menu, Timeline ve Waterfall var.
Sayı kalite demek değil. Radix ve Base UI bileşenlerinin arkasında yılların üretim kullanımı var. UI SDK’nın bileşen sayfaları test edilmiş davranışlarını satır satır listeliyor, bu iyi bir işaret, ama bir günlük açık hayat yılların hata raporlarıyla aynı şey değil.
Ajan köprüsü
Bu, yalnızca UI SDK’da olan kısım. @ui-sdk/react/agent içinden gelen createAgent(), sayfadaki her UI SDK bileşenine bağlanır. snapshot() onları etiketleri, durumları ve kullanılabilir eylemleriyle listeler. act() bu eylemleri her bileşenin API’si üzerinden çağırır ve change callback’leriniz details.source === "agent" görür. registerTools() aynı araçları WebMCP aracılığıyla tarayıcıya yerleşik bir ajana sunar.
Radix ve Base UI’da yerleşik olarak buna benzer bir şey yok. Bir ajan onları herhangi bir web sayfasını kullandığı gibi kullanır: ekran görüntüleri, DOM ya da erişilebilirlik ağacı üzerinden, tıklayan ve yazan tarayıcı araçlarıyla.
Vercel’in dokümanları bu farkın bir proje ayarları görevi üzerindeki benchmark’ını içeriyor. Onların rakamlarına göre, Claude Code üzerinden Sonnet ile ve üç çalıştırmanın medyanlarıyla ajan köprüsü araç çağrılarını 16’dan 5’e, maliyeti de $0.073’ten $0.032’ye düşürdü. Bunlar benim değil, Vercel’in tek bir görev için verdiği rakamlar, ama yön mantıklı: bileşenlerin durumlarıyla birlikte bir listesini okumak bir sayfayı okumaktan daha ucuz. Köprünün izinler ve özel bir bileşen içeren çalışan bir demosunu React uygulamanızı AI ajanlarının kullanabileceği hâle getirin yazısında kurdum.
Ajanların arayüzünüzü kullanması yol haritanızda yoksa bu bölüm hiçbir şeye karar vermemeli. Varsa, bu karşılaştırmadaki başka hiçbir şey ona yaklaşamaz.
Olgunluk ve lisans
Radix ve Base UI kararlı 1.x kütüphaneleridir. API’leri semver’e göre değişir ve shadcn/ui her bileşeni ikisi için de yayınlar.
UI SDK, README’sinde ve dokümanlarında beta aşamasında olduğunu ve framework’ün, API’lerin, dokümantasyonun ve davranışın genel kullanıma sunulmadan önce değişebileceğini söylüyor. Betası Vercel’in public beta sözleşmesi kapsamında. Buna ek olarak bazı API’ler deneysel olarak işaretlenmiş; özel primitive’lerdeki agent anahtarı ile geçmiş ve geri alma yardımcıları bunlar arasında. GitHub deposu vercel-labs/ui Ekim 2026’da oluşturuldu ve tek changelog girdisi 12 Kasım 2026 tarihli "Introducing UI SDK".
Lisanslar da farklı. Radix ve Base UI MIT lisanslı. UI SDK Apache-2.0; o da serbest bir lisans ve açık bir patent hakkı ekliyor. Yeniden dağıtırsanız Apache-2.0 lisansını ve bildirimlerini korumanızı ister; bu sizin için önemliyse şirketinizde lisanslarla ilgilenen kişiye danışın.
Framework’ler
Radix ve Base UI React kütüphaneleridir. UI SDK; @ui-sdk/react, @ui-sdk/vue, @ui-sdk/svelte, @ui-sdk/solid ve @ui-sdk/web paketlerini aynı sürümle, hepsi tek bir çekirdek üzerinde yayınlar. Şirketiniz bir React ve bir Vue uygulaması çalıştırıyorsa ya da bir CMS için Web Components yapısı istiyorsa, üçü arasında hepsini tek bir davranış ve öznitelik adı setiyle kapsayan tek kütüphane UI SDK’dır.
UI SDK’nın React paketi React 19 ve React DOM 19 ya da daha yenisini, @types/react için de 19.2.10 ya da daha yenisini gerektirir. Hâlâ React 18 kullanıyorsanız şimdilik karar verilmiş demektir.
Hangisi ne zaman seçilmeli
Uygulama çalışıyorsa, ekip onu biliyorsa ve bir engelle karşılaşmıyorsanız Radix’te kalın. Buradaki hiçbir şey sizi geçişe zorlamıyor. Geçecekseniz önce Base UI’a geçin: daha küçük bir adımdır ve öğrendiğiniz öznitelik modeli UI SDK’ya da taşınır.
Şimdi yayınlanacak bir React bileşen kütüphanesi ya da ürün arayüzü yapıyorsanız Base UI ile başlayın. Kararlıdır, shadcn/ui’ın varsayılanıdır ve açılır öğe, form ve animasyon desenleri iyi dokümante edilmiştir.
Şunlardan biri doğruysa UI SDK ile başlayın:
- birkaç framework’ün tek bir bileşen modelini paylaşması gerekiyorsa;
- ek bileşenlerine ihtiyacınız varsa ve aksi hâlde tarihler, renkler ya da ağaçlar için ek kütüphaneler ekleyecekseniz;
- ajanların arayüzünüzü kullanması bir ürün hedefiyse ve izinlerin ve değişiklik kaynaklarının yerleşik olmasını istiyorsanız;
- prototip yapıyorsanız ve beta sırasında kırıcı değişiklikleri kaldırabiliyorsanız.
Karıştırmak mümkün. UI SDK bileşenleri bir provider gerektirmez, bu yüzden bir Base UI uygulaması tek bir ekranda UI SDK Color Picker kullanabilir. İki bağımlılık ve iki öznitelik adı seti taşırsınız, o yüzden bunu başka yerde bulamadığınız bileşenlerle sınırlı tutun.
HextaUI ne yapıyor
HextaUI’ın bileşenleri Base UI’da kalıyor. Sitede bugün olan o sürüm ve bir yere gitmiyor. Aynı görünüm ve tema token’larıyla, ajan köprüsünü ya da ek bileşenleri isteyen projeler için ayrı bir UI SDK sürümü de yapıyorum. Henüz yayınlanmadı. Yayınlandığında geçiş yapmayacak, bir sürüm seçeceksiniz.
