nextjs-fullstack-setup

Next.js App Router + Bun + Drizzle ORM + Better Auth + Tailwind CSS + Biome ile full-stack proje kurulumu, authentication entegrasyonu ve DB workflow'ları.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "nextjs-fullstack-setup" with this command: npx skills add yigit433/nextjs-skills/yigit433-nextjs-skills-nextjs-fullstack-setup

nextjs-fullstack-setup

Amaç

Sıfırdan bir Next.js (App Router) projesi oluşturur. Bun runtime/package manager, Drizzle ORM, Better Auth, Tailwind CSS ve Biome formatter/linter ile tam entegre, production-ready bir full-stack uygulama iskeleti sağlar. Veritabanı yönetimi (migration, seed, reset) için standart workflow'lar ve script'ler içerir.

Ne Zaman Kullanılır

  • Yeni bir full-stack Next.js projesi başlatılacaksa.
  • Bun + Drizzle + Better Auth + Tailwind + Biome standart stack'i isteniyorsa.
  • Authentication dahil tutarlı bir proje yapısına ihtiyaç varsa.
  • DB migration, seed ve reset workflow'ları standartlaştırılacaksa.

Ön Koşullar

  • Bun >= 1.0 kurulu
  • Docker ve Docker Compose kurulu
  • Node.js >= 18 (Next.js uyumluluk)

Sağlanan Template Dosyalar

DosyaAçıklama
templates/docker-compose.ymlPostgreSQL 16 container (healthcheck, named volume)
templates/.env.exampleOrtam değişkenleri (secret'sız)
templates/biome.jsonBiome formatter + linter config
templates/tsconfig.jsonTypeScript strict config
templates/drizzle/schema.tsDrizzle schema (Post + Auth tabloları)
templates/drizzle/seed.tsÖrnek seed dosyası
templates/drizzle.config.tsdrizzle-kit config
scripts/init.shProje bootstrap
scripts/db-migrate.shDev/prod migration
scripts/db-reset.shDev-only DB reset
scripts/db-seed.shSeed çalıştırır

Adımlar

1. Next.js projesi oluştur

bun create next-app@latest my-app --typescript --tailwind --eslint=false --app --src-dir --import-alias "@/*"
cd my-app

ESLint devre dışı çünkü Biome kullanılacak.

2. ESLint'i kaldır, Biome'u kur

bun remove eslint eslint-config-next
bun add -d @biomejs/biome

templates/biome.json dosyasını proje kök dizinine kopyala:

cp ../templates/biome.json ./biome.json

package.json'a script'leri ekle:

{
  "scripts": {
    "check": "biome check .",
    "check:fix": "biome check --write .",
    "format": "biome format --write ."
  }
}

3. Drizzle ORM kur

bun add drizzle-orm postgres
bun add -d drizzle-kit @paralleldrive/cuid2

4. Template dosyaları kopyala

mkdir -p drizzle
cp ../templates/drizzle/schema.ts ./drizzle/schema.ts
cp ../templates/drizzle/seed.ts ./drizzle/seed.ts
cp ../templates/drizzle.config.ts ./drizzle.config.ts
cp ../templates/docker-compose.yml ./docker-compose.yml
cp ../templates/.env.example ./.env.example
cp ../templates/tsconfig.json ./tsconfig.json
cp .env.example .env

.env dosyasındaki değerleri düzenle.

5. Docker Compose ile PostgreSQL başlat

docker compose up -d

Healthcheck ile hazır olmasını bekle:

until docker compose exec -T postgres pg_isready -U postgres; do sleep 1; done

6. İlk schema push

bunx drizzle-kit push

7. DB client singleton oluştur — src/lib/db.ts

import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres";
import * as schema from "@/../drizzle/schema";

const globalForDb = globalThis as unknown as {
  client: ReturnType<typeof postgres> | undefined;
};

const client = globalForDb.client ?? postgres(process.env.DATABASE_URL!);

if (process.env.NODE_ENV !== "production") {
  globalForDb.client = client;
}

export const db = drizzle(client, { schema });

8. Better Auth kur

bun add better-auth

9. Auth config oluştur — src/lib/auth.ts

import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { db } from "./db";

export const auth = betterAuth({
  database: drizzleAdapter(db, { provider: "pg" }),
  emailAndPassword: {
    enabled: true,
  },
  session: {
    expiresIn: 60 * 60 * 24 * 7, // 7 gün
    updateAge: 60 * 60 * 24,      // 1 günde bir yenile
  },
});

Auth stratejisi: Session-based auth tercih ediliyor:

  1. Revoke kolaylığı — JWT'de token süresi dolana kadar iptal zor, session anında silinebilir.
  2. Better Auth varsayılanı — Kütüphanenin birincil ve en iyi test edilmiş yolu.
  3. Server component uyumu — Next.js App Router'da server component'lerden session'a erişmek doğal.

10. Auth client oluştur — src/lib/auth-client.ts

import { createAuthClient } from "better-auth/react";

export const authClient = createAuthClient({
  baseURL: process.env.NEXT_PUBLIC_APP_URL,
});

export const {
  signIn,
  signUp,
  signOut,
  useSession,
} = authClient;

11. API route handler — src/app/api/auth/[...all]/route.ts

import { auth } from "@/lib/auth";
import { toNextJsHandler } from "better-auth/next-js";

export const { GET, POST } = toNextJsHandler(auth);

12. Auth tabloları

Auth tabloları (users, sessions, accounts, verifications) drizzle/schema.ts içinde zaten tanımlı. Migration oluştur:

bunx drizzle-kit generate --name add-auth-tables
bunx drizzle-kit migrate

13. Middleware — src/middleware.ts

import { auth } from "@/lib/auth";
import { headers } from "next/headers";
import { NextRequest, NextResponse } from "next/server";

const protectedRoutes = ["/dashboard"];
const authRoutes = ["/sign-in", "/sign-up"];

export async function middleware(request: NextRequest) {
  const session = await auth.api.getSession({
    headers: await headers(),
  });

  const { pathname } = request.nextUrl;

  // Korumalı route — session yoksa sign-in'e yönlendir
  if (protectedRoutes.some((route) => pathname.startsWith(route))) {
    if (!session) {
      return NextResponse.redirect(new URL("/sign-in", request.url));
    }
  }

  // Auth route — session varsa dashboard'a yönlendir
  if (authRoutes.some((route) => pathname.startsWith(route))) {
    if (session) {
      return NextResponse.redirect(new URL("/dashboard", request.url));
    }
  }

  return NextResponse.next();
}

export const config = {
  matcher: ["/dashboard/:path*", "/sign-in", "/sign-up"],
};

14. Ortam değişkenleri

.env dosyasına ekle:

BETTER_AUTH_SECRET=generate_a_random_secret_here
BETTER_AUTH_URL=http://localhost:3000

Secret üretmek için:

openssl rand -base64 32

15. Proje yapısını standartlaştır

src/
├── app/
│   ├── layout.tsx
│   ├── page.tsx
│   └── api/
│       └── auth/
│           └── [...all]/
│               └── route.ts
├── components/
├── lib/
│   ├── db.ts              # Drizzle client singleton
│   ├── auth.ts            # Better Auth config
│   └── auth-client.ts     # Client-side auth
├── middleware.ts
├── types/
└── styles/
drizzle/
├── schema.ts              # Tablo tanımları
├── seed.ts                # Seed dosyası
└── migrations/            # drizzle-kit tarafından oluşturulur
drizzle.config.ts

16. Doğrulama

bun dev                                        # Proje çalışıyor mu?
bun run check                                  # Biome hatasız mı?
curl -s http://localhost:3000/api/auth/ok       # Auth endpoint yanıt veriyor mu?

DB Workflow'ları

Dev vs Prod Politikası

İşlemDevProd
drizzle-kit generateYeni migration oluştururKullanılmaz
drizzle-kit migrateMigration uygularTek yol
drizzle-kit pushHızlı prototypingKullanılmaz
db resetSerbestEngellendi
db seedSerbestManuel karar

Script Kullanımı

# Bootstrap (sıfırdan kurulum)
bash scripts/init.sh

# Dev migration (schema değişikliği sonrası)
bash scripts/db-migrate.sh --name add-users

# Prod migration (sadece mevcut migration'ları uygula)
NODE_ENV=production bash scripts/db-migrate.sh

# DB reset (dev-only, tüm veriyi siler)
bash scripts/db-reset.sh

# Seed çalıştır
bash scripts/db-seed.sh

DoD (Definition of Done)

  • bun dev ile proje ayağa kalkıyor.
  • Drizzle schema push/migration hatasız çalışıyor.
  • Tailwind sınıfları çalışıyor.
  • bun run check (Biome) hatasız geçiyor.
  • PostgreSQL container çalışıyor ve bağlantı başarılı.
  • Proje yapısı standartlaştırılmış (src/lib, src/components, vb.).
  • Email/password ile kayıt ve giriş çalışıyor.
  • Session oluşturuluyor ve doğrulanıyor.
  • Korumalı route'lara yetkisiz erişim engellenmiş.
  • BETTER_AUTH_SECRET .env.example'da placeholder olarak mevcut.
  • docker compose up -d ile PostgreSQL ayağa kalkıyor.
  • Seed script veritabanını dolduruyor.
  • Dev/prod ortam ayrımı .env ile sağlanmış.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

next-best-practices

No summary provided by upstream source.

Repository SourceNeeds Review
-234
vercel
General

next-cache-components

No summary provided by upstream source.

Repository SourceNeeds Review
General

next-upgrade

No summary provided by upstream source.

Repository SourceNeeds Review