agentbrief 0.1.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.
- package/LICENSE +21 -0
- package/README.md +141 -0
- package/briefs/code-reviewer/brief.yaml +8 -0
- package/briefs/code-reviewer/knowledge/review-standards.md +32 -0
- package/briefs/code-reviewer/personality.md +19 -0
- package/briefs/code-reviewer/skills/architecture-review/SKILL.md +76 -0
- package/briefs/code-reviewer/skills/review-process/SKILL.md +41 -0
- package/briefs/code-reviewer/skills/verification/SKILL.md +47 -0
- package/briefs/data-analyst/brief.yaml +8 -0
- package/briefs/data-analyst/knowledge/metrics-reference.md +43 -0
- package/briefs/data-analyst/personality.md +23 -0
- package/briefs/data-analyst/skills/metrics-framework/SKILL.md +90 -0
- package/briefs/data-analyst/skills/sql-query-builder/SKILL.md +115 -0
- package/briefs/devops-sre/brief.yaml +12 -0
- package/briefs/devops-sre/knowledge/runbook.md +69 -0
- package/briefs/devops-sre/personality.md +18 -0
- package/briefs/devops-sre/skills/ci-cd-github-actions/SKILL.md +114 -0
- package/briefs/devops-sre/skills/monitoring-observability/SKILL.md +394 -0
- package/briefs/devops-sre/skills/systematic-debugging/SKILL.md +46 -0
- package/briefs/devops-sre/skills/verification/SKILL.md +47 -0
- package/briefs/frontend-design/brief.yaml +8 -0
- package/briefs/frontend-design/knowledge/design-principles.md +43 -0
- package/briefs/frontend-design/personality.md +19 -0
- package/briefs/frontend-design/skills/design-review-checklist/SKILL.md +151 -0
- package/briefs/frontend-design/skills/web-design-guidelines/SKILL.md +39 -0
- package/briefs/fullstack-dev/brief.yaml +9 -0
- package/briefs/fullstack-dev/personality.md +18 -0
- package/briefs/growth-engineer/brief.yaml +8 -0
- package/briefs/growth-engineer/knowledge/growth-framework.md +83 -0
- package/briefs/growth-engineer/personality.md +19 -0
- package/briefs/growth-engineer/skills/analytics-setup/SKILL.md +109 -0
- package/briefs/growth-engineer/skills/brainstorming/SKILL.md +55 -0
- package/briefs/growth-engineer/skills/content-strategy/SKILL.md +93 -0
- package/briefs/growth-engineer/skills/seo-audit/SKILL.md +412 -0
- package/briefs/growth-engineer/skills/seo-audit/evals/evals.json +136 -0
- package/briefs/growth-engineer/skills/seo-audit/references/ai-writing-detection.md +200 -0
- package/briefs/nextjs-fullstack/brief.yaml +12 -0
- package/briefs/nextjs-fullstack/knowledge/conventions.md +57 -0
- package/briefs/nextjs-fullstack/personality.md +19 -0
- package/briefs/nextjs-fullstack/skills/next-best-practices/SKILL.md +153 -0
- package/briefs/nextjs-fullstack/skills/next-best-practices/async-patterns.md +87 -0
- package/briefs/nextjs-fullstack/skills/next-best-practices/bundling.md +180 -0
- package/briefs/nextjs-fullstack/skills/next-best-practices/data-patterns.md +297 -0
- package/briefs/nextjs-fullstack/skills/next-best-practices/debug-tricks.md +105 -0
- package/briefs/nextjs-fullstack/skills/next-best-practices/directives.md +73 -0
- package/briefs/nextjs-fullstack/skills/next-best-practices/error-handling.md +227 -0
- package/briefs/nextjs-fullstack/skills/next-best-practices/file-conventions.md +140 -0
- package/briefs/nextjs-fullstack/skills/next-best-practices/font.md +245 -0
- package/briefs/nextjs-fullstack/skills/next-best-practices/functions.md +108 -0
- package/briefs/nextjs-fullstack/skills/next-best-practices/hydration-error.md +91 -0
- package/briefs/nextjs-fullstack/skills/next-best-practices/image.md +173 -0
- package/briefs/nextjs-fullstack/skills/next-best-practices/metadata.md +301 -0
- package/briefs/nextjs-fullstack/skills/next-best-practices/parallel-routes.md +287 -0
- package/briefs/nextjs-fullstack/skills/next-best-practices/route-handlers.md +146 -0
- package/briefs/nextjs-fullstack/skills/next-best-practices/rsc-boundaries.md +159 -0
- package/briefs/nextjs-fullstack/skills/next-best-practices/runtime-selection.md +39 -0
- package/briefs/nextjs-fullstack/skills/next-best-practices/scripts.md +141 -0
- package/briefs/nextjs-fullstack/skills/next-best-practices/self-hosting.md +371 -0
- package/briefs/nextjs-fullstack/skills/next-best-practices/suspense-boundaries.md +67 -0
- package/briefs/nextjs-fullstack/skills/tdd/SKILL.md +53 -0
- package/briefs/product-manager/brief.yaml +8 -0
- package/briefs/product-manager/knowledge/pm-toolkit.md +51 -0
- package/briefs/product-manager/personality.md +19 -0
- package/briefs/product-manager/skills/brainstorming/SKILL.md +55 -0
- package/briefs/product-manager/skills/specification/SKILL.md +76 -0
- package/briefs/qa-engineer/brief.yaml +11 -0
- package/briefs/qa-engineer/knowledge/testing-patterns.md +54 -0
- package/briefs/qa-engineer/personality.md +24 -0
- package/briefs/qa-engineer/skills/qa-test-and-fix/SKILL.md +101 -0
- package/briefs/qa-engineer/skills/regression-testing/SKILL.md +95 -0
- package/briefs/security-auditor/brief.yaml +12 -0
- package/briefs/security-auditor/knowledge/code-patterns.md +49 -0
- package/briefs/security-auditor/knowledge/owasp-cheatsheet.md +75 -0
- package/briefs/security-auditor/personality.md +23 -0
- package/briefs/security-auditor/skills/security-review/SKILL.md +29 -0
- package/briefs/security-auditor/skills/systematic-debugging/SKILL.md +46 -0
- package/briefs/security-auditor/skills/verification/SKILL.md +47 -0
- package/briefs/startup-builder/brief.yaml +8 -0
- package/briefs/startup-builder/knowledge/startup-phases.md +64 -0
- package/briefs/startup-builder/personality.md +18 -0
- package/briefs/startup-builder/skills/ceo-review/SKILL.md +95 -0
- package/briefs/startup-builder/skills/launch-strategy/SKILL.md +353 -0
- package/briefs/startup-builder/skills/launch-strategy/evals/evals.json +91 -0
- package/briefs/startup-builder/skills/tdd/SKILL.md +53 -0
- package/briefs/startup-builder/skills/verification/SKILL.md +47 -0
- package/briefs/startup-kit/brief.yaml +9 -0
- package/briefs/startup-kit/personality.md +18 -0
- package/briefs/tech-writer/brief.yaml +8 -0
- package/briefs/tech-writer/knowledge/style-guide.md +54 -0
- package/briefs/tech-writer/personality.md +19 -0
- package/briefs/tech-writer/skills/api-documentation/SKILL.md +390 -0
- package/briefs/tech-writer/skills/plan-and-execute/SKILL.md +54 -0
- package/briefs/tech-writer/skills/release-notes/SKILL.md +77 -0
- package/briefs/typescript-strict/brief.yaml +8 -0
- package/briefs/typescript-strict/knowledge/type-patterns.md +117 -0
- package/briefs/typescript-strict/personality.md +23 -0
- package/briefs/typescript-strict/skills/typescript-advanced-types/SKILL.md +717 -0
- package/dist/brief.d.ts +13 -0
- package/dist/brief.d.ts.map +1 -0
- package/dist/brief.js +90 -0
- package/dist/brief.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +180 -0
- package/dist/cli.js.map +1 -0
- package/dist/compiler.d.ts +25 -0
- package/dist/compiler.d.ts.map +1 -0
- package/dist/compiler.js +253 -0
- package/dist/compiler.js.map +1 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +255 -0
- package/dist/index.js.map +1 -0
- package/dist/injector.d.ts +17 -0
- package/dist/injector.d.ts.map +1 -0
- package/dist/injector.js +76 -0
- package/dist/injector.js.map +1 -0
- package/dist/lock.d.ts +8 -0
- package/dist/lock.d.ts.map +1 -0
- package/dist/lock.js +50 -0
- package/dist/lock.js.map +1 -0
- package/dist/resolver.d.ts +24 -0
- package/dist/resolver.d.ts.map +1 -0
- package/dist/resolver.js +135 -0
- package/dist/resolver.js.map +1 -0
- package/dist/types.d.ts +61 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +15 -0
- package/dist/types.js.map +1 -0
- package/package.json +64 -0
- package/registry.yaml +91 -0
- package/templates/default/brief.yaml +7 -0
- package/templates/default/knowledge/.gitkeep +0 -0
- package/templates/default/personality.md +12 -0
- package/templates/security/brief.yaml +6 -0
- package/templates/security/knowledge/.gitkeep +0 -0
- package/templates/security/personality.md +20 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# AI Writing Detection
|
|
2
|
+
|
|
3
|
+
Words, phrases, and punctuation patterns commonly associated with AI-generated text. Avoid these to ensure writing sounds natural and human.
|
|
4
|
+
|
|
5
|
+
Sources: Grammarly (2025), Microsoft 365 Life Hacks (2025), GPTHuman (2025), Walter Writes (2025), Textero (2025), Plagiarism Today (2025), Rolling Stone (2025), MDPI Blog (2025)
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Contents
|
|
10
|
+
- Em Dashes: The Primary AI Tell
|
|
11
|
+
- Overused Verbs
|
|
12
|
+
- Overused Adjectives
|
|
13
|
+
- Overused Transitions and Connectors
|
|
14
|
+
- Phrases That Signal AI Writing (Opening Phrases, Transitional Phrases, Concluding Phrases, Structural Patterns)
|
|
15
|
+
- Filler Words and Empty Intensifiers
|
|
16
|
+
- Academic-Specific AI Tells
|
|
17
|
+
- How to Self-Check
|
|
18
|
+
|
|
19
|
+
## Em Dashes: The Primary AI Tell
|
|
20
|
+
|
|
21
|
+
**The em dash (—) has become one of the most reliable markers of AI-generated content.**
|
|
22
|
+
|
|
23
|
+
Em dashes are longer than hyphens (-) and are used for emphasis, interruptions, or parenthetical information. While they have legitimate uses in writing, AI models drastically overuse them.
|
|
24
|
+
|
|
25
|
+
### Why Em Dashes Signal AI Writing
|
|
26
|
+
- AI models were trained on edited books, academic papers, and style guides where em dashes appear frequently
|
|
27
|
+
- AI uses em dashes as a shortcut for sentence variety instead of commas, colons, or parentheses
|
|
28
|
+
- Most human writers rarely use em dashes because they don't exist as a standard keyboard key
|
|
29
|
+
- The overuse is so consistent that it has become the unofficial signature of ChatGPT writing
|
|
30
|
+
|
|
31
|
+
### What To Do Instead
|
|
32
|
+
| Instead of | Use |
|
|
33
|
+
|------------|-----|
|
|
34
|
+
| The results—which were surprising—showed... | The results, which were surprising, showed... |
|
|
35
|
+
| This approach—unlike traditional methods—allows... | This approach, unlike traditional methods, allows... |
|
|
36
|
+
| The study found—as expected—that... | The study found, as expected, that... |
|
|
37
|
+
| Communication skills—both written and verbal—are essential | Communication skills (both written and verbal) are essential |
|
|
38
|
+
|
|
39
|
+
### Guidelines
|
|
40
|
+
- Use commas for most parenthetical information
|
|
41
|
+
- Use colons to introduce explanations or lists
|
|
42
|
+
- Use parentheses for supplementary information
|
|
43
|
+
- Reserve em dashes for rare, deliberate emphasis only
|
|
44
|
+
- If you find yourself using more than one em dash per page, revise
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Overused Verbs
|
|
49
|
+
|
|
50
|
+
| Avoid | Use Instead |
|
|
51
|
+
|-------|-------------|
|
|
52
|
+
| delve (into) | explore, examine, investigate, look at |
|
|
53
|
+
| leverage | use, apply, draw on |
|
|
54
|
+
| optimise | improve, refine, enhance |
|
|
55
|
+
| utilise | use |
|
|
56
|
+
| facilitate | help, enable, support |
|
|
57
|
+
| foster | encourage, support, develop, nurture |
|
|
58
|
+
| bolster | strengthen, support, reinforce |
|
|
59
|
+
| underscore | emphasise, highlight, stress |
|
|
60
|
+
| unveil | reveal, show, introduce, present |
|
|
61
|
+
| navigate | manage, handle, work through |
|
|
62
|
+
| streamline | simplify, make more efficient |
|
|
63
|
+
| enhance | improve, strengthen |
|
|
64
|
+
| endeavour | try, attempt, effort |
|
|
65
|
+
| ascertain | find out, determine, establish |
|
|
66
|
+
| elucidate | explain, clarify, make clear |
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Overused Adjectives
|
|
71
|
+
|
|
72
|
+
| Avoid | Use Instead |
|
|
73
|
+
|-------|-------------|
|
|
74
|
+
| robust | strong, reliable, thorough, solid |
|
|
75
|
+
| comprehensive | complete, thorough, full, detailed |
|
|
76
|
+
| pivotal | key, critical, central, important |
|
|
77
|
+
| crucial | important, key, essential, critical |
|
|
78
|
+
| vital | important, essential, necessary |
|
|
79
|
+
| transformative | significant, important, major |
|
|
80
|
+
| cutting-edge | new, advanced, recent, modern |
|
|
81
|
+
| groundbreaking | new, original, significant |
|
|
82
|
+
| innovative | new, original, creative |
|
|
83
|
+
| seamless | smooth, easy, effortless |
|
|
84
|
+
| intricate | complex, detailed, complicated |
|
|
85
|
+
| nuanced | subtle, complex, detailed |
|
|
86
|
+
| multifaceted | complex, varied, diverse |
|
|
87
|
+
| holistic | complete, whole, comprehensive |
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Overused Transitions and Connectors
|
|
92
|
+
|
|
93
|
+
| Avoid | Use Instead |
|
|
94
|
+
|-------|-------------|
|
|
95
|
+
| furthermore | also, in addition, and |
|
|
96
|
+
| moreover | also, and, besides |
|
|
97
|
+
| notwithstanding | despite, even so, still |
|
|
98
|
+
| that being said | however, but, still |
|
|
99
|
+
| at its core | essentially, fundamentally, basically |
|
|
100
|
+
| to put it simply | in short, simply put |
|
|
101
|
+
| it is worth noting that | note that, importantly |
|
|
102
|
+
| in the realm of | in, within, regarding |
|
|
103
|
+
| in the landscape of | in, within |
|
|
104
|
+
| in today's [anything] | currently, now, today |
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Phrases That Signal AI Writing
|
|
109
|
+
|
|
110
|
+
### Opening Phrases to Avoid
|
|
111
|
+
- "In today's fast-paced world..."
|
|
112
|
+
- "In today's digital age..."
|
|
113
|
+
- "In an era of..."
|
|
114
|
+
- "In the ever-evolving landscape of..."
|
|
115
|
+
- "In the realm of..."
|
|
116
|
+
- "It's important to note that..."
|
|
117
|
+
- "Let's delve into..."
|
|
118
|
+
- "Imagine a world where..."
|
|
119
|
+
|
|
120
|
+
### Transitional Phrases to Avoid
|
|
121
|
+
- "That being said..."
|
|
122
|
+
- "With that in mind..."
|
|
123
|
+
- "It's worth mentioning that..."
|
|
124
|
+
- "At its core..."
|
|
125
|
+
- "To put it simply..."
|
|
126
|
+
- "In essence..."
|
|
127
|
+
- "This begs the question..."
|
|
128
|
+
|
|
129
|
+
### Concluding Phrases to Avoid
|
|
130
|
+
- "In conclusion..."
|
|
131
|
+
- "To sum up..."
|
|
132
|
+
- "By [doing X], you can [achieve Y]..."
|
|
133
|
+
- "In the final analysis..."
|
|
134
|
+
- "All things considered..."
|
|
135
|
+
- "At the end of the day..."
|
|
136
|
+
|
|
137
|
+
### Structural Patterns to Avoid
|
|
138
|
+
- "Whether you're a [X], [Y], or [Z]..." (listing three examples after "whether")
|
|
139
|
+
- "It's not just [X], it's also [Y]..."
|
|
140
|
+
- "Think of [X] as [elaborate metaphor]..."
|
|
141
|
+
- Starting sentences with "By" followed by a gerund: "By understanding X, you can Y..."
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Filler Words and Empty Intensifiers
|
|
146
|
+
|
|
147
|
+
These words often add nothing to meaning. Remove them or find specific alternatives:
|
|
148
|
+
|
|
149
|
+
- absolutely
|
|
150
|
+
- actually
|
|
151
|
+
- basically
|
|
152
|
+
- certainly
|
|
153
|
+
- clearly
|
|
154
|
+
- definitely
|
|
155
|
+
- essentially
|
|
156
|
+
- extremely
|
|
157
|
+
- fundamentally
|
|
158
|
+
- incredibly
|
|
159
|
+
- interestingly
|
|
160
|
+
- naturally
|
|
161
|
+
- obviously
|
|
162
|
+
- quite
|
|
163
|
+
- really
|
|
164
|
+
- significantly
|
|
165
|
+
- simply
|
|
166
|
+
- surely
|
|
167
|
+
- truly
|
|
168
|
+
- ultimately
|
|
169
|
+
- undoubtedly
|
|
170
|
+
- very
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Academic-Specific AI Tells
|
|
175
|
+
|
|
176
|
+
| Avoid | Use Instead |
|
|
177
|
+
|-------|-------------|
|
|
178
|
+
| shed light on | clarify, explain, reveal |
|
|
179
|
+
| pave the way for | enable, allow, make possible |
|
|
180
|
+
| a myriad of | many, numerous, various |
|
|
181
|
+
| a plethora of | many, numerous, several |
|
|
182
|
+
| paramount | very important, essential, critical |
|
|
183
|
+
| pertaining to | about, regarding, concerning |
|
|
184
|
+
| prior to | before |
|
|
185
|
+
| subsequent to | after |
|
|
186
|
+
| in light of | because of, given, considering |
|
|
187
|
+
| with respect to | about, regarding, for |
|
|
188
|
+
| in terms of | regarding, for, about |
|
|
189
|
+
| the fact that | that (or rewrite sentence) |
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## How to Self-Check
|
|
194
|
+
|
|
195
|
+
1. Read your text aloud. If phrases sound unnatural in speech, revise them
|
|
196
|
+
2. Ask: "Would I say this in a conversation with a colleague?"
|
|
197
|
+
3. Check for repetitive sentence structures
|
|
198
|
+
4. Look for clusters of the words listed above
|
|
199
|
+
5. Ensure varied sentence lengths (not all similar length)
|
|
200
|
+
6. Verify each intensifier adds genuine meaning
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
name: nextjs-fullstack
|
|
2
|
+
version: "1.0.0"
|
|
3
|
+
description: "Next.js 15 + App Router + React 19 + Tailwind full-stack specialist"
|
|
4
|
+
personality: personality.md
|
|
5
|
+
knowledge:
|
|
6
|
+
- knowledge/
|
|
7
|
+
skills:
|
|
8
|
+
- skills/
|
|
9
|
+
scale:
|
|
10
|
+
timeout: 120
|
|
11
|
+
engine: claude-code
|
|
12
|
+
model: claude-sonnet-4-6
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Next.js Full-Stack Conventions
|
|
2
|
+
|
|
3
|
+
## Architecture Principles
|
|
4
|
+
|
|
5
|
+
- **Server Components by default** -- only add `'use client'` when you need browser APIs, event handlers, or useState/useEffect
|
|
6
|
+
- **Server Actions for mutations** -- prefer over API routes for form submissions and data mutations
|
|
7
|
+
- **Route segments** -- use `layout.tsx`, `page.tsx`, `loading.tsx`, `error.tsx`, `not-found.tsx` correctly
|
|
8
|
+
- **Parallel routes and intercepting routes** when the UX requires them
|
|
9
|
+
- **Metadata API** for SEO -- use `generateMetadata` in layouts and pages
|
|
10
|
+
|
|
11
|
+
## Data Fetching Patterns
|
|
12
|
+
|
|
13
|
+
- Fetch data in Server Components -- no `useEffect` for initial data loads
|
|
14
|
+
- Use `fetch` with Next.js caching semantics (`cache`, `revalidate`, `tags`)
|
|
15
|
+
- Use React `cache()` to deduplicate requests within a render pass
|
|
16
|
+
- Server Actions with `revalidatePath` / `revalidateTag` for cache invalidation
|
|
17
|
+
- Colocate data fetching with the component that uses it
|
|
18
|
+
|
|
19
|
+
## Styling Rules
|
|
20
|
+
|
|
21
|
+
- **Tailwind CSS** for all styling -- no CSS modules or styled-components
|
|
22
|
+
- Use `class-variance-authority` (cva) for component variants
|
|
23
|
+
- Use `cn()` utility (clsx + tailwind-merge) for conditional classes
|
|
24
|
+
- Follow mobile-first responsive design
|
|
25
|
+
- Breakpoints: `sm` (640px), `md` (768px), `lg` (1024px), `xl` (1280px)
|
|
26
|
+
|
|
27
|
+
## Component Patterns
|
|
28
|
+
|
|
29
|
+
- Co-locate tests next to components: `component.tsx` + `component.test.tsx`
|
|
30
|
+
- Use `Suspense` boundaries for streaming
|
|
31
|
+
- Use `dynamic()` for heavy client components
|
|
32
|
+
- Optimize images with `next/image`
|
|
33
|
+
- Use `next/font` for font loading
|
|
34
|
+
- Keep client components small and leaf-level -- push `'use client'` as far down the tree as possible
|
|
35
|
+
|
|
36
|
+
## Project Structure
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
app/
|
|
40
|
+
layout.tsx # Root layout
|
|
41
|
+
page.tsx # Home page
|
|
42
|
+
(auth)/
|
|
43
|
+
login/page.tsx
|
|
44
|
+
register/page.tsx
|
|
45
|
+
dashboard/
|
|
46
|
+
layout.tsx
|
|
47
|
+
page.tsx
|
|
48
|
+
loading.tsx
|
|
49
|
+
error.tsx
|
|
50
|
+
components/
|
|
51
|
+
ui/ # shadcn/ui primitives
|
|
52
|
+
[feature]/ # Feature-specific components
|
|
53
|
+
lib/
|
|
54
|
+
actions/ # Server Actions
|
|
55
|
+
db/ # Database queries
|
|
56
|
+
utils.ts # Shared utilities (cn, etc.)
|
|
57
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
## Role
|
|
2
|
+
|
|
3
|
+
You are a Next.js 15 full-stack specialist. You build production applications using App Router, React 19, TypeScript, and Tailwind CSS. You follow the framework's conventions precisely and prefer server-first patterns.
|
|
4
|
+
|
|
5
|
+
## Tone
|
|
6
|
+
|
|
7
|
+
- Pragmatic and framework-aligned -- follow Next.js conventions, not custom abstractions
|
|
8
|
+
- Explain server vs client decisions when the boundary matters
|
|
9
|
+
- Prefer fewer dependencies and built-in framework features
|
|
10
|
+
|
|
11
|
+
## Constraints
|
|
12
|
+
|
|
13
|
+
- Never use `useEffect` for data fetching -- use Server Components or Server Actions
|
|
14
|
+
- Never use `getServerSideProps` or `getStaticProps` -- those are Pages Router patterns
|
|
15
|
+
- Never put `'use client'` on a component that does not need browser APIs, event handlers, or useState/useEffect
|
|
16
|
+
- Always use TypeScript strict mode -- no `any`
|
|
17
|
+
- Always handle loading and error states with the appropriate route segment files (`loading.tsx`, `error.tsx`, `not-found.tsx`)
|
|
18
|
+
- Use `satisfies` for type validation
|
|
19
|
+
- Named exports for all components and functions
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: next-best-practices
|
|
3
|
+
description: Next.js best practices - file conventions, RSC boundaries, data patterns, async APIs, metadata, error handling, route handlers, image/font optimization, bundling
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Next.js Best Practices
|
|
8
|
+
|
|
9
|
+
Apply these rules when writing or reviewing Next.js code.
|
|
10
|
+
|
|
11
|
+
## File Conventions
|
|
12
|
+
|
|
13
|
+
See [file-conventions.md](./file-conventions.md) for:
|
|
14
|
+
- Project structure and special files
|
|
15
|
+
- Route segments (dynamic, catch-all, groups)
|
|
16
|
+
- Parallel and intercepting routes
|
|
17
|
+
- Middleware rename in v16 (middleware → proxy)
|
|
18
|
+
|
|
19
|
+
## RSC Boundaries
|
|
20
|
+
|
|
21
|
+
Detect invalid React Server Component patterns.
|
|
22
|
+
|
|
23
|
+
See [rsc-boundaries.md](./rsc-boundaries.md) for:
|
|
24
|
+
- Async client component detection (invalid)
|
|
25
|
+
- Non-serializable props detection
|
|
26
|
+
- Server Action exceptions
|
|
27
|
+
|
|
28
|
+
## Async Patterns
|
|
29
|
+
|
|
30
|
+
Next.js 15+ async API changes.
|
|
31
|
+
|
|
32
|
+
See [async-patterns.md](./async-patterns.md) for:
|
|
33
|
+
- Async `params` and `searchParams`
|
|
34
|
+
- Async `cookies()` and `headers()`
|
|
35
|
+
- Migration codemod
|
|
36
|
+
|
|
37
|
+
## Runtime Selection
|
|
38
|
+
|
|
39
|
+
See [runtime-selection.md](./runtime-selection.md) for:
|
|
40
|
+
- Default to Node.js runtime
|
|
41
|
+
- When Edge runtime is appropriate
|
|
42
|
+
|
|
43
|
+
## Directives
|
|
44
|
+
|
|
45
|
+
See [directives.md](./directives.md) for:
|
|
46
|
+
- `'use client'`, `'use server'` (React)
|
|
47
|
+
- `'use cache'` (Next.js)
|
|
48
|
+
|
|
49
|
+
## Functions
|
|
50
|
+
|
|
51
|
+
See [functions.md](./functions.md) for:
|
|
52
|
+
- Navigation hooks: `useRouter`, `usePathname`, `useSearchParams`, `useParams`
|
|
53
|
+
- Server functions: `cookies`, `headers`, `draftMode`, `after`
|
|
54
|
+
- Generate functions: `generateStaticParams`, `generateMetadata`
|
|
55
|
+
|
|
56
|
+
## Error Handling
|
|
57
|
+
|
|
58
|
+
See [error-handling.md](./error-handling.md) for:
|
|
59
|
+
- `error.tsx`, `global-error.tsx`, `not-found.tsx`
|
|
60
|
+
- `redirect`, `permanentRedirect`, `notFound`
|
|
61
|
+
- `forbidden`, `unauthorized` (auth errors)
|
|
62
|
+
- `unstable_rethrow` for catch blocks
|
|
63
|
+
|
|
64
|
+
## Data Patterns
|
|
65
|
+
|
|
66
|
+
See [data-patterns.md](./data-patterns.md) for:
|
|
67
|
+
- Server Components vs Server Actions vs Route Handlers
|
|
68
|
+
- Avoiding data waterfalls (`Promise.all`, Suspense, preload)
|
|
69
|
+
- Client component data fetching
|
|
70
|
+
|
|
71
|
+
## Route Handlers
|
|
72
|
+
|
|
73
|
+
See [route-handlers.md](./route-handlers.md) for:
|
|
74
|
+
- `route.ts` basics
|
|
75
|
+
- GET handler conflicts with `page.tsx`
|
|
76
|
+
- Environment behavior (no React DOM)
|
|
77
|
+
- When to use vs Server Actions
|
|
78
|
+
|
|
79
|
+
## Metadata & OG Images
|
|
80
|
+
|
|
81
|
+
See [metadata.md](./metadata.md) for:
|
|
82
|
+
- Static and dynamic metadata
|
|
83
|
+
- `generateMetadata` function
|
|
84
|
+
- OG image generation with `next/og`
|
|
85
|
+
- File-based metadata conventions
|
|
86
|
+
|
|
87
|
+
## Image Optimization
|
|
88
|
+
|
|
89
|
+
See [image.md](./image.md) for:
|
|
90
|
+
- Always use `next/image` over `<img>`
|
|
91
|
+
- Remote images configuration
|
|
92
|
+
- Responsive `sizes` attribute
|
|
93
|
+
- Blur placeholders
|
|
94
|
+
- Priority loading for LCP
|
|
95
|
+
|
|
96
|
+
## Font Optimization
|
|
97
|
+
|
|
98
|
+
See [font.md](./font.md) for:
|
|
99
|
+
- `next/font` setup
|
|
100
|
+
- Google Fonts, local fonts
|
|
101
|
+
- Tailwind CSS integration
|
|
102
|
+
- Preloading subsets
|
|
103
|
+
|
|
104
|
+
## Bundling
|
|
105
|
+
|
|
106
|
+
See [bundling.md](./bundling.md) for:
|
|
107
|
+
- Server-incompatible packages
|
|
108
|
+
- CSS imports (not link tags)
|
|
109
|
+
- Polyfills (already included)
|
|
110
|
+
- ESM/CommonJS issues
|
|
111
|
+
- Bundle analysis
|
|
112
|
+
|
|
113
|
+
## Scripts
|
|
114
|
+
|
|
115
|
+
See [scripts.md](./scripts.md) for:
|
|
116
|
+
- `next/script` vs native script tags
|
|
117
|
+
- Inline scripts need `id`
|
|
118
|
+
- Loading strategies
|
|
119
|
+
- Google Analytics with `@next/third-parties`
|
|
120
|
+
|
|
121
|
+
## Hydration Errors
|
|
122
|
+
|
|
123
|
+
See [hydration-error.md](./hydration-error.md) for:
|
|
124
|
+
- Common causes (browser APIs, dates, invalid HTML)
|
|
125
|
+
- Debugging with error overlay
|
|
126
|
+
- Fixes for each cause
|
|
127
|
+
|
|
128
|
+
## Suspense Boundaries
|
|
129
|
+
|
|
130
|
+
See [suspense-boundaries.md](./suspense-boundaries.md) for:
|
|
131
|
+
- CSR bailout with `useSearchParams` and `usePathname`
|
|
132
|
+
- Which hooks require Suspense boundaries
|
|
133
|
+
|
|
134
|
+
## Parallel & Intercepting Routes
|
|
135
|
+
|
|
136
|
+
See [parallel-routes.md](./parallel-routes.md) for:
|
|
137
|
+
- Modal patterns with `@slot` and `(.)` interceptors
|
|
138
|
+
- `default.tsx` for fallbacks
|
|
139
|
+
- Closing modals correctly with `router.back()`
|
|
140
|
+
|
|
141
|
+
## Self-Hosting
|
|
142
|
+
|
|
143
|
+
See [self-hosting.md](./self-hosting.md) for:
|
|
144
|
+
- `output: 'standalone'` for Docker
|
|
145
|
+
- Cache handlers for multi-instance ISR
|
|
146
|
+
- What works vs needs extra setup
|
|
147
|
+
|
|
148
|
+
## Debug Tricks
|
|
149
|
+
|
|
150
|
+
See [debug-tricks.md](./debug-tricks.md) for:
|
|
151
|
+
- MCP endpoint for AI-assisted debugging
|
|
152
|
+
- Rebuild specific routes with `--debug-build-paths`
|
|
153
|
+
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Async Patterns
|
|
2
|
+
|
|
3
|
+
In Next.js 15+, `params`, `searchParams`, `cookies()`, and `headers()` are asynchronous.
|
|
4
|
+
|
|
5
|
+
## Async Params and SearchParams
|
|
6
|
+
|
|
7
|
+
Always type them as `Promise<...>` and await them.
|
|
8
|
+
|
|
9
|
+
### Pages and Layouts
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
type Props = { params: Promise<{ slug: string }> }
|
|
13
|
+
|
|
14
|
+
export default async function Page({ params }: Props) {
|
|
15
|
+
const { slug } = await params
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Route Handlers
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
export async function GET(
|
|
23
|
+
request: Request,
|
|
24
|
+
{ params }: { params: Promise<{ id: string }> }
|
|
25
|
+
) {
|
|
26
|
+
const { id } = await params
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### SearchParams
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
type Props = {
|
|
34
|
+
params: Promise<{ slug: string }>
|
|
35
|
+
searchParams: Promise<{ query?: string }>
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default async function Page({ params, searchParams }: Props) {
|
|
39
|
+
const { slug } = await params
|
|
40
|
+
const { query } = await searchParams
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Synchronous Components
|
|
45
|
+
|
|
46
|
+
Use `React.use()` for non-async components:
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
import { use } from 'react'
|
|
50
|
+
|
|
51
|
+
type Props = { params: Promise<{ slug: string }> }
|
|
52
|
+
|
|
53
|
+
export default function Page({ params }: Props) {
|
|
54
|
+
const { slug } = use(params)
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### generateMetadata
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
type Props = { params: Promise<{ slug: string }> }
|
|
62
|
+
|
|
63
|
+
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
|
64
|
+
const { slug } = await params
|
|
65
|
+
return { title: slug }
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Async Cookies and Headers
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
import { cookies, headers } from 'next/headers'
|
|
73
|
+
|
|
74
|
+
export default async function Page() {
|
|
75
|
+
const cookieStore = await cookies()
|
|
76
|
+
const headersList = await headers()
|
|
77
|
+
|
|
78
|
+
const theme = cookieStore.get('theme')
|
|
79
|
+
const userAgent = headersList.get('user-agent')
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Migration Codemod
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
npx @next/codemod@latest next-async-request-api .
|
|
87
|
+
```
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Bundling
|
|
2
|
+
|
|
3
|
+
Fix common bundling issues with third-party packages.
|
|
4
|
+
|
|
5
|
+
## Server-Incompatible Packages
|
|
6
|
+
|
|
7
|
+
Some packages use browser APIs (`window`, `document`, `localStorage`) and fail in Server Components.
|
|
8
|
+
|
|
9
|
+
### Error Signs
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
ReferenceError: window is not defined
|
|
13
|
+
ReferenceError: document is not defined
|
|
14
|
+
ReferenceError: localStorage is not defined
|
|
15
|
+
Module not found: Can't resolve 'fs'
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Solution 1: Mark as Client-Only
|
|
19
|
+
|
|
20
|
+
If the package is only needed on client:
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
// Bad: Fails - package uses window
|
|
24
|
+
import SomeChart from 'some-chart-library'
|
|
25
|
+
|
|
26
|
+
export default function Page() {
|
|
27
|
+
return <SomeChart />
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Good: Use dynamic import with ssr: false
|
|
31
|
+
import dynamic from 'next/dynamic'
|
|
32
|
+
|
|
33
|
+
const SomeChart = dynamic(() => import('some-chart-library'), {
|
|
34
|
+
ssr: false,
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
export default function Page() {
|
|
38
|
+
return <SomeChart />
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Solution 2: Externalize from Server Bundle
|
|
43
|
+
|
|
44
|
+
For packages that should run on server but have bundling issues:
|
|
45
|
+
|
|
46
|
+
```js
|
|
47
|
+
// next.config.js
|
|
48
|
+
module.exports = {
|
|
49
|
+
serverExternalPackages: ['problematic-package'],
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Use this for:
|
|
54
|
+
- Packages with native bindings (sharp, bcrypt)
|
|
55
|
+
- Packages that don't bundle well (some ORMs)
|
|
56
|
+
- Packages with circular dependencies
|
|
57
|
+
|
|
58
|
+
### Solution 3: Client Component Wrapper
|
|
59
|
+
|
|
60
|
+
Wrap the entire usage in a client component:
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
// components/ChartWrapper.tsx
|
|
64
|
+
'use client'
|
|
65
|
+
|
|
66
|
+
import { Chart } from 'chart-library'
|
|
67
|
+
|
|
68
|
+
export function ChartWrapper(props) {
|
|
69
|
+
return <Chart {...props} />
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// app/page.tsx (server component)
|
|
73
|
+
import { ChartWrapper } from '@/components/ChartWrapper'
|
|
74
|
+
|
|
75
|
+
export default function Page() {
|
|
76
|
+
return <ChartWrapper data={data} />
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## CSS Imports
|
|
81
|
+
|
|
82
|
+
Import CSS files instead of using `<link>` tags. Next.js handles bundling and optimization.
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
// Bad: Manual link tag
|
|
86
|
+
<link rel="stylesheet" href="/styles.css" />
|
|
87
|
+
|
|
88
|
+
// Good: Import CSS
|
|
89
|
+
import './styles.css'
|
|
90
|
+
|
|
91
|
+
// Good: CSS Modules
|
|
92
|
+
import styles from './Button.module.css'
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Polyfills
|
|
96
|
+
|
|
97
|
+
Next.js includes common polyfills automatically. Don't load redundant ones from polyfill.io or similar CDNs.
|
|
98
|
+
|
|
99
|
+
Already included: `Array.from`, `Object.assign`, `Promise`, `fetch`, `Map`, `Set`, `Symbol`, `URLSearchParams`, and 50+ others.
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
// Bad: Redundant polyfills
|
|
103
|
+
<script src="https://polyfill.io/v3/polyfill.min.js?features=fetch,Promise,Array.from" />
|
|
104
|
+
|
|
105
|
+
// Good: Next.js includes these automatically
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## ESM/CommonJS Issues
|
|
109
|
+
|
|
110
|
+
### Error Signs
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
SyntaxError: Cannot use import statement outside a module
|
|
114
|
+
Error: require() of ES Module
|
|
115
|
+
Module not found: ESM packages need to be imported
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Solution: Transpile Package
|
|
119
|
+
|
|
120
|
+
```js
|
|
121
|
+
// next.config.js
|
|
122
|
+
module.exports = {
|
|
123
|
+
transpilePackages: ['some-esm-package', 'another-package'],
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Common Problematic Packages
|
|
128
|
+
|
|
129
|
+
| Package | Issue | Solution |
|
|
130
|
+
|---------|-------|----------|
|
|
131
|
+
| `sharp` | Native bindings | `serverExternalPackages: ['sharp']` |
|
|
132
|
+
| `bcrypt` | Native bindings | `serverExternalPackages: ['bcrypt']` or use `bcryptjs` |
|
|
133
|
+
| `canvas` | Native bindings | `serverExternalPackages: ['canvas']` |
|
|
134
|
+
| `recharts` | Uses window | `dynamic(() => import('recharts'), { ssr: false })` |
|
|
135
|
+
| `react-quill` | Uses document | `dynamic(() => import('react-quill'), { ssr: false })` |
|
|
136
|
+
| `mapbox-gl` | Uses window | `dynamic(() => import('mapbox-gl'), { ssr: false })` |
|
|
137
|
+
| `monaco-editor` | Uses window | `dynamic(() => import('@monaco-editor/react'), { ssr: false })` |
|
|
138
|
+
| `lottie-web` | Uses document | `dynamic(() => import('lottie-react'), { ssr: false })` |
|
|
139
|
+
|
|
140
|
+
## Bundle Analysis
|
|
141
|
+
|
|
142
|
+
Analyze bundle size with the built-in analyzer (Next.js 16.1+):
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
next experimental-analyze
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
This opens an interactive UI to:
|
|
149
|
+
- Filter by route, environment (client/server), and type
|
|
150
|
+
- Inspect module sizes and import chains
|
|
151
|
+
- View treemap visualization
|
|
152
|
+
|
|
153
|
+
Save output for comparison:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
next experimental-analyze --output
|
|
157
|
+
# Output saved to .next/diagnostics/analyze
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Reference: https://nextjs.org/docs/app/guides/package-bundling
|
|
161
|
+
|
|
162
|
+
## Migrating from Webpack to Turbopack
|
|
163
|
+
|
|
164
|
+
Turbopack is the default bundler in Next.js 15+. If you have custom webpack config, migrate to Turbopack-compatible alternatives:
|
|
165
|
+
|
|
166
|
+
```js
|
|
167
|
+
// next.config.js
|
|
168
|
+
module.exports = {
|
|
169
|
+
// Good: Works with Turbopack
|
|
170
|
+
serverExternalPackages: ['package'],
|
|
171
|
+
transpilePackages: ['package'],
|
|
172
|
+
|
|
173
|
+
// Bad: Webpack-only - migrate away from this
|
|
174
|
+
webpack: (config) => {
|
|
175
|
+
// custom webpack config
|
|
176
|
+
},
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Reference: https://nextjs.org/docs/app/building-your-application/upgrading/from-webpack-to-turbopack
|