Frontend projeleri büyüdükçe component yapısı hızlıca dağılabiliyor. İşte tam bu noktada Atomic Design, yani arayüzü katmanlı ve kontrollü şekilde inşa etme yaklaşımı devreye giriyor. Bu yazıda Atomic Design’ı sıfırdan ele alacağız, sonra bunu React ve Storybook ile gerçek bir mini örneğe dönüştüreceğiz.
🧩 Atomic Design Nedir?
Atomic Design, arayüzleri küçük ve tekrar kullanılabilir parçalardan başlayarak daha büyük yapılara dönüştürmeyi öneren bir metodoloji. Bu yaklaşımı ilk kez Brad Frost sistematik hale getirdi ve bugün özellikle design system kurarken çok sık karşımıza çıkıyor.
Peki ama bu neden önemli? Çünkü çoğu projede component’ler başta masum başlıyor, sonra HeaderFinal, ProductCardNew, ProductCardUpdated gibi isimlerle kontrolden çıkıyor. Atomic Design bu karmaşayı azaltmak için bize net bir dil veriyor.
Atomic Design temel olarak 5 katmandan oluşur:
★ Atom
HTML seviyesindeki en küçük UI parçalarıdır. Bir button, input, label ya da küçük bir badge burada düşünülebilir.
★ Molecule
Birden fazla atomun birleşmesiyle anlamlı bir iş yapan küçük gruplardır. Mesela bir arama kutusu, yani input + button, iyi bir molecule örneğidir.
★ Organism
Molecule ve atomların birleşmesiyle oluşan daha büyük ve anlamlı bölümlerdir. Header, ProductCard, Sidebar gibi yapılar burada yer alır.
★ Template
Sayfanın iskeletini tanımlar. İçerikten çok yerleşime odaklanır.
★ Page
Template’in gerçek veriyle doldurulmuş halidir. Kullanıcının gördüğü son ekran budur.
Bir dakika, burada duralım ve şunu anlayalım: Atomic Design sadece klasör isimlendirme yöntemi değildir. Asıl mesele, UI sorumluluklarını katmanlara ayırmak ve her katmanın sınırını doğru çizmek.
🤔 Peki Ama Bu Neden Önemli?
Diyelim ki bir e-ticaret uygulaması geliştiriyorsunuz. Ana sayfa, kategori sayfası, kampanya sayfası ve favoriler ekranında birbirine çok benzeyen kartlar, butonlar, filtre alanları ve header yapıları var.
Eğer bu parçaları baştan sistemli kurmazsanız, kısa süre sonra aynı component’in 4 farklı versiyonunu taşımaya başlarsınız. Bu da refactor sürecini yavaşlatır, test yazmayı zorlaştırır ve onboarding süresini uzatır.
Bunu neden tercih ettiğimi açıklayayım:
★ Reusability artar
Bir kere yazdığınız atom veya molecule, farklı sayfalarda tekrar kullanılabilir.
★ Bakım maliyeti düşer
Bir tasarım güncellemesi geldiğinde her dosyayı tek tek aramazsınız.
★ Takım içi iletişim netleşir
“Bu bir organism mi, yoksa molecule mü?” diye konuşabildiğiniz anda ortak bir dil oluşur.
★ Storybook ile çok iyi çalışır
Component’leri izole geliştirmek ve test etmek daha kolay hale gelir.
★ Tasarım sistemi kurmak kolaylaşır
UI kütüphaneniz rastgele büyümez, kontrollü büyür.
Sonuç olarak, Atomic Design bize sadece düzen değil, uzun vadede hız da kazandırır.
⚛️ React Tarafında Atomic Design Nasıl Düşünülmeli?
React, kullanıcı arayüzleri geliştirmek için kullanılan component tabanlı bir JavaScript kütüphanesi. Bu yüzden Atomic Design ile doğal olarak çok iyi anlaşır.
Gelin bunu bir örnekle somutlaştıralım. React tarafında katmanları şu şekilde düşünebiliriz:
★ Atom = Saf, küçük, bağımsız component
Örnek: Button, Input
★ Molecule = Küçük UI kombinasyonları
Örnek: SearchBox
★ Organism = Belirli bir iş yapan büyük blok
Örnek: Header, ProductCard
★ Template = Sayfanın layout iskeleti
Örnek: MainLayout
★ Page = Gerçek veri ve state ile çalışan ekran
Örnek: HomePage
Burada kritik nokta şu: Her büyük component organism olmak zorunda değil. Bazen çok sade bir Card sadece molecule olarak kalabilir. Yani katman kararı verirken boyuta değil, sorumluluğa bakmak gerekir.
Teoriden pratiğe geçelim.
🛠️ Projeyi Kuralım
Bu kadar teori yeter, artık ellerimizi kirletelim! 🛠️ Önce temel React projesini oluşturacağız, sonra Storybook’u ekleyip component-driven development akışını hazırlayacağız.
Adım 1: React projesini oluşturalım
Vite, hızlı development server ve modern build deneyimi sunan bir frontend toolchain çözümüdür. Bu adımda Vite ile React projemizi kuracağız.
Aşağıdaki komutlar yeni bir React projesi oluşturur ve local ortamda ayağa kaldırır.
npm create vite@latest atomic-design-react -- --template react
cd atomic-design-react
npm install
npm run dev Bu komutların kritik kısımlarına bakalım:
- npm create vite@latest yeni proje iskeletini üretir.
- --template react hazır React şablonunu seçer.
- npm run dev development server'ı başlatır.
Adım 2: Storybook’u projeye ekleyelim
Storybook, UI component’lerini uygulamadan bağımsız şekilde geliştirmeyi ve belgelemeyi sağlayan bir tool’dur. Bu adımda Storybook kurulumunu yapacağız.
Aşağıdaki komut Storybook’u mevcut React projesine entegre eder.
npx storybook@latest init Kurulum sonrası şu komutla Storybook’u çalıştırabilirsiniz:
npm run storybook Buradaki önemli noktalar şunlar:
- init komutu proje yapısını analiz eder ve gerekli dosyaları otomatik oluşturur.
- npm run storybook ile component'leri ayrı bir ortamda görüntülemeye başlarsınız.
- Bu yapı özellikle atomic katmanları tek tek doğrulamak için çok faydalıdır.
Kurduğumuza göre şimdi proje yapısını düzenleyelim.
📁 Klasör Yapısını Kuralım
Dağınık bir klasör yapısı, en iyi component mimarisini bile zamanla yorar. O yüzden önce net bir iskelet kuralım.
Aşağıdaki yapı orta ölçekli projeler için temiz bir başlangıç sağlar.
src/
components/
atoms/
Button.jsx
Input.jsx
molecules/
SearchBox.jsx
organisms/
Header.jsx
ProductCard.jsx
templates/
MainLayout.jsx
pages/
HomePage.jsx
data/
products.js
App.jsx
main.jsx
styles.css Bu yapıda dikkat etmenizi istediğim birkaç nokta var:
- components/atoms en küçük ve en genel parçaları tutar.
- molecules atomları bir araya getirir ama hâlâ kontrollü boyuttadır.
- organisms iş değeri taşıyan daha büyük UI bloklarını içerir.
- templates yerleşimi tanımlar, gerçek sayfa verisini değil.
- pages gerçek state ve veri akışının başladığı yerdir.
Şimdi bu klasörleri component’lerle dolduralım.
🧪 Atom Seviyesi Component’ler
Atom seviyesinde amaç basit, küçük ve tekrar kullanılabilir parçalar yazmak. Buradaki component’ler mümkün olduğunca bağımsız olmalı.
Button.jsx
İlk atom olarak bir buton oluşturalım. Farklı varyantları desteklemesi, ileride aynı component’i daha çok yerde kullanmamızı sağlar.
// src/components/atoms/Button.jsx
export default function Button({
children,
variant = "primary",
type = "button",
onClick,
}) {
return (
<button
type={type}
className={`button button--${variant}`}
onClick={onClick}
>
{children}
</button>
);
} Burada kritik satırlar şunlar:
- variant = "primary" ile butona varsayılan bir stil tipi tanımladım.
- children kullanarak buton içeriğini esnek bıraktım.
- Atom seviyesinde işi sadece render etmek, business logic taşımamak.
Input.jsx
Şimdi bir input atomu yazalım. Bunu search, login ya da filtreleme gibi farklı alanlarda rahatça kullanabiliriz.
// src/components/atoms/Input.jsx
export default function Input({
value,
onChange,
placeholder = "Ara...",
...props
}) {
return (
<input
className="input"
value={value}
onChange={onChange}
placeholder={placeholder}
{...props}
/>
);
} Bu component’te özellikle şunlara dikkat edin:
- ...props ile input'u esnek hale getirdim.
- value ve onChange dışarıdan geldiği için component kontrollü şekilde kullanılabilir.
- Atom seviyesinde gereksiz state eklemedim.
💡 Küçük özet geçeyim: Atomlar ne kadar sade olursa, üst katmanlarda o kadar rahat hareket ederiz.
🧬 Molecule Seviyesi Component’ler
Molecule katmanında artık küçük ama anlamlı kombinasyonlar kuruyoruz. Tek başına Input sadece bir alan sunar, ama SearchBox belirli bir amacı temsil eder.
SearchBox.jsx
Bu component, bir input ve bir button atomunu bir araya getiriyor. Yani artık sadece görsel bir parça değil, kullanıcı niyeti taşıyan bir yapı oluşturuyoruz.
// src/components/molecules/SearchBox.jsx
import Button from "../atoms/Button";
import Input from "../atoms/Input";
export default function SearchBox({ query, onQueryChange, onSearch }) {
return (
<div className="search-box">
<Input
value={query}
onChange={(event) => onQueryChange(event.target.value)}
placeholder="Ürün ara"
/>
<Button onClick={onSearch}>Ara</Button>
</div>
);
} Buradaki tasarım kararlarını netleştirelim:
- SearchBox kendi state'ini tutmuyor, kontrolü page katmanına bırakıyor.
- Input ve Button atom olarak kaldı, sadece burada bir araya geldi.
- Bu component artık sayfada anlamlı bir iş yapıyor, bu yüzden molecule olarak düşünmek mantıklı.
🏗️ Organism Seviyesi Component’ler
Organism katmanında artık daha anlamlı arayüz blokları kuruyoruz. Burada component’ler tek bir küçük görevi değil, sayfadaki belirgin bir bölümü temsil eder.
Header.jsx
Önce arama alanını ve aksiyon butonunu bir araya getiren bir header oluşturalım.
// src/components/organisms/Header.jsx
import Button from "../atoms/Button";
import SearchBox from "../molecules/SearchBox";
export default function Header({ query, onQueryChange, onSearch }) {
return (
<header className="header">
<div className="header__brand">ShopSphere</div>
<SearchBox
query={query}
onQueryChange={onQueryChange}
onSearch={onSearch}
/>
<Button variant="secondary">Sepetim</Button>
</header>
);
} Burada dikkat etmeniz gereken noktalar:
- Header, artık tek bir atom ya da molecule değil, daha büyük bir arayüz parçası.
- İçinde hem molecule hem atom kullanıyor.
- Marka alanı, arama alanı ve sepet aksiyonu bir araya gelerek işlevsel bir bölüm oluşturuyor.
ProductCard.jsx
Şimdi e-ticaret senaryosunda çok sık kullanacağımız product card component’ini yazalım.
// src/components/organisms/ProductCard.jsx
import Button from "../atoms/Button";
export default function ProductCard({ product }) {
return (
<article className="product-card">
<div className="product-card__emoji" aria-hidden="true">
{product.emoji}
</div>
<h3 className="product-card__title">{product.title}</h3>
<p className="product-card__description">{product.description}</p>
<div className="product-card__footer">
<strong>{product.price} TL</strong>
<Button>Sepete Ekle</Button>
</div>
</article>
);
} Buradaki önemli detaylar:
- product nesnesi organism seviyesinde anlam kazanıyor.
- Button atom olarak tekrar kullanılıyor.
- Kartın tamamı sayfada tek başına büyük bir iş birimi olduğu için organism olarak düşünülüyor.
📐 Template ve Page Katmanları
Çoğumuzun en çok karıştırdığı yer burası. Template ile page aynı şey değiller
Template, sayfanın yapısını tanımlar.
Page ise o yapının gerçek veri ve state ile çalışan halidir.
MainLayout.jsx
Önce template katmanını oluşturalım. Bu dosya veri yönetmek yerine sayfanın iskeletini kuracak.
// src/components/templates/MainLayout.jsx
import Header from "../organisms/Header";
export default function MainLayout({
query,
onQueryChange,
onSearch,
children,
}) {
return (
<div className="layout">
<Header
query={query}
onQueryChange={onQueryChange}
onSearch={onSearch}
/>
<main className="layout__content">{children}</main>
</div>
);
} Bu yapının kritik tarafları şunlar:
- children ile template'i esnek hale getirdim.
- MainLayout, yerleşimi kuruyor ama ürün verisini bilmiyor.
- Bu ayrım büyüyen projelerde çok ciddi temizlik sağlar.
Template mümkün olduğunca içerik bağımsız olmalı. Veri, filtreleme ve sayfa davranışları page katmanına ait olmalı.
🛍️ Örnek Proje: Mini Bir E-Ticaret Arayüzü Geliştirelim
Gelin bunu bir örnekle somutlaştıralım. Şimdi yukarıda oluşturduğumuz katmanları gerçek bir sayfada birleştireceğiz.
Adım 1: Sahte ürün verisini oluşturalım
Önce page katmanında kullanacağımız örnek ürün listesini hazırlayacağız.
// src/data/products.js
export const products = [
{
id: 1,
emoji: "⌨️",
title: "Mechanical Keyboard",
description: "Hot-swappable, RGB destekli kompakt klavye.",
price: 2499,
},
{
id: 2,
emoji: "🖱️",
title: "Gaming Mouse",
description: "Hafif gövde, yüksek DPI ve düşük latency.",
price: 1499,
},
{
id: 3,
emoji: "🎧",
title: "Wireless Headset",
description: "Uzun pil ömrü ve düşük gecikmeli bağlantı.",
price: 3299,
},
]; Bu dosyada özellikle şunları amaçlıyoruz:
- Page katmanını gerçek API’dan bağımsız şekilde test edebiliyoruz.
- Storybook tarafında da aynı mock datayı kullanabiliyoruz.
- Geliştirme sırasında veri akışını rahatça görebiliyoruz.
Adım 2: HomePage component'ini yazalım
Bu adımda gerçek state’i yöneten page component’ini oluşturacağız.
// src/pages/HomePage.jsx
import { useMemo, useState } from "react";
import ProductCard from "../components/organisms/ProductCard";
import MainLayout from "../components/templates/MainLayout";
import { products } from "../data/products";
export default function HomePage() {
const [query, setQuery] = useState("");
const filteredProducts = useMemo(() => {
return products.filter((product) =>
product.title.toLowerCase().includes(query.toLowerCase())
);
}, [query]);
const handleSearch = () => {
console.log(`Searching for: ${query}`);
};
return (
<MainLayout
query={query}
onQueryChange={setQuery}
onSearch={handleSearch}
>
<section className="page-intro">
<h1>Öne Çıkan Ürünler</h1>
<p>Atomic Design yaklaşımıyla oluşturulmuş örnek katalog ekranı.</p>
</section>
<section className="product-grid">
{filteredProducts.map((product) => (
<ProductCard key={product.id} product={product} />
))}
</section>
</MainLayout>
);
} Bu dosyada en kritik noktalar şunlar:
- Gerçek state burada tutuluyor, yani doğru katmandayız.
- Filtreleme mantığı page seviyesinde çözüldü.
- MainLayout sadece yerleşim sağlıyor, veriyi yönetmiyor.
Adım 3: Uygulamanın giriş noktasını bağlayalım
Artık sayfayı uygulamanın ana girişine bağlayacağız.
// src/App.jsx
import HomePage from "./pages/HomePage";
import "./styles.css";
export default function App() {
return <HomePage />;
} Bu dosya küçük görünüyor ama önemli:
- App artık page seviyesindeki ekranı render ediyor.
- Global stilleri tek noktadan yüklüyoruz.
- Atomic katmanlar yukarıdan aşağıya düzgün şekilde bağlanmış oluyor.
Adım 4: Minimum stilleri ekleyelim
Odak noktamız mimari olsa da, component sınırlarını daha net görmek için küçük bir stil dosyası ekleyeceğiz.
/* src/styles.css */
:root {
font-family: Inter, system-ui, sans-serif;
color: #e2e8f0;
background: #0f172a;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.layout__content {
max-width: 1100px;
margin: 0 auto;
padding: 32px 20px;
}
.header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
padding: 20px;
border-bottom: 1px solid #1e293b;
background: #111827;
}
.header__brand {
font-size: 20px;
font-weight: 700;
}
.search-box {
display: flex;
gap: 12px;
flex: 1;
max-width: 520px;
}
.input,
.button {
border-radius: 12px;
border: 1px solid #334155;
padding: 12px 16px;
}
.input {
flex: 1;
background: #0f172a;
color: #e2e8f0;
}
.button {
cursor: pointer;
color: white;
background: #2563eb;
}
.button--secondary {
background: #334155;
}
.page-intro {
margin-bottom: 24px;
}
.product-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 16px;
}
.product-card {
padding: 20px;
border: 1px solid #1e293b;
border-radius: 18px;
background: #111827;
}
.product-card__emoji {
font-size: 40px;
margin-bottom: 12px;
}
.product-card__footer {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 16px;
} Bu stil dosyasında özellikle şunlar önemli:
- Karanlık tema ile component sınırlarını daha görünür yaptım.
- product-grid yapısı card organism'lerini rahat incelememizi sağlıyor.
- button--secondary gibi varyant sınıfları atom seviyesindeki esnekliği gösteriyor.
Son durumda elimizde çalışan, küçük ama mimarisi oturmuş bir React örneği var.
📝 Son dönemde makaleleri yazarken hep SCSS ile Module CSS kullandığımı farkettim. Normalde Storybook projesi veya başka bir proje yapacak olsam, ben yine Module CSS kullanırım ama bu sefer farklılık olsun ve eski günleri analım diye 🥲 makalede BEM kullandım
👀 Storybook ile Component’leri İzole Geliştirmek
Peki Storybook burada neden bu kadar değerli? Çünkü Atomic Design ile kurduğumuz katmanları tek tek, uygulamaya bağımlı olmadan test etmemizi sağlıyor.
İşte tam bu noktada Storybook devreye giriyor. Uygulama ayağa kalkmadan bile Button, SearchBox ya da ProductCard component'ini ayrı ayrı doğrulayabiliyorsunuz.
Adım 1: Button için bir story yazalım
İlk olarak atom seviyesindeki bir component’i Storybook’a taşıyacağız.
// src/components/atoms/Button.stories.js
import Button from "./Button";
export default {
title: "Atoms/Button",
component: Button,
args: {
children: "Sepete Ekle",
variant: "primary",
},
};
export const Primary = {};
export const Secondary = {
args: {
children: "Detay",
variant: "secondary",
},
}; Bu story dosyasında dikkat edilmesi gerekenler:
- title: "Atoms/Button" ile component'i atomic katmana göre sınıflandırdım.
- args sayesinde farklı varyasyonları hızlıca test edebilirsiniz.
- Aynı atom için birden fazla görünüm tanımlamak çok kolay hale gelir.
ProductCard component’ini uygulamadan bağımsız, tek başına çalışan bir örnek olarak görebilirsiniz. Storybook ile Atomic Design birleşince component’leri üretmek, test etmek ve paylaşmak ciddi şekilde kolaylaşıyor.
Adım 2: ProductCard için bir story yazalım
Bu kez organism seviyesindeki daha büyük bir component’i tek başına test edeceğiz.
// src/components/organisms/ProductCard.stories.js
import ProductCard from "./ProductCard";
export default {
title: "Organisms/ProductCard",
component: ProductCard,
args: {
product: {
id: 1,
emoji: "⌨️",
title: "Mechanical Keyboard",
description: "Hot-swappable, RGB destekli kompakt klavye.",
price: 2499,
},
},
};
export const Default = {}; Buradaki önemli noktalar:
- Organism component’leri de page’den bağımsız şekilde test edebiliyoruz.
- Mock data kullanarak gerçek API beklemeden geliştirme yapıyoruz.
- Görsel regresyon kontrolü ve UI review süreçleri kolaylaşıyor.
ProductCard component'ini uygulamadan bağımsız, tek başına çalışan bir örnek olarak görebilirsiniz.
Storybook ile Atomic Design birleşince component’leri üretmek, test etmek ve paylaşmak ciddi şekilde kolaylaşıyor.
⚖️ Atomic Design’ın Avantajları ve Dezavantajları
Her iyi yaklaşım gibi Atomic Design’ın da güçlü ve zayıf tarafları var. Körü körüne uygulamak yerine ne kazandırdığını ve nerede maliyet oluşturduğunu bilmek gerekiyor.
Avantajlar
★ Component sınırları daha net olur.
★ Reusability ciddi şekilde artar.
★ Storybook, test ve design system süreçleri güçlenir.
★ Büyük ekiplerde ortak bir UI dili oluşur.
★ Refactor süreçleri daha güvenli hale gelir.
Dezavantajlar
★ Küçük projelerde fazla soyutlama hissi yaratabilir.
★ Katmanları yanlış yorumlarsanız gereksiz dosya kalabalığı oluşur.
★ Her component’i parçalamaya çalışmak geliştirme hızını düşürebilir.
★ Yeni başlayan ekipler için ilk etapta biraz disiplin ister.
Bunu çok net söyleyeyim: Atomic Design sihirli çözüm değil. Ama UI yoğun ve büyüme potansiyeli olan projelerde çok güçlü bir çerçeve sunuyor.
Sık Yapılan Hatalar 😅
Bu yaklaşımı uygularken en sık gördüğüm hatalar şunlar:
★ Her şeyi atomlaştırmak
Bir component küçük diye otomatik olarak atom olmaz. Önemli olan sorumluluğudur.
★ Template ile page’i karıştırmak
Layout bilgisi template’te, veri ve davranış page’de kalmalı.
★ Business logic’i atomlara gömmek
Atom seviyesindeki component’ler mümkün olduğunca saf kalmalı.
★ Klasör yapısını amaç haline getirmek
Atomic Design, klasör estetiği için değil sürdürülebilir UI mimarisi için vardır.
★ Storybook’u sadece vitrin gibi kullanmak
Asıl değer, component’i izole geliştirip edge case’leri erken görmekte.
Bir başka kritik hata da naming tarafında yapılıyor. Card2, HeaderNew, ButtonLatest gibi isimler gördüğünüz anda durup yeniden düşünün.
Ne Zaman Tercih Etmeliyiz? 🤔
Atomic Design, özellikle component sayısı artan ve tekrar kullanılabilir arayüz parçalarının çoğaldığı projelerde çok işe yarıyor. React ile birlikte düşündüğümüzde bu yaklaşım daha da doğal hale geliyor çünkü zaten component tabanlı bir dünyada çalışıyoruz.
Eğer küçük ve tek ekranlık bir uygulama geliştiriyorsanız, belki bu kadar katman kurmanıza gerek yok. Ama bir design system oluşturuyorsanız, farklı ekiplerin aynı UI parçalarını paylaştığı bir yapı kuruyorsanız ya da proje hızlı büyüyorsa, Atomic Design çok mantıklı bir tercih oluyor.
Sonuç olarak, Atomic Design’ı sadece teori olarak değil, günlük geliştirme pratiğinin bir parçası olarak düşünmek gerekiyor. React ve Storybook ile birlikte kullandığınızda elinizde daha düzenli, daha okunabilir ve daha ölçeklenebilir bir frontend mimarisi oluyor.
📬 Geri Bildirim
Makaleyi yazarken, kaynakları belirleme, araştırma ve yazım denetimi için GPT 5.4 High modelini kullandım. Resimleri üretmek için ise Gemini 3 Pro Preview 2k (Nano Banana Pro) modelini kullandım.
Yazı ile ilgili tavsiye, öneri, eleştirileri dikkate alıyorum. İletişime geçmek isterseniz bana websitemdeki sosyal medya adreslerimden veya Linkedin üzerinden ulaşabilirsiniz.
Sevgiyle kalın, Yasin 🤗
📚 Makaleyi Yazarken Kullandığım Kaynaklar
- Atomic Design by Brad Frost — Atomic Design metodolojisinin temel mantığını ve katmanlarını netleştirmek için kullandım.
- React Documentation — React component yapısı, state yönetimi ve temel mimari yaklaşımı için kullandım.
- Storybook for React — Storybook kurulumu ve React entegrasyonu için referans aldım.
- Vite Guide — React projesini hızlı şekilde başlatmak için Vite kurulum akışını doğrulamak için kullandım.
- Storybook Writing Stories — Story dosyalarının nasıl yazılacağını netleştirmek için kullandım.
- BEM CSS Convention — Makale içerisinde kullancığım CSS metadolojisi