shadcn/ui CLI, monorepo yapısını tanır: npx shadcn@latest init komutunda Next.js (Monorepo) seçeneğini seçtiğinizde Turborepo ile yönetilen, web ve ui adlı iki çalışma alanı (workspace) içeren hazır bir proje oluşur. Bileşen eklemek için add komutunu uygulamanın klasöründe çalıştırırsınız; CLI bileşeni paylaşılan packages/ui paketine yazar, uygulamadaki içe aktarma yollarını da kendisi düzenler. Bileşenleri @workspace/ui/components/button gibi yollardan içe aktarırsınız.
Bu yazıda belgedeki adımları, oluşan dosya yapısını, her çalışma alanında bulunması gereken components.json dosyalarını ve depodaki monorepo şablonunun bu yapıyı nasıl bağladığını anlatıyoruz. Monorepo kavramının ve Turborepo'nun kendisi bu yazının dışında; onlar için Turborepo'nun kendi belgelerine bakın. Tek uygulamalı Next.js kurulumu ise shadcn Next.js kurulumu yazısında.
Monorepo desteği neyi çözüyor?

Belgeye göre bu destekten önce shadcn/ui'yi monorepo içinde kullanmak zahmetliydi: CLI ile bileşen eklenebiliyordu ama bileşenlerin nereye kurulacağını sizin yönetmeniz ve içe aktarma yollarını elle düzeltmeniz gerekiyordu. Changelog'un Aralık 2024 notuyla gelen monorepo desteğinde CLI yapıyı anlar; bileşenleri, bağımlılıkları ve registry bağımlılıklarını doğru yollara kurar ve içe aktarmaları sizin yerinize ayarlar. Ağustos 2025'teki CLI 3.0 notu da yeniden yazılan registry motorunun monorepo desteğini iyileştirdiğini belirtir.
Yeni bir monorepo projesi oluşturmak
Başlangıç noktası her zamanki init komutudur. Komut, oluşturmak istediğiniz proje türünü sorar:
npx shadcn@latest init? Would you like to start a new project?
Next.js
❯ Next.js (Monorepo)Next.js (Monorepo) seçeneğini seçtiğinizde CLI, web ve ui çalışma alanlarına sahip ve derleme sistemi olarak Turborepo kullanan yeni bir proje oluşturur. Belgeye göre her şey hazır gelir ve doğrudan bileşen eklemeye başlayabilirsiniz. Bu monorepo React 19 ve Tailwind CSS v4 kullanır. Soruyu atlamak isterseniz CLI belgesindeki -t, --template seçeneği next ve next-monorepo değerlerini kabul eder:
npx shadcn@latest init -t next-monorepoDepo kopyasındaki 3.6.2 kaynağı bu seçimin arka planda ne yaptığını da gösterir. CLI, shadcn-ui/ui deposundaki templates/monorepo-next şablonunu indirip proje klasörüne çıkarır, algıladığı paket yöneticisiyle install komutunu çalıştırır, kök package.json dosyasındaki adı proje klasörünün adıyla değiştirir ve son olarak bir git deposu başlatıp "Initial commit" mesajıyla ilk commit'i oluşturur. Bu yüzden komut ağ erişimi ister ve birkaç dakika sürebilir; CLI de bunu "Creating a new Next.js monorepo. This may take a few minutes." mesajıyla bildirir. Şablonun kendisi pnpm çalışma alanlarıyla hazırlanmıştır (pnpm-workspace.yaml dosyası ve workspace:* bağımlılıkları); farklı bir paket yöneticisi kullanacaksanız bu dosyaların onunla nasıl davranacağını kendi paket yöneticinizin belgelerinden kontrol edin.
React 19 kullanılan bir proje olduğu için npm ile kurulumda peer dependency uyarısı görürseniz React 19 peer dependency yazısına bakın. init komutunun diğer seçenekleri shadcn kurulumu ve init yazısında.
Dosya yapısı
Belgede gösterilen yapıda uygulamalar apps, paylaşılan paketler packages klasöründedir. Kökte Turborepo yapılandırması için turbo.json bulunur:
apps
web # Uygulamanız burada
app
page.tsx
components
login-form.tsx
components.json
package.json
packages
ui # Bileşenler ve bağımlılıkları burada
src
components
button.tsx
hooks
lib
utils.ts
styles
globals.css
components.json
package.json
package.json
turbo.jsonBu yapıdaki kritik ayrım şudur: packages/ui tüm uygulamaların paylaştığı ilkel bileşenleri (button, card gibi), cn yardımcısını, kancaları ve tema CSS dosyasını taşır. apps/web/components ise o uygulamaya özgü, ilkelleri bir araya getiren bileşenleri tutar. Belgedeki login-form.tsx bu ikinci türe örnektir.
Bileşen eklemek: komutu uygulama klasöründe çalıştırın
Belge, add komutunu uygulamanızın yolunda çalıştırmanızı ister:
cd apps/web
npx shadcn@latest add [COMPONENT]CLI eklediğiniz öğenin türünü anlar ve dosyaları doğru yere koyar. Belgedeki iki örnek farkı iyi gösterir. npx shadcn@latest add button çalıştırdığınızda düğme bileşeni packages/ui altına kurulur ve apps/web içindeki bileşen içe aktarma yolu güncellenir. Bir blok olan npx shadcn@latest add login-01 ise button, label, input ve card bileşenlerini packages/ui altına, login-form bileşenini ise apps/web/components altına yerleştirir. Yani ilkeller paylaşılan pakete, sayfaya özgü birleşik bileşen uygulamaya gider. Blokların kendisi shadcn blocks yazısında.
Kökten ayrılmadan çalışmak isterseniz CLI'nin -c, --cwd seçeneğini kullanabilirsiniz. Depodaki monorepo şablonunun README dosyası bu biçimi pnpm ile gösterir ve ilkel bileşenlerin packages/ui/src/components klasörüne yerleşeceğini söyler:
pnpm dlx shadcn@latest add button -c apps/webBileşenleri içe aktarmak
Uygulama kodunda bileşenler @workspace/ui paketinden içe aktarılır. Kancalar ve yardımcılar da aynı paketten gelir:
import { Button } from "@workspace/ui/components/button"
import { useTheme } from "@workspace/ui/hooks/use-theme"
import { cn } from "@workspace/ui/lib/utils"Bu yollar, paylaşılan paketin package.json dosyasındaki exports alanıyla çalışır. Depodaki şablonda packages/ui/package.json şu eşlemeleri tanımlar; ./components/* yolu src/components altındaki .tsx dosyalarına, ./lib/* ve ./hooks/* ise .ts dosyalarına gider:
{
"name": "@workspace/ui",
"exports": {
"./globals.css": "./src/styles/globals.css",
"./postcss.config": "./postcss.config.mjs",
"./lib/*": "./src/lib/*.ts",
"./components/*": "./src/components/*.tsx",
"./hooks/*": "./src/hooks/*.ts"
}
}Şablonun web uygulaması bu paketi "@workspace/ui": "workspace:*" bağımlılığıyla kullanır, next.config.mjs içinde transpilePackages: ["@workspace/ui"] ayarıyla paketin Next.js tarafından derlenmesini sağlar ve kök düzende tema CSS'ini import "@workspace/ui/globals.css" satırıyla yükler. Şablonun tsconfig.json dosyasında ayrıca @workspace/ui/* yolu ../../packages/ui/src/* klasörüne eşlenir; takma ad kavramı için TypeScript paths ayarları yazısına bakabilirsiniz.
Gereksinimler: iki components.json

Belge, CLI'nin doğru çalışması için dört gereksinim sayar. İlki, her çalışma alanında bir components.json dosyası bulunmasıdır. Belgenin benzetmesiyle package.json npm'e bağımlılıkların nasıl kurulacağını, components.json ise CLI'ye bileşenlerin nasıl ve nereye kurulacağını söyler. İkincisi, bu dosyalardaki takma adların çalışma alanına göre doğru tanımlanmasıdır. Uygulama tarafındaki dosya:
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "../../packages/ui/src/styles/globals.css",
"baseColor": "zinc",
"cssVariables": true
},
"iconLibrary": "lucide",
"aliases": {
"components": "@/components",
"hooks": "@/hooks",
"lib": "@/lib",
"utils": "@workspace/ui/lib/utils",
"ui": "@workspace/ui/components"
}
}Paylaşılan paketteki dosya:
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/styles/globals.css",
"baseColor": "zinc",
"cssVariables": true
},
"iconLibrary": "lucide",
"aliases": {
"components": "@workspace/ui/components",
"utils": "@workspace/ui/lib/utils",
"hooks": "@workspace/ui/hooks",
"lib": "@workspace/ui/lib",
"ui": "@workspace/ui/components"
}
}İki dosyayı karşılaştırmak yapının mantığını gösterir. Uygulamada components, hooks ve lib uygulamanın kendi @/ yollarını gösterir; ama ui ve utils paylaşılan pakete yönelir. CLI'nin ilkel bileşenleri packages/ui altına, birleşik bileşenleri uygulamaya yazabilmesinin nedeni budur. Uygulamanın tailwind.css değeri de göreli bir yolla paylaşılan paketteki CSS dosyasını gösterir. Paketteki dosyada ise tüm takma adlar @workspace/ui altındadır. Alanların genel anlamı components.json ayarları yazısında.
Üçüncü gereksinim, iki dosyada style, iconLibrary ve baseColor değerlerinin aynı olmasıdır. Dördüncüsü, Tailwind CSS v4 için tailwind.config alanının boş bırakılmasıdır. Belgedeki örnek zinc kullanırken depodaki şablonun web uygulamasında neutral görürsünüz; önemli olan değerin hangisi olduğu değil, iki dosyada aynı olmasıdır.
| Alan | apps/web | packages/ui |
|---|---|---|
| tailwind.css | ../../packages/ui/src/styles/globals.css | src/styles/globals.css |
| aliases.components | @/components | @workspace/ui/components |
| aliases.ui | @workspace/ui/components | @workspace/ui/components |
| aliases.utils | @workspace/ui/lib/utils | @workspace/ui/lib/utils |
| aliases.hooks | @/hooks | @workspace/ui/hooks |
| style, iconLibrary, baseColor | Aynı olmalı | Aynı olmalı |
| tailwind.config | Boş (Tailwind v4) | Boş (Tailwind v4) |
CLI dosyanın yerini nasıl buluyor?
components.json belgesine göre CLI, oluşturduğu bileşenleri doğru yere koymak için takma adlarla birlikte tsconfig.json (ya da jsconfig.json) dosyasındaki paths ayarını kullanır. Monorepo şablonunda bu iki bilgi birlikte okunduğunda yol netleşir. apps/web klasöründe add button çalıştırdığınızda CLI o klasördeki components.json dosyasında aliases.ui değerinin @workspace/ui/components olduğunu görür. Uygulamanın tsconfig.json dosyasında @workspace/ui/* yolu ../../packages/ui/src/* klasörüne eşlendiği için bu takma ad diskte packages/ui/src/components klasörüne karşılık gelir.
Bileşenin kendi içindeki içe aktarmalar ise paylaşılan paketin bakış açısıyla yazılmalıdır; örneğin düğme dosyası cn yardımcısını @workspace/ui/lib/utils yolundan almalıdır. packages/ui/components.json dosyasının tüm takma adlarının @workspace/ui altında olması bu yüzden önemlidir. İki dosyadan biri eksik ya da hatalıysa CLI ya bileşeni yanlış klasöre yazar ya da içindeki içe aktarmalar çözülemez. Belgenin "her çalışma alanında bir components.json olmalı" kuralı bu iki yönlü ihtiyaçtan gelir.
Uygulamalı örnek: paylaşılan bileşenlerle bir sayfa
Yeni oluşturulmuş monorepo'da bir duyuru kartı göstermek istediğinizi düşünün. Önce uygulama klasörüne geçip ihtiyacınız olan iki ilkel bileşeni eklersiniz:
cd apps/web
npx shadcn@latest add card buttonBelgedeki davranışa göre card.tsx ve button.tsx dosyaları packages/ui altına yazılır. Ardından apps/web/app/page.tsx dosyasında bunları paylaşılan paketten içe aktarırsınız:
import { Button } from "@workspace/ui/components/button"
import {
Card,
CardContent,
CardHeader,
CardTitle,
} from "@workspace/ui/components/card"
export default function Page() {
return (
<Card>
<CardHeader>
<CardTitle>Bakım duyurusu</CardTitle>
</CardHeader>
<CardContent>
<Button>Ayrıntılar</Button>
</CardContent>
</Card>
)
}Aynı monorepo'ya ikinci bir uygulama eklediğinizde o uygulama da aynı Card ve Button dosyalarını kullanır; bir düzeltmeyi packages/ui içinde yaptığınızda tüm uygulamalara yansır. shadcn/ui'nin açık kod yaklaşımı burada da geçerlidir: paylaşılan paketteki dosyalar sizindir ve onları doğrudan düzenleyebilirsiniz. Değişikliğin yalnızca tek bir uygulamayı etkilemesini istiyorsanız o uygulamanın components klasöründe ilkeli saran ayrı bir bileşen yazmak daha doğru olur.
Şablondaki Tailwind ayarı
Bileşenler paylaşılan pakette, onları kullanan sayfalar uygulamada durduğu için Tailwind'in her iki yerdeki sınıfları da taraması gerekir. Depodaki şablonun packages/ui/src/styles/globals.css dosyası bunu en baştaki @source satırlarıyla yapar ve ardından shadcn/ui'nin bilinen satırlarıyla devam eder:
@import "tailwindcss";
@source "../../../apps/**/*.{ts,tsx}";
@source "../../../components/**/*.{ts,tsx}";
@source "../**/*.{ts,tsx}";
@import "tw-animate-css";
@custom-variant dark (&:is(.dark *));Yeni bir uygulama eklediğinizde onun dosyaları apps altında kaldığı sürece bu tarama kapsamına girer. @source yönergesinin kendisi Tailwind'in konusudur; Tailwind CSS v4 yenilikleri yazısına bakabilirsiniz. Tema değişkenlerinin geri kalanı shadcn tema, koyu tema sağlayıcısı ise dark mode kurulumu yazısında.
Şablonun kökündeki pnpm-workspace.yaml dosyası apps/* ve packages/* klasörlerini çalışma alanı olarak tanımlar, kök package.json ise turbo build, turbo dev ve turbo lint betiklerini içerir. Belgenin kendisi paket yöneticisi konusunda bir zorunluluk yazmaz; şablon pnpm ile hazırlanmıştır.
Şablonun turbo.json dosyasındaki build görevi önce bağımlı paketlerin derlenmesini bekler ("dependsOn": ["^build"]) ve çıktı olarak .next klasörünü tanımlar; dev görevi ise önbelleğe alınmaz ve sürekli çalışır. Yani kökte turbo build çalıştırdığınızda paylaşılan paket ve web uygulaması doğru sırayla ele alınır. Derlenen Next.js uygulamasını bir sunucuya taşıma adımları için Next.js VPS deploy yazısına bakabilirsiniz.
Sık yapılan hatalar

- add komutunu kökte çalıştırmak: Belge komutun uygulama klasöründe çalıştırılmasını ister; kökteyseniz
-c apps/webverin. - Tek bir components.json ile yetinmek: Her çalışma alanında ayrı dosya gerekir.
- Takma adları karıştırmak: Uygulamadaki
uiveutilspaylaşılan pakete yönelmelidir; yanlış yönelirse ilkeller uygulamaya kopyalanır. - İki dosyada farklı stil veya temel renk kullanmak:
style,iconLibraryvebaseColoraynı olmalıdır. - Tailwind v4 projesinde tailwind.config yolu yazmak: Alan boş bırakılmalıdır.
- Bileşenleri göreli yollarla içe aktarmak:
@workspace/ui/components/...biçimini kullanın; CLI de bu biçimi yazar.
Sık Sorulan Sorular
Var olan bir monorepo'ya shadcn/ui ekleyebilir miyim?
Belge yeni bir monorepo oluşturmayı anlatır. Var olan bir yapıda ise aynı gereksinimleri sağlamanız gerekir: her çalışma alanında doğru takma adlara sahip bir components.json, iki dosyada aynı stil ve renk değerleri ve Tailwind v4 için boş tailwind.config. Bunlar sağlandığında CLI bileşenleri doğru yollara kurabilir.
İkinci bir uygulama eklersem ne olur?
Belge bu senaryoyu ayrıca anlatmaz. Gereksinimlere göre yeni uygulamanın da kendi components.json dosyası olmalı ve ui ile utils takma adları aynı paylaşılan pakete yönelmelidir.
Monorepo şablonu hangi React ve Tailwind sürümlerini kullanır?
Belgeye göre monorepo React 19 ve Tailwind CSS v4 kullanır. Depo kopyasındaki şablonda web uygulamasının package.json dosyası next için 16.0.10, react için ^19.2.1 sürümünü yazar; bu değerler 19 Aralık 2025 tarihli kopyaya aittir ve sizin oluşturduğunuz projede daha yeni olabilir.
Monorepo'da koyu tema nasıl kurulur?
Şablonda bu iş hazırdır: apps/web/components/providers.tsx dosyası next-themes sağlayıcısını sarar, kök düzen onu kullanır ve paylaşılan paketteki globals.css .dark değişkenlerini taşır. Tema düğmesini eklemek için dark mode kurulumu yazısındaki adımlar geçerlidir; tek fark, düğmenin kullandığı ilkelleri @workspace/ui/components yolundan içe aktarmanızdır.
Hazır bloklar monorepo'da nasıl kurulur?
Belgedeki login-01 örneğinde olduğu gibi blok içindeki ilkel bileşenler packages/ui altına, blokun kendi bileşeni uygulamanın components klasörüne yerleşir.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: shadcn/ui öğrenme rehberi · init komutu · components.json · Next.js kurulumu · CLI komutları · Next.js uygulamasını VPS'e yayınlama