4.8 KiB
AGENTS.md
Author Preferences
Infrastructure Checklist
When creating new infrastructure (routes, API handlers, providers), use exploration findings as a checklist — systematically verify each convention is followed before writing code.
Project
Next.js 16 landing page for Frosty using the App Router with React 19. Deployed on Cloudflare Workers via @opennextjs/cloudflare.
Commands
pnpm dev # Start development server
pnpm build # Production build
pnpm start # Start production server (Node.js)
pnpm preview # Build and preview on local Cloudflare Workers
pnpm deploy # Build and deploy to Cloudflare Workers
pnpm upload # Build and upload to Cloudflare Workers (no deploy)
pnpm cf-typegen # Generate CloudflareEnv types from wrangler.jsonc
pnpm lint # Run ESLint
pnpm typecheck # TypeScript type checking (tsc --noEmit)
pnpm format # Format with Prettier
pnpm clean # Delete .next, .open-next, and node_modules
pnpm nuke # Delete .next, .open-next, node_modules, and pnpm-lock.yaml
Source Structure
src/app/- App Router pages and layoutssrc/components/- React components (ui/subdirectory for shadcnbase-vegastyle — add withpnpm dlx shadcn@latest add <component>)src/lib/- Utilities (cn()for className merging,constants.tsfor external links)src/assets/- Static images (screenshots)
Key Configuration
- React Compiler: Enabled in
next.config.tsfor automatic memoization - Typed Routes: Enabled for type-safe navigation (use
Routetype fromnext/navigation) - Path Alias:
@/*maps to./src/* - Strict TypeScript:
noUncheckedIndexedAccess,noImplicitReturns,noFallthroughCasesInSwitch,noImplicitOverride,verbatimModuleSyntax
Cache Components
Enabled (docs) — everything is dynamic (SSR) by default. Opt into caching with "use cache" + cacheLife(), wrap async work in <Suspense> for PPR. Old revalidate/dynamic/fetchCache exports are replaced. Use cacheTag() + revalidateTag()/updateTag() for on-demand invalidation. Durable runtime cache requires R2 incremental cache (see open-next.config.ts) — without it, cache is in-memory only per Worker instance.
Cloudflare Workers
wrangler.jsonc- Cloudflare Workers configuration (bindings, R2, KV, etc.)open-next.config.ts- OpenNext adapter config (ISR requires uncommenting R2 incremental cache)cloudflare-env.d.ts- Generated types for Cloudflare bindings (runpnpm cf-typegento regenerate)- Dev mode calls
initOpenNextCloudflareForDev()innext.config.tsfor local Cloudflare emulation
Naming Conventions
- Components: PascalCase (
Button.tsx) - Utilities: camelCase (
formatDate.ts) - Hooks:
useprefix (useDebounce.ts) - Types: PascalCase (
UserProfile)
ESLint Rules
Config: eslint.config.mjs. Ignores src/components/ui/.
Notable strict rules enforced:
eqeqeq: 'smart'- Strict equality (except== null)no-console- Warn on console usage (allowsconsole.warnandconsole.error)@typescript-eslint/strict-boolean-expressions- No implicit boolean coercion (butallowNullableBooleanandallowNullableStringare enabled)@typescript-eslint/switch-exhaustiveness-check- Exhaustive switch statements@typescript-eslint/consistent-type-imports- Useimport typefor types (fixStyle: 'inline-type-imports')@typescript-eslint/no-unnecessary-condition- No redundant conditions@typescript-eslint/no-misused-promises- Prevent floating promises (checksVoidReturn.attributesdisabled for JSX)@eslint-react/jsx-shorthand-boolean- Use shorthand boolean JSX props@eslint-react/no-array-index-key- Warn on array index as keyreact-you-might-not-need-an-effect- Avoid unnecessary useEffect- Unused variables must be prefixed with
_
Gotchas
- shadcn uses @base-ui/react: Not Radix UI — component primitives differ from older shadcn examples.
button.tsxis a'use client'module with noasChildprop. Checksrc/components/ui/before building custom UI. useSearchParams()needs Suspense: Always wrap components usinguseSearchParams()in a<Suspense>boundary — required for production builds.- Never remove
tw-animate-css: Required by shadcn/ui components for animations. Check shadcn dependencies before removing any package. - No
pnpmprefix inside package.json scripts: The package manager is already the script runner. Use bare commands (e.g.,next build, notpnpm next build).
Dev Tooling
- Prettier: Auto-sorts imports (
prettier-plugin-organize-imports) and Tailwind classes (prettier-plugin-tailwindcss) - react-scan: Runtime render performance visualization (dev only)