@mandujs/skills 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,174 @@
1
+ ---
2
+ name: mandu-deploy
3
+ description: "프로덕션 배포 파이프라인. Docker/CI-CD/nginx"
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ # Mandu Deploy
8
+
9
+ 프로덕션 배포 파이프라인 가이드.
10
+ Build -> Test -> Deploy 체크리스트와 Docker/CI-CD/nginx 설정을 다룹니다.
11
+
12
+ ## Build -> Test -> Deploy Checklist
13
+
14
+ ### 1. Pre-Deploy Checks
15
+
16
+ ```bash
17
+ # Architecture validation
18
+ bunx mandu guard arch --ci
19
+
20
+ # TypeScript check
21
+ bunx tsc --noEmit
22
+
23
+ # Run tests
24
+ bun test
25
+
26
+ # Production build
27
+ bun run build
28
+ ```
29
+
30
+ ### 2. Dockerfile
31
+
32
+ ```dockerfile
33
+ FROM oven/bun:1.2-alpine AS base
34
+ WORKDIR /app
35
+
36
+ # Install dependencies
37
+ FROM base AS deps
38
+ COPY package.json bun.lock* ./
39
+ RUN bun install --frozen-lockfile --production
40
+
41
+ # Build
42
+ FROM base AS build
43
+ COPY package.json bun.lock* ./
44
+ RUN bun install --frozen-lockfile
45
+ COPY . .
46
+ RUN bun run build
47
+
48
+ # Production
49
+ FROM base AS production
50
+ COPY --from=deps /app/node_modules ./node_modules
51
+ COPY --from=build /app/.mandu ./.mandu
52
+ COPY --from=build /app/app ./app
53
+ COPY --from=build /app/src ./src
54
+ COPY --from=build /app/spec ./spec
55
+ COPY --from=build /app/package.json ./
56
+
57
+ ENV NODE_ENV=production
58
+ ENV PORT=3333
59
+ EXPOSE 3333
60
+
61
+ CMD ["bun", "run", "start"]
62
+ ```
63
+
64
+ ### 3. docker-compose.yml
65
+
66
+ ```yaml
67
+ version: "3.8"
68
+ services:
69
+ app:
70
+ build: .
71
+ ports:
72
+ - "3333:3333"
73
+ environment:
74
+ - NODE_ENV=production
75
+ - DATABASE_URL=${DATABASE_URL}
76
+ restart: unless-stopped
77
+ healthcheck:
78
+ test: ["CMD", "curl", "-f", "http://localhost:3333/api/health"]
79
+ interval: 30s
80
+ timeout: 10s
81
+ retries: 3
82
+ ```
83
+
84
+ ### 4. GitHub Actions CI/CD
85
+
86
+ ```yaml
87
+ # .github/workflows/deploy.yml
88
+ name: Deploy
89
+ on:
90
+ push:
91
+ branches: [main]
92
+
93
+ jobs:
94
+ deploy:
95
+ runs-on: ubuntu-latest
96
+ steps:
97
+ - uses: actions/checkout@v4
98
+ - uses: oven-sh/setup-bun@v2
99
+ with:
100
+ bun-version: latest
101
+
102
+ - run: bun install --frozen-lockfile
103
+ - run: bunx mandu guard arch --ci
104
+ - run: bun test
105
+ - run: bun run build
106
+
107
+ - name: Deploy
108
+ run: |
109
+ # docker build & push, or platform-specific deploy
110
+ docker build -t myapp:${{ github.sha }} .
111
+ docker push myapp:${{ github.sha }}
112
+ ```
113
+
114
+ ### 5. nginx Reverse Proxy
115
+
116
+ ```nginx
117
+ upstream mandu_app {
118
+ server 127.0.0.1:3333;
119
+ keepalive 32;
120
+ }
121
+
122
+ server {
123
+ listen 80;
124
+ server_name example.com;
125
+
126
+ # Static assets (long cache)
127
+ location /.mandu/client/ {
128
+ proxy_pass http://mandu_app;
129
+ proxy_cache_valid 200 30d;
130
+ add_header Cache-Control "public, max-age=2592000, immutable";
131
+ }
132
+
133
+ # API routes
134
+ location /api/ {
135
+ proxy_pass http://mandu_app;
136
+ proxy_http_version 1.1;
137
+ proxy_set_header Upgrade $http_upgrade;
138
+ proxy_set_header Connection "upgrade";
139
+ proxy_set_header Host $host;
140
+ proxy_set_header X-Real-IP $remote_addr;
141
+ }
142
+
143
+ # All other routes (SSR)
144
+ location / {
145
+ proxy_pass http://mandu_app;
146
+ proxy_http_version 1.1;
147
+ proxy_set_header Host $host;
148
+ proxy_set_header X-Real-IP $remote_addr;
149
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
150
+ proxy_set_header X-Forwarded-Proto $scheme;
151
+ }
152
+ }
153
+ ```
154
+
155
+ ## Environment Variables
156
+
157
+ ```bash
158
+ # .env.production
159
+ NODE_ENV=production
160
+ PORT=3333
161
+ DATABASE_URL=postgresql://user:pass@host:5432/db
162
+ ```
163
+
164
+ IMPORTANT: `.env` 파일은 절대 git에 커밋하지 않기. `.gitignore`에 추가 확인.
165
+
166
+ ## Production Optimizations
167
+
168
+ | Area | Action |
169
+ |------|--------|
170
+ | Build | `bun run build` (minification, tree-shaking) |
171
+ | CSS | Tailwind purge (자동) |
172
+ | Islands | `"visible"` or `"idle"` priority (not `"immediate"`) |
173
+ | Static | nginx에서 `.mandu/client/` 장기 캐시 |
174
+ | Health | `/api/health` endpoint 필수 |
@@ -0,0 +1,121 @@
1
+ ---
2
+ name: mandu-explain
3
+ description: |
4
+ Mandu 개념 설명. Island/Filling/Guard/Contract/Slot/SSR/ISR 등 '뭐야'/'어떻게' 시 자동 호출
5
+ ---
6
+
7
+ # Mandu Explain
8
+
9
+ Mandu 프레임워크의 핵심 개념 18가지를 설명하는 레퍼런스.
10
+
11
+ ## Core Concepts
12
+
13
+ ### 1. Island Architecture
14
+ 페이지의 대부분은 정적 HTML로 서버 렌더링하고, 인터랙티브한 부분만 JavaScript를 로드하는 패턴.
15
+ ```
16
+ [Static HTML] [Static HTML] [Island: JS] [Static HTML]
17
+ ```
18
+ 장점: 초기 로딩 속도, 작은 번들 크기, SEO 친화적.
19
+
20
+ ### 2. Filling (Mandu.filling())
21
+ API 핸들러를 체이닝으로 작성하는 API. Express의 미들웨어와 유사하지만 타입 안전.
22
+ ```typescript
23
+ Mandu.filling().guard(authCheck).get(handler).post(handler)
24
+ ```
25
+
26
+ ### 3. Guard
27
+ 아키텍처 규칙을 코드 레벨에서 강제하는 시스템. import 방향, 파일 위치, 금지된 의존성을 검사.
28
+ ```bash
29
+ bunx mandu guard arch # 전체 프로젝트 검사
30
+ ```
31
+
32
+ ### 4. Contract
33
+ Zod 스키마 기반 API 계약. 클라이언트-서버 간 타입을 공유하고 런타임 validation을 수행.
34
+ ```typescript
35
+ // src/shared/contracts/user.contract.ts
36
+ export const CreateUser = z.object({ name: z.string(), email: z.string().email() });
37
+ ```
38
+
39
+ ### 5. Slot
40
+ 서버에서 렌더링 전에 실행되는 데이터 로더. `spec/slots/*.slot.ts`에 위치.
41
+ ```typescript
42
+ // spec/slots/dashboard.slot.ts - page 렌더링 전에 데이터를 fetch
43
+ export default Mandu.filling().get(async (ctx) => ctx.ok({ stats: await getStats() }));
44
+ ```
45
+
46
+ ### 6. SSR (Server-Side Rendering)
47
+ 모든 페이지를 서버에서 HTML로 렌더링. `app/layout.tsx`에서 `<html>/<head>/<body>` 태그 불필요 (자동 생성).
48
+
49
+ ### 7. Streaming SSR
50
+ 서버에서 HTML을 청크 단위로 스트리밍. 첫 바이트 시간(TTFB)을 단축.
51
+
52
+ ### 8. Hydration
53
+ 서버 렌더링된 HTML에 JavaScript 인터랙티비티를 부착하는 과정.
54
+ Priority: `immediate` > `visible` > `idle` > `interaction`
55
+
56
+ ### 9. FS Routes
57
+ 파일 시스템 기반 라우팅. `app/` 폴더 구조가 URL이 됨.
58
+ - `app/page.tsx` -> `/`
59
+ - `app/users/[id]/page.tsx` -> `/users/:id`
60
+
61
+ ### 10. Layout
62
+ 페이지를 감싸는 공통 UI 래퍼. `<html>/<head>/<body>` 사용 금지.
63
+ ```tsx
64
+ export default function Layout({ children }) {
65
+ return <div className="min-h-screen">{children}</div>;
66
+ }
67
+ ```
68
+
69
+ ### 11. Route Groups
70
+ `(name)` 괄호로 감싼 폴더는 URL에 영향 없이 라우트를 그룹화.
71
+ ```
72
+ app/(auth)/login/page.tsx -> /login
73
+ app/(auth)/signup/page.tsx -> /signup
74
+ ```
75
+
76
+ ### 12. MCP (Model Context Protocol)
77
+ AI 에이전트가 프레임워크 도구를 직접 호출하는 인터페이스.
78
+ `@mandujs/mcp`가 50+ 도구를 제공: negotiate, generate, guard, brain 등.
79
+
80
+ ### 13. ATE (Automated Test Engine)
81
+ API 엔드포인트의 테스트를 자동 생성하는 엔진.
82
+
83
+ ### 14. Brain
84
+ 코드 분석 및 진단 시스템. 프로젝트 구조, 의존성, 성능 이슈를 분석.
85
+
86
+ ### 15. Presets
87
+ Guard가 사용하는 아키텍처 템플릿: `mandu`, `fsd`, `clean`, `hexagonal`, `atomic`, `cqrs`
88
+
89
+ ### 16. Lockfile (.mandu/lockfile.json)
90
+ 프로젝트 설정의 무결성을 보장하는 해시 기반 잠금 파일.
91
+
92
+ ### 17. useServerData
93
+ Island에서 서버 Slot이 주입한 데이터를 읽는 클라이언트 훅.
94
+ ```typescript
95
+ const data = useServerData<UserData>("user-profile");
96
+ ```
97
+
98
+ ### 18. useIslandEvent
99
+ Island 간 통신을 위한 이벤트 시스템.
100
+ ```typescript
101
+ const { emit, on } = useIslandEvent();
102
+ emit("cart:updated", { count: 5 });
103
+ ```
104
+
105
+ ## Architecture Layers
106
+
107
+ ```
108
+ app/ UI (pages, layouts, islands)
109
+ src/client/ Client-side code
110
+ src/server/ Server-side business logic
111
+ src/shared/ Shared types, contracts, utils
112
+ spec/ Slots, tests
113
+ ```
114
+
115
+ ## Key Import Rules
116
+
117
+ | From | Import |
118
+ |------|--------|
119
+ | Island files | `@mandujs/core/client` |
120
+ | Server files | `@mandujs/core` |
121
+ | Shared code | `@/shared/*` |
@@ -0,0 +1,131 @@
1
+ ---
2
+ name: mandu-fs-routes
3
+ description: |
4
+ 파일 시스템 라우팅 규칙. layout에 html/head/body 금지.
5
+ app/ 폴더, page.tsx, route.ts, layout.tsx, [id] 작업 시 자동 호출.
6
+ ---
7
+
8
+ # Mandu FS Routes
9
+
10
+ 파일 시스템 기반 라우팅. `app/` 폴더의 파일 구조가 URL이 됩니다.
11
+
12
+ ## File Naming Conventions
13
+
14
+ | File | Purpose | Export |
15
+ |------|---------|--------|
16
+ | `page.tsx` | Page component | `default` function component |
17
+ | `route.ts` | API handler | `default` Mandu.filling() chain |
18
+ | `layout.tsx` | Shared layout | `default` function with `children` prop |
19
+ | `loading.tsx` | Loading UI | `default` function component |
20
+ | `error.tsx` | Error UI | `default` function component |
21
+
22
+ ## URL Mapping
23
+
24
+ | File Path | URL |
25
+ |-----------|-----|
26
+ | `app/page.tsx` | `/` |
27
+ | `app/about/page.tsx` | `/about` |
28
+ | `app/blog/[slug]/page.tsx` | `/blog/:slug` |
29
+ | `app/users/[id]/page.tsx` | `/users/:id` |
30
+ | `app/docs/[...path]/page.tsx` | `/docs/*` (catch-all) |
31
+ | `app/(auth)/login/page.tsx` | `/login` (grouped) |
32
+ | `app/api/users/route.ts` | `/api/users` |
33
+ | `app/api/users/[id]/route.ts` | `/api/users/:id` |
34
+
35
+ ## Layout Rules (CRITICAL)
36
+
37
+ Layout MUST NOT include `<html>`, `<head>`, or `<body>` tags.
38
+ Mandu SSR generates these automatically.
39
+
40
+ ```tsx
41
+ // app/layout.tsx - CORRECT
42
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
43
+ return (
44
+ <div className="min-h-screen bg-background font-sans antialiased">
45
+ {children}
46
+ </div>
47
+ );
48
+ }
49
+ ```
50
+
51
+ ```tsx
52
+ // app/layout.tsx - WRONG (causes double-wrapping)
53
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
54
+ return (
55
+ <html> // <-- DO NOT include
56
+ <head /> // <-- DO NOT include
57
+ <body> // <-- DO NOT include
58
+ {children}
59
+ </body>
60
+ </html>
61
+ );
62
+ }
63
+ ```
64
+
65
+ Nested layouts wrap child pages:
66
+ ```
67
+ app/layout.tsx -> wraps ALL pages
68
+ app/dashboard/layout.tsx -> wraps /dashboard/* pages
69
+ ```
70
+
71
+ ## Page Components
72
+
73
+ ```tsx
74
+ // app/dashboard/page.tsx
75
+ export default function DashboardPage() {
76
+ return (
77
+ <main>
78
+ <h1>Dashboard</h1>
79
+ </main>
80
+ );
81
+ }
82
+ ```
83
+
84
+ Pages are server-rendered by default. No `"use client"` needed unless using Islands.
85
+
86
+ ## API Routes
87
+
88
+ ```typescript
89
+ // app/api/users/route.ts
90
+ import { Mandu } from "@mandujs/core";
91
+
92
+ export default Mandu.filling()
93
+ .get((ctx) => ctx.ok({ users: [] }))
94
+ .post(async (ctx) => {
95
+ const body = await ctx.body<{ name: string }>();
96
+ return ctx.created({ user: body });
97
+ });
98
+ ```
99
+
100
+ API routes use `.ts` extension (NOT `.tsx`).
101
+
102
+ ## Dynamic Routes
103
+
104
+ ```tsx
105
+ // app/users/[id]/page.tsx
106
+ export default function UserPage({ params }: { params: { id: string } }) {
107
+ return <h1>User {params.id}</h1>;
108
+ }
109
+
110
+ // app/docs/[...path]/page.tsx
111
+ export default function DocsPage({ params }: { params: { path: string[] } }) {
112
+ return <h1>Doc: {params.path.join("/")}</h1>;
113
+ }
114
+ ```
115
+
116
+ ## Route Groups
117
+
118
+ Parenthesized folders create logical groups without affecting the URL:
119
+
120
+ ```
121
+ app/(marketing)/about/page.tsx -> /about
122
+ app/(marketing)/pricing/page.tsx -> /pricing
123
+ app/(app)/dashboard/page.tsx -> /dashboard
124
+ ```
125
+
126
+ ## Common Mistakes
127
+
128
+ - Adding `<html>/<head>/<body>` in layout.tsx (SSR does this)
129
+ - Using `route.tsx` instead of `route.ts` for API handlers
130
+ - Forgetting to export default from page/layout files
131
+ - Mixing page.tsx and route.ts in the same directory
@@ -0,0 +1,150 @@
1
+ ---
2
+ name: mandu-guard-guide
3
+ description: |
4
+ Guard 아키텍처 가이드. 위반 수정/프리셋 선택/레이어 규칙. guard violation 시 자동 호출
5
+ ---
6
+
7
+ # Mandu Guard Guide
8
+
9
+ Mandu Guard 아키텍처 강제 시스템의 상세 가이드.
10
+ 6개 프리셋, 위반 유형별 수정 방법, 레이어 규칙을 다룹니다.
11
+
12
+ ## 6 Presets
13
+
14
+ ### mandu (default)
15
+ FSD + Clean Architecture 하이브리드. 프론트엔드와 백엔드 모두 커버.
16
+ ```typescript
17
+ // mandu.config.ts
18
+ export default { guard: { preset: "mandu" } };
19
+ ```
20
+
21
+ ### fsd (Feature-Sliced Design)
22
+ 프론트엔드 전용. 7계층 레이어 구조.
23
+ ```
24
+ app > pages > widgets > features > entities > shared
25
+ ```
26
+
27
+ ### clean (Clean Architecture)
28
+ 백엔드 전용. 의존성 역전 원칙.
29
+ ```
30
+ api > application > domain > infra > core > shared
31
+ ```
32
+
33
+ ### hexagonal (Ports & Adapters)
34
+ 포트와 어댑터 패턴. domain이 중심, adapters가 외부 의존성 처리.
35
+ ```
36
+ adapters > ports > application > domain
37
+ ```
38
+
39
+ ### atomic (Atomic Design)
40
+ UI 컴포넌트 전용. atoms -> molecules -> organisms -> templates -> pages.
41
+
42
+ ### cqrs (Command Query Responsibility Segregation)
43
+ 명령과 조회를 분리. command, query, event, dto 전용 구조.
44
+
45
+ ## Violation Types and Fixes
46
+
47
+ ### LAYER_VIOLATION (error)
48
+ 상위 레이어가 하위 레이어를 import하는 것만 허용.
49
+
50
+ ```typescript
51
+ // BAD: shared가 features를 import (하위 -> 상위)
52
+ // src/shared/utils/helper.ts
53
+ import { useAuth } from "@/features/auth"; // VIOLATION
54
+
55
+ // FIX: 의존 방향 반전, 또는 shared에 인터페이스 정의
56
+ // src/shared/types/auth.ts
57
+ export interface AuthContext { userId: string; }
58
+ ```
59
+
60
+ ### FORBIDDEN_IMPORT (error)
61
+ 클라이언트 코드에서 서버 전용 모듈 import 금지.
62
+
63
+ ```typescript
64
+ // BAD: island에서 fs import
65
+ // app/editor.island.tsx
66
+ import fs from "fs"; // VIOLATION
67
+
68
+ // FIX: 서버 로직은 slot으로 분리
69
+ // spec/slots/editor.slot.ts
70
+ import fs from "fs"; // OK (server-only)
71
+ ```
72
+
73
+ ### WRONG_SLOT_LOCATION (warning)
74
+ Slot 파일이 잘못된 위치에 있음.
75
+
76
+ ```
77
+ BAD: src/server/slots/user.slot.ts
78
+ FIX: spec/slots/user.slot.ts
79
+ ```
80
+
81
+ ### GENERATED_DIRECT_EDIT (error)
82
+ 자동 생성된 파일을 직접 수정하면 안 됨.
83
+
84
+ ```
85
+ BAD: .mandu/generated/server/routes.ts 직접 편집
86
+ FIX: 소스 파일을 수정하고 regenerate
87
+ ```
88
+
89
+ ### CONTRACT_MISSING (warning)
90
+ API route에 대응하는 contract가 없음.
91
+
92
+ ```
93
+ Missing: src/shared/contracts/user.contract.ts
94
+ For: app/api/users/route.ts
95
+ FIX: contract 파일 생성
96
+ ```
97
+
98
+ ### SLOT_NAMING (warning)
99
+ Slot 파일명이 규칙에 맞지 않음.
100
+
101
+ ```
102
+ BAD: spec/slots/userData.ts
103
+ FIX: spec/slots/user-data.slot.ts
104
+ ```
105
+
106
+ ## CLI Commands
107
+
108
+ ```bash
109
+ # 전체 아키텍처 검사
110
+ bunx mandu guard arch
111
+
112
+ # 특정 프리셋으로 검사
113
+ bunx mandu guard arch --preset fsd
114
+
115
+ # CI 모드 (위반 시 exit 1)
116
+ bunx mandu guard arch --ci
117
+
118
+ # Watch 모드
119
+ bunx mandu guard arch --watch
120
+
121
+ # 단일 파일 검사
122
+ bunx mandu guard check-file src/client/features/auth.ts
123
+ ```
124
+
125
+ ## Configuration
126
+
127
+ ```typescript
128
+ // mandu.config.ts
129
+ export default {
130
+ guard: {
131
+ preset: "mandu",
132
+ rules: {
133
+ LAYER_VIOLATION: "error", // "error" | "warning" | "off"
134
+ FORBIDDEN_IMPORT: "error",
135
+ WRONG_SLOT_LOCATION: "warning",
136
+ CONTRACT_MISSING: "off",
137
+ GENERATED_DIRECT_EDIT: "error",
138
+ SLOT_NAMING: "warning",
139
+ }
140
+ }
141
+ };
142
+ ```
143
+
144
+ ## MCP Tools
145
+
146
+ | Tool | Purpose |
147
+ |------|---------|
148
+ | `mandu_guard` | Run architecture check |
149
+ | `mandu_guard_heal` | Auto-fix violations |
150
+ | `mandu_negotiate` | Analyze with preset awareness |
@@ -0,0 +1,134 @@
1
+ ---
2
+ name: mandu-hydration
3
+ description: |
4
+ Island import 규칙. 반드시 @mandujs/core/client에서 import.
5
+ "use client", .island.tsx, useState, hydration 작업 시 자동 호출.
6
+ ---
7
+
8
+ # Mandu Island Hydration
9
+
10
+ Island Hydration은 페이지의 일부분만 클라이언트에서 인터랙티브하게 만드는 기술입니다.
11
+
12
+ ## Import Rule (CRITICAL)
13
+
14
+ Client islands MUST import from `@mandujs/core/client`, NOT `@mandujs/core`.
15
+ The main module includes server-side dependencies that break client bundles.
16
+
17
+ ```typescript
18
+ // CORRECT
19
+ import { island } from "@mandujs/core/client";
20
+ import { useServerData, useHydrated, useIslandEvent } from "@mandujs/core/client";
21
+
22
+ // WRONG - will cause build errors or bloated bundles
23
+ import { island } from "@mandujs/core";
24
+ ```
25
+
26
+ ## Island File Conventions
27
+
28
+ | File | Purpose |
29
+ |------|---------|
30
+ | `*.island.tsx` | Island component (auto-detected for hydration) |
31
+ | `*.client.tsx` | Client-only logic file |
32
+ | `*.slot.ts` / `*.slot.tsx` | Server-side data loader |
33
+
34
+ All island files MUST have `"use client"` directive at the very top.
35
+
36
+ ## island() API
37
+
38
+ ### Declarative Style (simple)
39
+
40
+ ```tsx
41
+ // app/counter.island.tsx
42
+ "use client";
43
+
44
+ import { island } from "@mandujs/core/client";
45
+ import { useState } from "react";
46
+
47
+ function Counter() {
48
+ const [count, setCount] = useState(0);
49
+ return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
50
+ }
51
+
52
+ export default island("visible", Counter);
53
+ ```
54
+
55
+ ### Client Island with Setup (advanced)
56
+
57
+ ```tsx
58
+ // app/chat.island.tsx
59
+ "use client";
60
+
61
+ import { island } from "@mandujs/core/client";
62
+ import { useState } from "react";
63
+
64
+ export default island<ServerData>({
65
+ setup(data) {
66
+ const [messages, setMessages] = useState(data.initialMessages);
67
+ return { messages, setMessages };
68
+ },
69
+ render({ messages, setMessages }) {
70
+ return <div>{messages.map(m => <p key={m.id}>{m.text}</p>)}</div>;
71
+ }
72
+ });
73
+ ```
74
+
75
+ ## Hydration Priorities
76
+
77
+ | Priority | When loaded | Use case |
78
+ |----------|------------|----------|
79
+ | `"immediate"` | Page load | Critical interactions (nav, auth) |
80
+ | `"visible"` | In viewport | Default - most components |
81
+ | `"idle"` | Browser idle | Below-fold content |
82
+ | `"interaction"` | User interacts | Heavy widgets (editor, map) |
83
+
84
+ ```tsx
85
+ island("immediate", NavigationIsland); // Load right away
86
+ island("visible", CommentSection); // Load when scrolled into view
87
+ island("idle", AnalyticsDashboard); // Load when browser is idle
88
+ island("interaction", RichTextEditor); // Load on first click/focus
89
+ ```
90
+
91
+ ## Client Hooks
92
+
93
+ ```typescript
94
+ import { useServerData, useHydrated, useIslandEvent } from "@mandujs/core/client";
95
+
96
+ // Access data from server slot
97
+ const data = useServerData<UserData>("user", defaultValue);
98
+
99
+ // Check if component has hydrated (SSR-safe code branching)
100
+ const isHydrated = useHydrated();
101
+
102
+ // Cross-island communication
103
+ const { emit, on } = useIslandEvent();
104
+ emit("cart:updated", { items: newItems });
105
+ on("cart:updated", (data) => setCartItems(data.items));
106
+ ```
107
+
108
+ ## Server Data Flow
109
+
110
+ ```typescript
111
+ // spec/slots/user-profile.slot.ts (server)
112
+ import { Mandu } from "@mandujs/core";
113
+ export default Mandu.filling()
114
+ .get(async (ctx) => {
115
+ const user = await db.getUser(ctx.params.id);
116
+ return ctx.ok({ user }); // Data available to Islands
117
+ });
118
+
119
+ // app/user-profile.island.tsx (client)
120
+ "use client";
121
+ import { useServerData } from "@mandujs/core/client";
122
+ export default function UserProfile() {
123
+ const { user } = useServerData("user-profile");
124
+ return <div>{user.name}</div>;
125
+ }
126
+ ```
127
+
128
+ ## Common Mistakes
129
+
130
+ - Importing from `@mandujs/core` instead of `@mandujs/core/client` in Islands
131
+ - Forgetting `"use client"` directive in island files
132
+ - Using `useState`/`useEffect` in server components (non-island files)
133
+ - Setting all Islands to `"immediate"` priority (defeats partial hydration)
134
+ - Putting heavy server imports in `.island.tsx` files (increases bundle size)