@thorprovider/create-storefront 0.1.1

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.
Files changed (75) hide show
  1. package/README.md +119 -0
  2. package/bin/install.js +116 -0
  3. package/commands/sf-add-view.md +21 -0
  4. package/commands/sf-init.md +16 -0
  5. package/commands/sf-theme.md +15 -0
  6. package/commands/sf-view.md +20 -0
  7. package/package.json +40 -0
  8. package/recipes/archetype.schema.json +39 -0
  9. package/recipes/archetypes.json +148 -0
  10. package/recipes/recipe.schema.json +59 -0
  11. package/recipes/recipes.json +90 -0
  12. package/recipes/sections.json +46 -0
  13. package/recipes/validate.mjs +190 -0
  14. package/skills/building-storefronts/SKILL.md +178 -0
  15. package/skills/building-storefronts/references/frontend-integration.md +229 -0
  16. package/skills/json-render-core/SKILL.md +291 -0
  17. package/skills/json-render-next/SKILL.md +194 -0
  18. package/skills/json-render-react/SKILL.md +298 -0
  19. package/skills/json-render-remotion/SKILL.md +111 -0
  20. package/skills/json-render-shadcn/SKILL.md +159 -0
  21. package/skills/json-render-solid/SKILL.md +204 -0
  22. package/skills/nextjs-shadcn/SKILL.md +303 -0
  23. package/skills/nextjs-shadcn/references/architecture.md +499 -0
  24. package/skills/nextjs-shadcn/references/project-setup.md +127 -0
  25. package/skills/nextjs-shadcn/references/shadcn-platform.md +258 -0
  26. package/skills/nextjs-shadcn/references/sidebar.md +274 -0
  27. package/skills/nextjs-shadcn/references/styling.md +555 -0
  28. package/skills/sf-scaffold/SKILL.md +118 -0
  29. package/skills/sf-theme-gen/SKILL.md +44 -0
  30. package/skills/sf-view-gen/SKILL.md +94 -0
  31. package/skills/shadcn-component-discovery/SKILL.md +273 -0
  32. package/skills/shadcn-component-discovery/references/registries.md +226 -0
  33. package/skills/shadcn-theming/SKILL.md +104 -0
  34. package/skills/shadcn-theming/references/templates/theme-setup.md +109 -0
  35. package/skills/shadcn-theming/references/theming-guide.md +90 -0
  36. package/skills/storefront-best-practices/SKILL.md +421 -0
  37. package/skills/storefront-best-practices/reference/components/breadcrumbs.md +123 -0
  38. package/skills/storefront-best-practices/reference/components/cart-popup.md +189 -0
  39. package/skills/storefront-best-practices/reference/components/country-selector.md +298 -0
  40. package/skills/storefront-best-practices/reference/components/footer.md +112 -0
  41. package/skills/storefront-best-practices/reference/components/hero.md +241 -0
  42. package/skills/storefront-best-practices/reference/components/megamenu.md +239 -0
  43. package/skills/storefront-best-practices/reference/components/navbar.md +397 -0
  44. package/skills/storefront-best-practices/reference/components/popups.md +221 -0
  45. package/skills/storefront-best-practices/reference/components/product-card.md +125 -0
  46. package/skills/storefront-best-practices/reference/components/product-reviews.md +217 -0
  47. package/skills/storefront-best-practices/reference/components/product-slider.md +174 -0
  48. package/skills/storefront-best-practices/reference/components/search.md +101 -0
  49. package/skills/storefront-best-practices/reference/connecting-to-backend.md +391 -0
  50. package/skills/storefront-best-practices/reference/design.md +388 -0
  51. package/skills/storefront-best-practices/reference/features/promotions.md +307 -0
  52. package/skills/storefront-best-practices/reference/features/wishlist.md +230 -0
  53. package/skills/storefront-best-practices/reference/layouts/account.md +380 -0
  54. package/skills/storefront-best-practices/reference/layouts/cart.md +316 -0
  55. package/skills/storefront-best-practices/reference/layouts/checkout.md +486 -0
  56. package/skills/storefront-best-practices/reference/layouts/home-page.md +264 -0
  57. package/skills/storefront-best-practices/reference/layouts/order-confirmation.md +231 -0
  58. package/skills/storefront-best-practices/reference/layouts/product-details.md +527 -0
  59. package/skills/storefront-best-practices/reference/layouts/product-listing.md +520 -0
  60. package/skills/storefront-best-practices/reference/layouts/static-pages.md +356 -0
  61. package/skills/storefront-best-practices/reference/medusa.md +307 -0
  62. package/skills/storefront-best-practices/reference/mobile-responsiveness.md +183 -0
  63. package/skills/storefront-best-practices/reference/seo.md +195 -0
  64. package/templates/app/app/[[...slug]]/page.tsx +17 -0
  65. package/templates/app/app/[[...slug]]/renderer.tsx +10 -0
  66. package/templates/app/app/globals.css +101 -0
  67. package/templates/app/app/layout.tsx +35 -0
  68. package/templates/app/lib/__STOREFRONT__/catalog.ts +132 -0
  69. package/templates/app/lib/__STOREFRONT__/handlers.ts +33 -0
  70. package/templates/app/lib/__STOREFRONT__/registry.tsx +134 -0
  71. package/templates/app/lib/__STOREFRONT__/runtime.ts +25 -0
  72. package/templates/app/lib/__STOREFRONT__/spec/home.ts +62 -0
  73. package/templates/app/lib/__STOREFRONT__/spec/index.ts +59 -0
  74. package/templates/app/lib/__STOREFRONT__/spec/types.ts +14 -0
  75. package/templates/app/lib/__STOREFRONT__/state.ts +35 -0
@@ -0,0 +1,159 @@
1
+ ---
2
+ name: shadcn
3
+ description: Pre-built shadcn/ui components for json-render. Use when working with @json-render/shadcn, adding standard UI components to a catalog, or building web UIs with Radix UI + Tailwind CSS components.
4
+ ---
5
+
6
+ # @json-render/shadcn
7
+
8
+ Pre-built shadcn/ui component definitions and implementations for json-render. Provides 36 components built on Radix UI + Tailwind CSS.
9
+
10
+ ## Two Entry Points
11
+
12
+ | Entry Point | Exports | Use For |
13
+ |-------------|---------|---------|
14
+ | `@json-render/shadcn/catalog` | `shadcnComponentDefinitions` | Catalog schemas (no React dependency, safe for server) |
15
+ | `@json-render/shadcn` | `shadcnComponents` | React implementations |
16
+
17
+ ## Usage Pattern
18
+
19
+ Pick the components you need from the standard definitions. Do not spread all definitions -- explicitly select what your app uses:
20
+
21
+ ```typescript
22
+ import { defineCatalog } from "@json-render/core";
23
+ import { schema } from "@json-render/react/schema";
24
+ import { shadcnComponentDefinitions } from "@json-render/shadcn/catalog";
25
+ import { defineRegistry } from "@json-render/react";
26
+ import { shadcnComponents } from "@json-render/shadcn";
27
+
28
+ // Catalog: pick definitions
29
+ const catalog = defineCatalog(schema, {
30
+ components: {
31
+ Card: shadcnComponentDefinitions.Card,
32
+ Stack: shadcnComponentDefinitions.Stack,
33
+ Heading: shadcnComponentDefinitions.Heading,
34
+ Button: shadcnComponentDefinitions.Button,
35
+ Input: shadcnComponentDefinitions.Input,
36
+ },
37
+ actions: {},
38
+ });
39
+
40
+ // Registry: pick matching implementations
41
+ const { registry } = defineRegistry(catalog, {
42
+ components: {
43
+ Card: shadcnComponents.Card,
44
+ Stack: shadcnComponents.Stack,
45
+ Heading: shadcnComponents.Heading,
46
+ Button: shadcnComponents.Button,
47
+ Input: shadcnComponents.Input,
48
+ },
49
+ });
50
+ ```
51
+
52
+ > State actions (`setState`, `pushState`, `removeState`) are built into the React schema and handled by `ActionProvider` automatically. No need to declare them.
53
+
54
+ ## Extending with Custom Components
55
+
56
+ Add custom components alongside standard ones:
57
+
58
+ ```typescript
59
+ const catalog = defineCatalog(schema, {
60
+ components: {
61
+ // Standard
62
+ Card: shadcnComponentDefinitions.Card,
63
+ Stack: shadcnComponentDefinitions.Stack,
64
+
65
+ // Custom
66
+ Metric: {
67
+ props: z.object({
68
+ label: z.string(),
69
+ value: z.string(),
70
+ trend: z.enum(["up", "down", "neutral"]).nullable(),
71
+ }),
72
+ description: "KPI metric display",
73
+ },
74
+ },
75
+ actions: {},
76
+ });
77
+
78
+ const { registry } = defineRegistry(catalog, {
79
+ components: {
80
+ Card: shadcnComponents.Card,
81
+ Stack: shadcnComponents.Stack,
82
+ Metric: ({ props }) => <div>{props.label}: {props.value}</div>,
83
+ },
84
+ });
85
+ ```
86
+
87
+ ## Available Components
88
+
89
+ ### Layout
90
+ - **Card** - Container with optional title, description, maxWidth, centered
91
+ - **Stack** - Flex container with direction, gap, align, justify
92
+ - **Grid** - Grid layout with columns (number) and gap
93
+ - **Separator** - Visual divider with orientation
94
+
95
+ ### Navigation
96
+ - **Tabs** - Tabbed navigation with tabs array, defaultValue, value
97
+ - **Accordion** - Collapsible sections with items array and type (single/multiple)
98
+ - **Collapsible** - Single collapsible section with title
99
+ - **Pagination** - Page navigation with totalPages and page
100
+
101
+ ### Overlay
102
+ - **Dialog** - Modal dialog with title, description, openPath
103
+ - **Drawer** - Bottom drawer with title, description, openPath
104
+ - **Tooltip** - Hover tooltip with content and text
105
+ - **Popover** - Click-triggered popover with trigger and content
106
+ - **DropdownMenu** - Dropdown with label and items array
107
+
108
+ ### Content
109
+ - **Heading** - Heading text with level (h1-h4)
110
+ - **Text** - Paragraph with variant (body, caption, muted, lead, code)
111
+ - **Image** - Image with alt, width, height
112
+ - **Avatar** - User avatar with src, name, size
113
+ - **Badge** - Status badge with text and variant (default, secondary, destructive, outline)
114
+ - **Alert** - Alert banner with title, message, type (success, warning, info, error)
115
+ - **Carousel** - Scrollable carousel with items array
116
+ - **Table** - Data table with columns (string[]) and rows (string[][])
117
+
118
+ ### Feedback
119
+ - **Progress** - Progress bar with value, max, label
120
+ - **Skeleton** - Loading placeholder with width, height, rounded
121
+ - **Spinner** - Loading spinner with size and label
122
+
123
+ ### Input
124
+ - **Button** - Button with label, variant (primary, secondary, danger), disabled
125
+ - **Link** - Anchor link with label and href
126
+ - **Input** - Text input with label, name, type, placeholder, value, checks
127
+ - **Textarea** - Multi-line input with label, name, placeholder, rows, value, checks
128
+ - **Select** - Dropdown select with label, name, options (string[]), value, checks
129
+ - **Checkbox** - Checkbox with label, name, checked, checks, validateOn
130
+ - **Radio** - Radio group with label, name, options (string[]), value, checks, validateOn
131
+ - **Switch** - Toggle switch with label, name, checked, checks, validateOn
132
+ - **Slider** - Range slider with label, min, max, step, value
133
+ - **Toggle** - Toggle button with label, pressed, variant
134
+ - **ToggleGroup** - Group of toggles with items, type, value
135
+ - **ButtonGroup** - Button group with buttons array and selected
136
+
137
+ ## Built-in Actions (from `@json-render/react`)
138
+
139
+ These are built into the React schema and handled by `ActionProvider` automatically. They appear in prompts without needing to be declared in the catalog.
140
+
141
+ - **setState** - Set a value at a state path (`{ statePath, value }`)
142
+ - **pushState** - Push a value onto an array (`{ statePath, value, clearStatePath? }`)
143
+ - **removeState** - Remove an array item by index (`{ statePath, index }`)
144
+ - **validateForm** - Validate all fields, write `{ valid, errors }` to state (`{ statePath? }`)
145
+
146
+ ## Validation Timing (`validateOn`)
147
+
148
+ All form components support `validateOn` to control when validation runs:
149
+ - `"change"` — validate on every input change (default for Select, Checkbox, Radio, Switch)
150
+ - `"blur"` — validate when field loses focus (default for Input, Textarea)
151
+ - `"submit"` — validate only on form submission
152
+
153
+ ## Important Notes
154
+
155
+ - The `/catalog` entry point has no React dependency -- use it for server-side prompt generation
156
+ - Components use Tailwind CSS classes -- your app must have Tailwind configured
157
+ - Component implementations use bundled shadcn/ui primitives (not your app's `components/ui/`)
158
+ - All form inputs support `checks` for validation (type + message pairs) and `validateOn` for timing
159
+ - Events: inputs emit `change`/`submit`/`focus`/`blur`; buttons emit `press`; selects emit `change`/`select`
@@ -0,0 +1,204 @@
1
+ ---
2
+ name: solid
3
+ description: SolidJS renderer for json-render. Use when building @json-render/solid catalogs/registries, wiring Renderer providers, implementing bindings/actions, or troubleshooting Solid-specific reactivity patterns.
4
+ ---
5
+
6
+ # @json-render/solid
7
+
8
+ `@json-render/solid` renders json-render specs into Solid component trees with fine-grained reactivity.
9
+
10
+ ## Quick Start
11
+
12
+ ```tsx
13
+ import { Renderer, JSONUIProvider } from "@json-render/solid";
14
+ import type { Spec } from "@json-render/solid";
15
+ import { registry } from "./registry";
16
+
17
+ export function App(props: { spec: Spec | null }) {
18
+ return (
19
+ <JSONUIProvider registry={registry} initialState={{}}>
20
+ <Renderer spec={props.spec} registry={registry} />
21
+ </JSONUIProvider>
22
+ );
23
+ }
24
+ ```
25
+
26
+ ## Create a Catalog
27
+
28
+ ```typescript
29
+ import { defineCatalog } from "@json-render/core";
30
+ import { schema } from "@json-render/solid/schema";
31
+ import { z } from "zod";
32
+
33
+ export const catalog = defineCatalog(schema, {
34
+ components: {
35
+ Button: {
36
+ props: z.object({
37
+ label: z.string(),
38
+ variant: z.enum(["primary", "secondary"]).nullable(),
39
+ }),
40
+ description: "Clickable button",
41
+ },
42
+ Card: {
43
+ props: z.object({ title: z.string() }),
44
+ description: "Card container",
45
+ },
46
+ },
47
+ actions: {
48
+ submit: { description: "Submit data" },
49
+ },
50
+ });
51
+ ```
52
+
53
+ ## Define Components
54
+
55
+ Components receive `ComponentRenderProps` from the renderer:
56
+
57
+ ```ts
58
+ interface ComponentRenderProps<P = Record<string, unknown>> {
59
+ element: UIElement<string, P>;
60
+ children?: JSX.Element;
61
+ emit: (event: string) => void;
62
+ on: (event: string) => EventHandle;
63
+ bindings?: Record<string, string>;
64
+ loading?: boolean;
65
+ }
66
+ ```
67
+
68
+ Example:
69
+
70
+ ```tsx
71
+ import type { BaseComponentProps } from "@json-render/solid";
72
+
73
+ export function Button(props: BaseComponentProps<{ label: string }>) {
74
+ return (
75
+ <button onClick={() => props.emit("press")}>{props.props.label}</button>
76
+ );
77
+ }
78
+ ```
79
+
80
+ ## Create a Registry
81
+
82
+ ```typescript
83
+ import { defineRegistry } from "@json-render/solid";
84
+ import { catalog } from "./catalog";
85
+ import { Card } from "./Card";
86
+ import { Button } from "./Button";
87
+
88
+ const { registry, handlers, executeAction } = defineRegistry(catalog, {
89
+ components: {
90
+ Card,
91
+ Button,
92
+ },
93
+ actions: {
94
+ submit: async (params, setState, state) => {
95
+ // custom action logic
96
+ },
97
+ },
98
+ });
99
+ ```
100
+
101
+ ## Spec Structure
102
+
103
+ ```json
104
+ {
105
+ "root": "card1",
106
+ "elements": {
107
+ "card1": {
108
+ "type": "Card",
109
+ "props": { "title": "Hello" },
110
+ "children": ["btn1"]
111
+ },
112
+ "btn1": {
113
+ "type": "Button",
114
+ "props": { "label": "Click me" },
115
+ "on": {
116
+ "press": { "action": "submit" }
117
+ }
118
+ }
119
+ }
120
+ }
121
+ ```
122
+
123
+ ## Providers
124
+
125
+ - `StateProvider`: state model read/write and controlled mode via `store`
126
+ - `VisibilityProvider`: evaluates `visible` conditions
127
+ - `ValidationProvider`: field validation + `validateForm` integration
128
+ - `ActionProvider`: runs built-in and custom actions
129
+ - `JSONUIProvider`: combined provider wrapper
130
+
131
+ ## Hooks
132
+
133
+ - `useStateStore`, `useStateValue`, `useStateBinding`
134
+ - `useVisibility`, `useIsVisible`
135
+ - `useActions`, `useAction`
136
+ - `useValidation`, `useOptionalValidation`, `useFieldValidation`
137
+ - `useBoundProp`
138
+ - `useUIStream`, `useChatUI`
139
+
140
+ ## Built-in Actions
141
+
142
+ Handled automatically by `ActionProvider`:
143
+
144
+ - `setState`
145
+ - `pushState`
146
+ - `removeState`
147
+ - `validateForm`
148
+
149
+ ## Dynamic Props and Bindings
150
+
151
+ Nested lists can set `repeat.statePath` to `{ "$item": "field" }` inside an enclosing repeat.
152
+
153
+ Supported expression forms include:
154
+
155
+ - `{"$state": "/path"}`
156
+ - `{"$bindState": "/path"}`
157
+ - `{"$bindItem": "field"}`
158
+ - `{"$template": "Hi ${/user/name}"}`
159
+ - `{"$computed": "fn", "args": {...}}`
160
+ - `{"$cond": <condition>, "$then": <value>, "$else": <value>}`
161
+
162
+ Use `useBoundProp` in components for writable bound values:
163
+
164
+ ```tsx
165
+ import { useBoundProp } from "@json-render/solid";
166
+
167
+ function Input(props: BaseComponentProps<{ value?: string }>) {
168
+ const [value, setValue] = useBoundProp(
169
+ props.props.value,
170
+ props.bindings?.value,
171
+ );
172
+ return (
173
+ <input
174
+ value={String(value() ?? "")}
175
+ onInput={(e) => setValue(e.currentTarget.value)}
176
+ />
177
+ );
178
+ }
179
+ ```
180
+
181
+ `useStateValue`, `useStateBinding`, and the `state` / `errors` / `isValid` fields from `useFieldValidation` are reactive accessors in Solid. Call them as functions inside JSX, `createMemo`, or `createEffect`.
182
+
183
+ ## Solid Reactivity Rules
184
+
185
+ - Do not destructure component props in function signatures when values need to stay reactive.
186
+ - Keep changing reads inside JSX expressions, `createMemo`, or `createEffect`.
187
+ - Context values are exposed through getter-based objects so consumers always observe live signals.
188
+
189
+ ## Streaming UI
190
+
191
+ ```tsx
192
+ import { useUIStream, Renderer } from "@json-render/solid";
193
+
194
+ const stream = useUIStream({ api: "/api/generate-ui" });
195
+ await stream.send("Create a support dashboard");
196
+
197
+ <Renderer
198
+ spec={stream.spec}
199
+ registry={registry}
200
+ loading={stream.isStreaming}
201
+ />;
202
+ ```
203
+
204
+ Use `useChatUI` for chat + UI generation flows.
@@ -0,0 +1,303 @@
1
+ ---
2
+ name: nextjs-shadcn
3
+ argument-hint: "[component or page]"
4
+ description: Creates Next.js frontends with shadcn/ui. Use when building React UIs, components, pages, or applications with shadcn, Tailwind, or modern frontend patterns. Also use when the user asks to create a new Next.js project, add UI components, style pages, or build any web interface — even if they don't mention shadcn explicitly.
5
+ ---
6
+
7
+ # Next.js + shadcn/ui
8
+
9
+ Build distinctive, production-grade interfaces that avoid generic "AI slop" aesthetics.
10
+
11
+ ## Core Principles
12
+
13
+ 1. **Minimize noise** - Icons communicate; excessive labels don't
14
+ 2. **No generic AI-UI** - Avoid purple gradients, excessive shadows, predictable layouts
15
+ 3. **Context over decoration** - Every element serves a purpose
16
+ 4. **Theme consistency** - Use CSS variables from `globals.css`, never hardcode colors
17
+
18
+ ## Quick Start
19
+
20
+ ```bash
21
+ bunx --bun shadcn@latest init --template next --base base
22
+ ```
23
+
24
+ `--base` selects the primitive library: `base` (Base UI, the default since July
25
+ 2026), `radix` (projects already on Radix — still fully supported, not
26
+ deprecated), or `aria` (React Aria). **The same component has different props per
27
+ base** — Base UI composes with `render={<Link href="/" />}` where Radix uses
28
+ `asChild` — and the docs are base-scoped (`/docs/components/base/sidebar` vs
29
+ `/docs/components/radix/sidebar`).
30
+
31
+ For a custom design system, generate a preset code in `shadcn/create` and apply it:
32
+
33
+ ```bash
34
+ bunx --bun shadcn@latest init --preset <CODE> --template next
35
+ ```
36
+
37
+ ### Before touching an existing project
38
+
39
+ ```bash
40
+ bunx --bun shadcn@latest info --json # base, framework, aliases, installed components
41
+ bunx --bun shadcn@latest docs <component> # API reference resolved to THIS project's base
42
+ ```
43
+
44
+ Run these instead of writing component code from memory. See
45
+ [references/shadcn-platform.md](references/shadcn-platform.md) for the full CLI
46
+ surface, typeset, and the shimmer/scroll-fade utilities.
47
+
48
+ ## Component Rules
49
+
50
+ ### Page Structure
51
+
52
+ ```tsx
53
+ // page.tsx - content only, no layout chrome
54
+ export default function Page() {
55
+ return (
56
+ <>
57
+ <HeroSection />
58
+ <Features />
59
+ <Testimonials />
60
+ </>
61
+ );
62
+ }
63
+
64
+ // layout.tsx - shared UI (header, footer, sidebar)
65
+ export default function Layout({ children }: { children: React.ReactNode }) {
66
+ return (
67
+ <>
68
+ <Header />
69
+ <main>{children}</main>
70
+ <Footer />
71
+ </>
72
+ );
73
+ }
74
+ ```
75
+
76
+ ### Client Boundaries
77
+
78
+ - `"use client"` only at leaf components (smallest boundary)
79
+ - Props must be serializable (data or Server Actions, no functions/classes)
80
+ - Pass server content via `children`
81
+
82
+ ### Import Aliases
83
+
84
+ Never use relative paths (`../../lib/utils`). Default to the `@/` alias
85
+ (`@/lib/utils`) in new projects. In an existing project, read `components.json`
86
+ and follow the alias style already configured — shadcn also supports Node
87
+ package imports (`#components/ui/button`). Never mix both styles.
88
+
89
+ ### Style Merging
90
+
91
+ ```tsx
92
+ import { cn } from "@/lib/utils";
93
+
94
+ function Button({ className, ...props }) {
95
+ return <button className={cn("px-4 py-2 rounded", className)} {...props} />;
96
+ }
97
+ ```
98
+
99
+ ## File Organization
100
+
101
+ ```
102
+ app/
103
+ ├── (protected)/ # Auth required routes
104
+ │ ├── dashboard/
105
+ │ ├── settings/
106
+ │ ├── components/ # Route-specific components
107
+ │ └── lib/ # Route-specific utils/types
108
+ ├── (public)/ # Public routes
109
+ │ ├── login/
110
+ │ └── register/
111
+ ├── actions/ # Server Actions (global)
112
+ ├── api/ # API routes
113
+ ├── layout.tsx # Root layout
114
+ └── globals.css # Theme tokens
115
+ components/ # Shared components
116
+ ├── ui/ # shadcn primitives
117
+ └── shared/ # Business components
118
+ hooks/ # Custom React hooks
119
+ lib/ # Shared utils
120
+ data/ # Database queries
121
+ ai/ # AI logic (tools, agents, prompts)
122
+ ```
123
+
124
+ ## Next.js 16 Features
125
+
126
+ ### Async Params
127
+
128
+ ```tsx
129
+ export default async function Page({
130
+ params,
131
+ searchParams,
132
+ }: {
133
+ params: Promise<{ id: string }>;
134
+ searchParams: Promise<{ q?: string }>;
135
+ }) {
136
+ const { id } = await params;
137
+ const { q } = await searchParams;
138
+ }
139
+ ```
140
+
141
+ ### Data Fetching vs Server Actions
142
+
143
+ **CRITICAL RULE:**
144
+ - **Server Actions** = ONLY for mutations (create, update, delete)
145
+ - **Data fetching** = In Server Components or `'use cache'` functions
146
+
147
+ `"use cache"` (and `cacheTag`/`cacheLife`/`updateTag`) requires the Cache Components opt-in flag — Next.js 16 does not enable it by default:
148
+
149
+ ```ts
150
+ // next.config.ts
151
+ const nextConfig = { cacheComponents: true }
152
+ ```
153
+
154
+ ```tsx
155
+ // ❌ WRONG: Server Action for data fetching
156
+ "use server"
157
+ export async function getUsers() {
158
+ return await db.users.findMany()
159
+ }
160
+
161
+ // ✅ CORRECT: Data function with caching
162
+ // data/users.ts
163
+ export async function getUsers() {
164
+ "use cache"
165
+ cacheTag("users")
166
+ cacheLife("hours")
167
+ return await db.users.findMany()
168
+ }
169
+
170
+ // ✅ CORRECT: Read cookies in Server Component directly
171
+ export default async function Page() {
172
+ const theme = (await cookies()).get("theme")?.value ?? "light"
173
+ return <App theme={theme} />
174
+ }
175
+ ```
176
+
177
+ ### Caching
178
+
179
+ ```tsx
180
+ "use cache";
181
+
182
+ import { cacheTag, cacheLife } from "next/cache";
183
+
184
+ export async function getProducts() {
185
+ cacheTag("products");
186
+ cacheLife("hours");
187
+ return await db.products.findMany();
188
+ }
189
+ ```
190
+
191
+ ### Server Actions (Mutations Only)
192
+
193
+ ```tsx
194
+ "use server";
195
+
196
+ import { updateTag, revalidateTag } from "next/cache";
197
+ import { z } from "zod";
198
+
199
+ const schema = z.object({
200
+ title: z.string().min(1),
201
+ content: z.string(),
202
+ });
203
+
204
+ export async function createPost(formData: FormData) {
205
+ // Always validate input
206
+ const parsed = schema.parse({
207
+ title: formData.get("title"),
208
+ content: formData.get("content"),
209
+ });
210
+
211
+ await db.insert(posts).values(parsed);
212
+ updateTag("posts"); // Read-your-writes
213
+ // Or SWR-style revalidation: revalidateTag("posts", "max")
214
+ }
215
+ ```
216
+
217
+ ### Proxy API
218
+
219
+ Use `proxy.ts` for request interception (replaces middleware). Place at project root:
220
+
221
+ ```tsx
222
+ // proxy.ts (project root, same level as app/)
223
+ import { NextResponse } from "next/server"
224
+ import type { NextRequest } from "next/server"
225
+
226
+ export function proxy(request: NextRequest) {
227
+ // Auth checks, redirects, etc.
228
+ }
229
+
230
+ export const config = {
231
+ matcher: ['/dashboard/:path*'],
232
+ }
233
+ ```
234
+
235
+ ## Dev Tools (next-devtools-mcp)
236
+
237
+ Next.js 16+ ships an MCP endpoint at `/_next/mcp` that exposes the dev server's
238
+ internals to coding agents. When working in a Next.js 16 project, recommend the
239
+ user add `next-devtools-mcp` to `.mcp.json`:
240
+
241
+ ```json filename=".mcp.json"
242
+ {
243
+ "mcpServers": {
244
+ "next-devtools": {
245
+ "command": "npx",
246
+ "args": ["-y", "next-devtools-mcp@latest"]
247
+ }
248
+ }
249
+ }
250
+ ```
251
+
252
+ Tools it provides (when dev server is running):
253
+
254
+ - `get_errors` — live build/runtime/type errors (esp. helpful for hydration mismatches)
255
+ - `get_logs` — dev log file path (browser console + server output)
256
+ - `get_routes` — all entry-point routes grouped by router type
257
+ - `get_page_metadata` — route, components, rendering details for a specific page
258
+ - `get_project_metadata` — project structure + dev server URL
259
+ - `get_server_action_by_id` — locate Server Action source from its hashed ID
260
+ - `get_compilation_issues` / `compile_route` — bundler warnings for the project,
261
+ or compile one route on demand without requesting it (Turbopack only)
262
+
263
+ It also acts as a docs gateway: it points at the version-accurate docs shipped
264
+ inside `node_modules/next/dist/docs/`, which beat any remembered API shape.
265
+
266
+ Use these instead of asking the user to copy-paste error messages. Reference:
267
+ [nextjs.org/docs/app/guides/mcp](https://nextjs.org/docs/app/guides/mcp).
268
+
269
+ ## Rendered markdown and loading states
270
+
271
+ Don't hand-roll CSS for these — shadcn ships them:
272
+
273
+ - **Rendered markdown / LLM output** → typeset. One owned CSS file, three
274
+ variables (`--typeset-size`, `--typeset-leading`, `--typeset-flow`), one
275
+ preset per context. Streaming-stable: new blocks don't restyle earlier ones.
276
+ ```tsx
277
+ <div className="typeset typeset-chat">{markdown}</div>
278
+ ```
279
+ - **Indeterminate text state** ("Thinking…") → `className="shimmer"`. Use
280
+ `Skeleton` only for placeholders with a known shape; don't stack both.
281
+ - **Soft scroll container edges** → `className="scroll-fade overflow-y-auto"`.
282
+
283
+ Details and the full class tables: [references/shadcn-platform.md](references/shadcn-platform.md).
284
+
285
+ ## References
286
+
287
+ - **Architecture**: [references/architecture.md](references/architecture.md) - Components, routing, Suspense, data patterns, AI directory structure
288
+ - **Styling**: [references/styling.md](references/styling.md) - Themes, fonts, radius, animations, CSS variables
289
+ - **shadcn Platform**: [references/shadcn-platform.md](references/shadcn-platform.md) - Base UI vs Radix vs React Aria, CLI verbs, typeset, shimmer, scroll-fade, RTL, package imports
290
+ - **Sidebar**: [references/sidebar.md](references/sidebar.md) - shadcn sidebar with nested layouts, blocks, RTL
291
+ - **Project Setup**: [references/project-setup.md](references/project-setup.md) - bun commands, presets
292
+ - **Official shadcn skill**: `bunx --bun skills add shadcn/ui` - live project config + CLI/registry reference. Install alongside this skill; it covers CLI mechanics, this one covers conventions.
293
+ - **shadcn/ui**: [llms.txt](https://ui.shadcn.com/llms.txt) - fallback when the CLI isn't available; prefer `shadcn docs <component>`
294
+
295
+ ## Package Manager
296
+
297
+ **Always use bun** in new projects, never npm or npx:
298
+
299
+ - `bun install` (not npm install)
300
+ - `bun add` (not npm install package)
301
+ - `bunx --bun` (not npx)
302
+
303
+ In an existing repo, respect the project's `packageManager` field and lockfile instead of switching to bun.