agy-superpowers 5.0.7 → 5.0.9
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/package.json +1 -1
- package/template/agent/rules/superpowers.md +54 -0
- package/template/agent/skills/api-design/SKILL.md +193 -0
- package/template/agent/skills/app-store-optimizer/SKILL.md +127 -0
- package/template/agent/skills/auth-and-identity/SKILL.md +167 -0
- package/template/agent/skills/backend-developer/SKILL.md +148 -0
- package/template/agent/skills/community-manager/SKILL.md +115 -0
- package/template/agent/skills/content-marketer/SKILL.md +111 -0
- package/template/agent/skills/conversion-optimizer/SKILL.md +142 -0
- package/template/agent/skills/copywriter/SKILL.md +114 -0
- package/template/agent/skills/cto-architect/SKILL.md +133 -0
- package/template/agent/skills/customer-success-manager/SKILL.md +126 -0
- package/template/agent/skills/data-analyst/SKILL.md +147 -0
- package/template/agent/skills/devops-engineer/SKILL.md +117 -0
- package/template/agent/skills/email-infrastructure/SKILL.md +164 -0
- package/template/agent/skills/frontend-developer/SKILL.md +172 -0
- package/template/agent/skills/frontend-developer/references/react-nextjs.md +343 -0
- package/template/agent/skills/frontend-developer/references/react-rules/_sections.md +46 -0
- package/template/agent/skills/frontend-developer/references/react-rules/_template.md +28 -0
- package/template/agent/skills/frontend-developer/references/react-rules/advanced-event-handler-refs.md +55 -0
- package/template/agent/skills/frontend-developer/references/react-rules/advanced-init-once.md +42 -0
- package/template/agent/skills/frontend-developer/references/react-rules/advanced-use-latest.md +39 -0
- package/template/agent/skills/frontend-developer/references/react-rules/async-api-routes.md +38 -0
- package/template/agent/skills/frontend-developer/references/react-rules/async-defer-await.md +80 -0
- package/template/agent/skills/frontend-developer/references/react-rules/async-dependencies.md +51 -0
- package/template/agent/skills/frontend-developer/references/react-rules/async-parallel.md +28 -0
- package/template/agent/skills/frontend-developer/references/react-rules/async-suspense-boundaries.md +99 -0
- package/template/agent/skills/frontend-developer/references/react-rules/bundle-barrel-imports.md +59 -0
- package/template/agent/skills/frontend-developer/references/react-rules/bundle-conditional.md +31 -0
- package/template/agent/skills/frontend-developer/references/react-rules/bundle-defer-third-party.md +49 -0
- package/template/agent/skills/frontend-developer/references/react-rules/bundle-dynamic-imports.md +35 -0
- package/template/agent/skills/frontend-developer/references/react-rules/bundle-preload.md +50 -0
- package/template/agent/skills/frontend-developer/references/react-rules/client-event-listeners.md +74 -0
- package/template/agent/skills/frontend-developer/references/react-rules/client-localstorage-schema.md +71 -0
- package/template/agent/skills/frontend-developer/references/react-rules/client-passive-event-listeners.md +48 -0
- package/template/agent/skills/frontend-developer/references/react-rules/client-swr-dedup.md +56 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-batch-dom-css.md +107 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-cache-function-results.md +80 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-cache-property-access.md +28 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-cache-storage.md +70 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-combine-iterations.md +32 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-early-exit.md +50 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-flatmap-filter.md +60 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-hoist-regexp.md +45 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-index-maps.md +37 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-length-check-first.md +49 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-min-max-loop.md +82 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-set-map-lookups.md +24 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-tosorted-immutable.md +57 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-activity.md +26 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-animate-svg-wrapper.md +47 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-conditional-render.md +40 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-content-visibility.md +38 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-hoist-jsx.md +46 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-hydration-no-flicker.md +82 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-hydration-suppress-warning.md +30 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-resource-hints.md +85 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-script-defer-async.md +68 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-svg-precision.md +28 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-usetransition-loading.md +75 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-defer-reads.md +39 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-dependencies.md +45 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-derived-state-no-effect.md +40 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-derived-state.md +29 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-functional-setstate.md +74 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-lazy-state-init.md +58 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-memo-with-default-value.md +38 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-memo.md +44 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-move-effect-to-event.md +45 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-no-inline-components.md +82 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-simple-expression-in-memo.md +35 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-split-combined-hooks.md +64 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-transitions.md +40 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-use-deferred-value.md +59 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-use-ref-transient-values.md +73 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-after-nonblocking.md +73 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-auth-actions.md +96 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-cache-lru.md +41 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-cache-react.md +76 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-dedup-props.md +65 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-hoist-static-io.md +142 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-parallel-fetching.md +83 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-serialization.md +38 -0
- package/template/agent/skills/frontend-developer/references/svelte-sveltekit.md +220 -0
- package/template/agent/skills/frontend-developer/references/vanilla.md +275 -0
- package/template/agent/skills/frontend-developer/references/vue-nuxt.md +289 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/_index.md +154 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/animation-class-based-technique.md +254 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/animation-state-driven-technique.md +291 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-async.md +97 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-data-flow.md +307 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-fallthrough-attrs.md +174 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-keep-alive.md +137 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-slots.md +216 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-suspense.md +228 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-teleport.md +108 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-transition-group.md +128 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-transition.md +125 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/composables.md +290 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/directives.md +162 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/perf-avoid-component-abstraction-in-lists.md +159 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/perf-v-once-v-memo-directives.md +182 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/perf-virtualize-large-lists.md +187 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/plugins.md +166 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/reactivity.md +344 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/render-functions.md +201 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/sfc.md +310 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/state-management.md +135 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/updated-hook-performance.md +187 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/_index.md +23 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-beforeenter-no-param-trigger.md +167 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-beforerouteenter-no-this.md +176 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-guard-async-await-pattern.md +227 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-navigation-guard-infinite-loop.md +187 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-navigation-guard-next-deprecated.md +150 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-param-change-no-lifecycle.md +181 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-simple-routing-cleanup.md +209 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-use-vue-router-for-production.md +183 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/_index.md +29 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/async-component-testing.md +163 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/teleport-testing-complexity.md +158 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-async-await-flushpromises.md +175 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-browser-vs-node-runners.md +208 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-component-blackbox-approach.md +144 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-composables-helper-wrapper.md +238 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-e2e-playwright-recommended.md +242 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-no-snapshot-only.md +197 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-pinia-store-setup.md +228 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-suspense-async-components.md +229 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-vitest-recommended-for-vue.md +204 -0
- package/template/agent/skills/game-design/SKILL.md +194 -0
- package/template/agent/skills/game-developer/SKILL.md +175 -0
- package/template/agent/skills/growth-hacker/SKILL.md +122 -0
- package/template/agent/skills/i18n-localization/SKILL.md +126 -0
- package/template/agent/skills/influencer-marketer/SKILL.md +141 -0
- package/template/agent/skills/mobile-developer/SKILL.md +194 -0
- package/template/agent/skills/mobile-developer/references/android-native.md +396 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-accessibility.md +36 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-architecture.md +52 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-coroutines.md +139 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-data-layer.md +51 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-emulator-skill.md +108 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-gradle-logic.md +126 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-retrofit.md +142 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-testing.md +102 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-viewmodel.md +43 -0
- package/template/agent/skills/mobile-developer/references/android-rules/coil-compose.md +74 -0
- package/template/agent/skills/mobile-developer/references/android-rules/compose-navigation.md +422 -0
- package/template/agent/skills/mobile-developer/references/android-rules/compose-performance-audit.md +199 -0
- package/template/agent/skills/mobile-developer/references/android-rules/compose-ui.md +49 -0
- package/template/agent/skills/mobile-developer/references/android-rules/gradle-build-performance.md +346 -0
- package/template/agent/skills/mobile-developer/references/android-rules/kotlin-concurrency-expert.md +169 -0
- package/template/agent/skills/mobile-developer/references/android-rules/rxjava-to-coroutines-migration.md +101 -0
- package/template/agent/skills/mobile-developer/references/android-rules/xml-to-compose-migration.md +338 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-best-practices.md +52 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-checks-migration.md +134 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-cli-app-best-practices.md +123 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-doc-validation.md +45 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-matcher-best-practices.md +106 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-modern-features.md +241 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-package-maintenance.md +75 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-test-fundamentals.md +124 -0
- package/template/agent/skills/mobile-developer/references/flutter.md +291 -0
- package/template/agent/skills/mobile-developer/references/ios-native.md +358 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/accessibility-patterns.md +215 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/animation-advanced.md +403 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/animation-basics.md +284 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/animation-transitions.md +326 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/charts-accessibility.md +135 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/charts.md +602 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/image-optimization.md +203 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/latest-apis.md +464 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/layout-best-practices.md +266 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/liquid-glass.md +416 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/list-patterns.md +394 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/macos-scenes.md +318 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/macos-views.md +357 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/macos-window-styling.md +303 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/performance-patterns.md +403 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/scroll-patterns.md +293 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/sheet-navigation-patterns.md +363 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/state-management.md +417 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/view-structure.md +389 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/_sections.md +86 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/_template.md +28 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/animation-derived-value.md +53 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/animation-gesture-detector-press.md +95 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/animation-gpu-properties.md +65 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/design-system-compound-components.md +66 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/fonts-config-plugin.md +71 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/imports-design-system-folder.md +68 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/js-hoist-intl.md +61 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-callbacks.md +44 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-function-references.md +132 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-images.md +53 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-inline-objects.md +97 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-item-expensive.md +94 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-item-memo.md +82 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-item-types.md +104 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-virtualize.md +67 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/monorepo-native-deps-in-app.md +46 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/monorepo-single-dependency-versions.md +63 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/navigation-native-navigators.md +188 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/react-compiler-destructure-functions.md +50 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/react-compiler-reanimated-shared-values.md +48 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/react-state-dispatcher.md +91 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/react-state-fallback.md +56 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/react-state-minimize.md +65 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/rendering-no-falsy-and.md +74 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/rendering-text-in-text-component.md +36 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/scroll-position-no-state.md +82 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/state-ground-truth.md +80 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-expo-image.md +66 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-image-gallery.md +104 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-measure-views.md +78 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-menus.md +174 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-native-modals.md +77 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-pressable.md +61 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-safe-area-scroll.md +65 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-scrollview-content-inset.md +45 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-styling.md +87 -0
- package/template/agent/skills/mobile-developer/references/react-native.md +345 -0
- package/template/agent/skills/monetization-strategist/SKILL.md +119 -0
- package/template/agent/skills/paid-acquisition-specialist/SKILL.md +119 -0
- package/template/agent/skills/product-manager/SKILL.md +105 -0
- package/template/agent/skills/real-time-features/SKILL.md +194 -0
- package/template/agent/skills/retention-specialist/SKILL.md +123 -0
- package/template/agent/skills/saas-architect/SKILL.md +139 -0
- package/template/agent/skills/security-engineer/SKILL.md +133 -0
- package/template/agent/skills/seo-specialist/SKILL.md +130 -0
- package/template/agent/skills/subscription-billing/SKILL.md +179 -0
- package/template/agent/skills/ux-designer/SKILL.md +128 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: frontend-developer
|
|
3
|
+
description: Use when building web UI, designing component architecture, or reviewing frontend code — regardless of framework (React, Vue, Svelte, etc.)
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Frontend Developer Lens
|
|
7
|
+
|
|
8
|
+
> **Philosophy:** Component-first. User-perception-first. Accessibility is not optional.
|
|
9
|
+
> Performance is felt by users, not measured in isolation.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## ⚠️ ASK BEFORE ASSUMING
|
|
14
|
+
|
|
15
|
+
If the stack is unspecified, **DO NOT default to Create React App**. Ask:
|
|
16
|
+
|
|
17
|
+
| What | Why it matters |
|
|
18
|
+
|------|----------------|
|
|
19
|
+
| **Framework?** React / Vue / Svelte / vanilla | Determines patterns, tooling, idioms |
|
|
20
|
+
| **Rendering?** CSR / SSR / SSG / ISR | SEO and performance strategy |
|
|
21
|
+
| **Design system?** Custom / Tailwind / MUI / shadcn | Styling approach and constraints |
|
|
22
|
+
| **Target browsers?** Modern / IE support? | Determines APIs and CSS you can use |
|
|
23
|
+
|
|
24
|
+
When stack is unspecified, assume React + TypeScript + Next.js (App Router).
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Core Instincts
|
|
29
|
+
|
|
30
|
+
- **User perception is reality** — loading states, micro-animations, and feedback loops matter as much as the happy path
|
|
31
|
+
- **Accessibility is load-bearing** — keyboard nav, screen readers, and contrast ratios affect real users
|
|
32
|
+
- **Render cost is real** — unnecessary re-renders degrade UX; measure before optimizing
|
|
33
|
+
- **Web Vitals are felt** — LCP, CLS, INP directly impact user satisfaction and SEO
|
|
34
|
+
- **Mobile is primary** — design mobile-first; test at real viewport sizes on real devices
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Web Vitals Thresholds (Google Standard)
|
|
39
|
+
|
|
40
|
+
| Metric | Good | Needs Improvement | Poor |
|
|
41
|
+
|--------|------|-------------------|------|
|
|
42
|
+
| **LCP** (Largest Contentful Paint) | < 2.5s | 2.5–4s | > 4s |
|
|
43
|
+
| **INP** (Interaction to Next Paint) | < 200ms | 200–500ms | > 500ms |
|
|
44
|
+
| **CLS** (Cumulative Layout Shift) | < 0.1 | 0.1–0.25 | > 0.25 |
|
|
45
|
+
| **FCP** (First Contentful Paint) | < 1.8s | 1.8–3s | > 3s |
|
|
46
|
+
| **TTFB** (Time to First Byte) | < 800ms | 800ms–1.8s | > 1.8s |
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Bundle Size Guidelines
|
|
51
|
+
|
|
52
|
+
| Bundle | Target | Action needed |
|
|
53
|
+
|--------|--------|---------------|
|
|
54
|
+
| Main JS (gzipped) | < 200KB | > 400KB: audit imports, code-split |
|
|
55
|
+
| Per-route chunk | < 50KB | > 100KB: lazy load heavy deps |
|
|
56
|
+
| CSS (gzipped) | < 50KB | > 100KB: purge unused styles |
|
|
57
|
+
| Images (hero) | < 200KB | Use `next/image` or WebP + lazy load |
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## ❌ Anti-Patterns to Avoid
|
|
62
|
+
|
|
63
|
+
| ❌ NEVER DO | Why | ✅ DO INSTEAD |
|
|
64
|
+
|------------|-----|--------------|
|
|
65
|
+
| Skip loading/error/empty states | User thinks the app is broken | Always handle all 3 async states |
|
|
66
|
+
| `onClick` only (no keyboard handler) | Keyboard users excluded | Use `<button>`; it's free keyboard support |
|
|
67
|
+
| Index as list `key` in dynamic lists | Reorder causes state and animation bugs | Unique stable ID from data |
|
|
68
|
+
| Images without `alt` or explicit dimensions | Screen reader fail + CLS score hit | `alt` always; `width`/`height` or `aspect-ratio` always |
|
|
69
|
+
| `<div>` for interactive elements | Not focusable, not semantic, no ARIA | Use `<button>`, `<a>`, or explicit `role` + `tabIndex` |
|
|
70
|
+
| Sequential `await` for independent fetches | Each waits on the previous (waterfall) | `Promise.all([fetchA(), fetchB()])` |
|
|
71
|
+
| Barrel exports in app code (`index.ts`) | Defeats tree-shaking, slow cold start | Import directly from the source file |
|
|
72
|
+
| Import entire library for one function | Bundle bloat (e.g., `import _ from 'lodash'`) | Named import or specific entry (`lodash/debounce`) |
|
|
73
|
+
| Client fetch where SSR/SSG would work | Slower FCP, worse SEO | Server-render or static-generate whenever possible |
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Accessibility Quick Rules
|
|
78
|
+
|
|
79
|
+
| Rule | Detail |
|
|
80
|
+
|------|--------|
|
|
81
|
+
| Color contrast (normal text) | ≥ 4.5:1 against background (WCAG AA) |
|
|
82
|
+
| Color contrast (large text, ≥18pt) | ≥ 3:1 against background |
|
|
83
|
+
| Touch / click target size | ≥ 44×44px (WCAG 2.5.5, Level AAA) |
|
|
84
|
+
| Focus indicator | Must be visible; `outline: none` without replacement is a violation |
|
|
85
|
+
| Form inputs | Must have `<label>` (associated via `for`/`id` or wrapping) |
|
|
86
|
+
| Images | Decorative → `alt=""`, informative → descriptive `alt` |
|
|
87
|
+
| Interactive elements order | DOM order must match visual order for keyboard users |
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Questions You Always Ask
|
|
92
|
+
|
|
93
|
+
**When planning UI:**
|
|
94
|
+
- What's the loading state? The error state? The empty state?
|
|
95
|
+
- Is this accessible to keyboard and screen reader users?
|
|
96
|
+
- What does this look like at 375px? At 1440px?
|
|
97
|
+
- Is this content crawlable by search engines (SSR or SSG)?
|
|
98
|
+
|
|
99
|
+
**When reviewing components:**
|
|
100
|
+
- Does this cause layout shift (CLS)? Are image dimensions declared?
|
|
101
|
+
- Can a user complete this entire flow using only the keyboard?
|
|
102
|
+
- Is every form input associated with a visible `<label>`?
|
|
103
|
+
- What's the bundle size delta from this new dependency?
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Red Flags in Code Review
|
|
108
|
+
|
|
109
|
+
**Must fix:**
|
|
110
|
+
- [ ] No loading/error/empty states for async data
|
|
111
|
+
- [ ] Interactive elements unreachable by keyboard
|
|
112
|
+
- [ ] Images without `alt` text or explicit dimensions (CLS risk)
|
|
113
|
+
- [ ] Form inputs without associated `<label>` elements
|
|
114
|
+
- [ ] Color contrast below 4.5:1 for body text
|
|
115
|
+
|
|
116
|
+
**Should fix:**
|
|
117
|
+
- [ ] Missing unique identifiers for list items
|
|
118
|
+
- [ ] Large dependencies added without bundle size justification
|
|
119
|
+
- [ ] Client-side fetch where server-rendering would work
|
|
120
|
+
- [ ] `outline: none` without visible focus replacement
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Performance Debugging Checklist
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
Slow initial load → Check bundle size, server render, remove unused deps
|
|
128
|
+
Layout shift (CLS) → Set image dimensions, avoid injecting content above fold
|
|
129
|
+
Janky interaction → Use CSS transforms, avoid forced layout (getBoundingClientRect in loops)
|
|
130
|
+
Too many re-renders → React DevTools Profiler → memo, useMemo, useCallback
|
|
131
|
+
Slow data fetch → Parallel with Promise.all(), SWR/React Query for cache
|
|
132
|
+
Large images → WebP format, srcset for responsive, lazy loading
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Platform References
|
|
138
|
+
|
|
139
|
+
When this skill is invoked, detect the project's framework and read
|
|
140
|
+
the matching reference file(s) from `references/` before proceeding:
|
|
141
|
+
|
|
142
|
+
| Stack indicator | Reference file |
|
|
143
|
+
|-----------------------------------------|---------------------------------|
|
|
144
|
+
| `next.config.js/ts` or `react` in deps | `references/react-nextjs.md` |
|
|
145
|
+
| `nuxt.config.ts` or `vue` in deps | `references/vue-nuxt.md` |
|
|
146
|
+
| `svelte.config.js` or `svelte` in deps | `references/svelte-sveltekit.md`|
|
|
147
|
+
| No framework deps / plain HTML | `references/vanilla.md` |
|
|
148
|
+
|
|
149
|
+
If the stack is unclear, ask the user which framework they're using.
|
|
150
|
+
|
|
151
|
+
### Granular Rules (React)
|
|
152
|
+
|
|
153
|
+
For React/Next.js projects, `references/react-rules/` contains 66
|
|
154
|
+
individual rule files from [Vercel's agent-skills](https://github.com/vercel-labs/agent-skills).
|
|
155
|
+
Each rule covers one specific pattern with incorrect/correct code examples.
|
|
156
|
+
|
|
157
|
+
Read `references/react-rules/_sections.md` for the full index
|
|
158
|
+
organized by priority (CRITICAL → LOW). Reference individual rules
|
|
159
|
+
when working on specific areas (waterfalls, bundle size, re-renders, SSR, etc.).
|
|
160
|
+
|
|
161
|
+
### Granular Rules (Vue)
|
|
162
|
+
|
|
163
|
+
For Vue/Nuxt projects, `references/vue-rules/` contains 44 individual
|
|
164
|
+
rule files from [antfu/skills](https://github.com/antfu/skills)
|
|
165
|
+
(sourced from [vuejs-ai/skills](https://github.com/vuejs-ai/skills)),
|
|
166
|
+
organized into three sub-directories:
|
|
167
|
+
|
|
168
|
+
- `best-practices/` — Components, reactivity, composables, performance (22 files)
|
|
169
|
+
- `router/` — Vue Router guards, navigation, lifecycle gotchas (8 files)
|
|
170
|
+
- `testing/` — Vitest, composable testing, Pinia setup, async patterns (11 files)
|
|
171
|
+
|
|
172
|
+
Read the `_index.md` in each sub-directory for an overview.
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
# React + Next.js (App Router) Reference
|
|
2
|
+
|
|
3
|
+
> **Philosophy:** Server-first. Components render on the server by default.
|
|
4
|
+
> Client components are opt-in. React Server Components change everything.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Project Setup & Detection
|
|
9
|
+
|
|
10
|
+
**Stack indicators:** `next.config.js` / `next.config.ts`, `package.json` with `next` dependency.
|
|
11
|
+
|
|
12
|
+
**Key config files:**
|
|
13
|
+
|
|
14
|
+
| File | Purpose |
|
|
15
|
+
|------|---------|
|
|
16
|
+
| `next.config.js` / `.ts` | Next.js configuration (redirects, rewrites, images) |
|
|
17
|
+
| `tsconfig.json` | TypeScript configuration |
|
|
18
|
+
| `tailwind.config.ts` | TailwindCSS configuration (if used) |
|
|
19
|
+
| `.env.local` | Local environment variables |
|
|
20
|
+
| `middleware.ts` | Edge middleware (auth, redirects) |
|
|
21
|
+
|
|
22
|
+
**Recommended project structure (App Router):**
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
app/
|
|
26
|
+
layout.tsx # Root layout (Server Component)
|
|
27
|
+
page.tsx # Home page
|
|
28
|
+
loading.tsx # Loading UI (Suspense boundary)
|
|
29
|
+
error.tsx # Error boundary
|
|
30
|
+
not-found.tsx # 404 page
|
|
31
|
+
(auth)/
|
|
32
|
+
login/page.tsx
|
|
33
|
+
register/page.tsx
|
|
34
|
+
(dashboard)/
|
|
35
|
+
layout.tsx # Dashboard layout with sidebar
|
|
36
|
+
page.tsx
|
|
37
|
+
settings/page.tsx
|
|
38
|
+
api/
|
|
39
|
+
route.ts # API route handlers
|
|
40
|
+
components/
|
|
41
|
+
ui/ # Reusable UI components (shadcn, etc.)
|
|
42
|
+
forms/ # Form-specific components
|
|
43
|
+
lib/
|
|
44
|
+
db.ts # Database client
|
|
45
|
+
auth.ts # Auth configuration
|
|
46
|
+
utils.ts # Utility functions
|
|
47
|
+
actions/ # Server Actions
|
|
48
|
+
hooks/ # Custom React hooks (client-side)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Architecture Patterns
|
|
54
|
+
|
|
55
|
+
### Server vs Client Components
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
Server Components (default) | Client Components ('use client')
|
|
59
|
+
-------------------------------|----------------------------------
|
|
60
|
+
Fetch data directly | useState, useEffect, event handlers
|
|
61
|
+
Access backend resources | Browser APIs (localStorage, etc.)
|
|
62
|
+
Keep secrets server-side | Interactivity (onClick, onChange)
|
|
63
|
+
Reduce bundle size | Third-party client libraries
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Rules of thumb:**
|
|
67
|
+
- Start everything as Server Component
|
|
68
|
+
- Add `'use client'` only when you need interactivity or browser APIs
|
|
69
|
+
- Push `'use client'` boundary as low as possible in the component tree
|
|
70
|
+
- Server Components can render Client Components (not vice versa)
|
|
71
|
+
|
|
72
|
+
### Data Fetching
|
|
73
|
+
|
|
74
|
+
| Pattern | Use When |
|
|
75
|
+
|---------|----------|
|
|
76
|
+
| **Server Components + `fetch`** | Default — data fetched at request or build time |
|
|
77
|
+
| **Server Actions** | Mutations (forms, button clicks) |
|
|
78
|
+
| **Route Handlers** (`app/api/`) | External API clients, webhooks |
|
|
79
|
+
| **`use` hook + Suspense** | Streaming data to client |
|
|
80
|
+
| **React Query / SWR** | Client-side caching, polling, optimistic updates |
|
|
81
|
+
|
|
82
|
+
**Server Actions** replace API routes for mutations:
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
// lib/actions/user.ts
|
|
86
|
+
'use server'
|
|
87
|
+
|
|
88
|
+
export async function updateProfile(formData: FormData) {
|
|
89
|
+
const name = formData.get('name') as string
|
|
90
|
+
await db.user.update({ where: { id: userId }, data: { name } })
|
|
91
|
+
revalidatePath('/profile')
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### State Management
|
|
96
|
+
|
|
97
|
+
| Approach | Use When |
|
|
98
|
+
|----------|----------|
|
|
99
|
+
| **Server state** (fetch in Server Components) | Most data — no client state needed |
|
|
100
|
+
| **React Context** | Theme, locale, auth — infrequently changing |
|
|
101
|
+
| **Zustand** | Complex client-side state |
|
|
102
|
+
| **URL state** (`useSearchParams`) | Filters, pagination, shareable state |
|
|
103
|
+
| **React Query / SWR** | Client-side server state cache |
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Performance Optimization
|
|
108
|
+
|
|
109
|
+
### Core Web Vitals (Target)
|
|
110
|
+
|
|
111
|
+
| Metric | Good | Poor |
|
|
112
|
+
|--------|------|------|
|
|
113
|
+
| **LCP** | < 2.5s | > 4s |
|
|
114
|
+
| **INP** | < 200ms | > 500ms |
|
|
115
|
+
| **CLS** | < 0.1 | > 0.25 |
|
|
116
|
+
|
|
117
|
+
### Key Optimizations
|
|
118
|
+
|
|
119
|
+
1. **Eliminate waterfalls** — parallel data fetching is critical.
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
// ❌ Bad: sequential (waterfall)
|
|
123
|
+
const user = await getUser(id)
|
|
124
|
+
const posts = await getPosts(user.id)
|
|
125
|
+
|
|
126
|
+
// ✅ Good: parallel
|
|
127
|
+
const [user, posts] = await Promise.all([getUser(id), getPosts(id)])
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
2. **`next/image`** — automatic optimization, lazy loading, responsive sizes.
|
|
131
|
+
|
|
132
|
+
3. **Dynamic imports** — code-split heavy components.
|
|
133
|
+
|
|
134
|
+
```tsx
|
|
135
|
+
const HeavyChart = dynamic(() => import('@/components/Chart'), {
|
|
136
|
+
loading: () => <ChartSkeleton />,
|
|
137
|
+
ssr: false, // client-only if needed
|
|
138
|
+
})
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
4. **Streaming with Suspense** — show content progressively.
|
|
142
|
+
|
|
143
|
+
```tsx
|
|
144
|
+
export default function Page() {
|
|
145
|
+
return (
|
|
146
|
+
<main>
|
|
147
|
+
<Header /> {/* instant */}
|
|
148
|
+
<Suspense fallback={<PostsSkeleton />}>
|
|
149
|
+
<Posts /> {/* streams when ready */}
|
|
150
|
+
</Suspense>
|
|
151
|
+
</main>
|
|
152
|
+
)
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
5. **Route segment config** — control caching behavior.
|
|
157
|
+
|
|
158
|
+
```tsx
|
|
159
|
+
export const dynamic = 'force-dynamic' // or 'auto', 'force-static'
|
|
160
|
+
export const revalidate = 3600 // ISR: revalidate every hour
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Common Libraries Ecosystem
|
|
166
|
+
|
|
167
|
+
| Category | Recommended | Alternative |
|
|
168
|
+
|----------|-------------|-------------|
|
|
169
|
+
| **UI** | `shadcn/ui` (copy-paste) | `radix-ui`, `headless-ui` |
|
|
170
|
+
| **Styling** | `tailwindcss` | `css modules`, `vanilla-extract` |
|
|
171
|
+
| **Forms** | `react-hook-form` + `zod` | `formik` |
|
|
172
|
+
| **Auth** | `next-auth` / `clerk` | `lucia`, `supabase auth` |
|
|
173
|
+
| **Database** | `prisma` / `drizzle` | `kysely` |
|
|
174
|
+
| **Server State** | `@tanstack/react-query` | `swr` |
|
|
175
|
+
| **Tables** | `@tanstack/react-table` | `ag-grid` |
|
|
176
|
+
| **Email** | `react-email` + `resend` | `nodemailer` |
|
|
177
|
+
| **Testing** | `vitest` + `@testing-library/react` | `jest` |
|
|
178
|
+
| **E2E** | `playwright` | `cypress` |
|
|
179
|
+
| **Analytics** | `@vercel/analytics` | `posthog` |
|
|
180
|
+
| **Icons** | `lucide-react` | `heroicons`, `phosphor` |
|
|
181
|
+
| **Date** | `date-fns` | `dayjs` |
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Anti-Patterns & Gotchas
|
|
186
|
+
|
|
187
|
+
| ❌ Don't | Why | ✅ Do Instead |
|
|
188
|
+
|----------|-----|---------------|
|
|
189
|
+
| `'use client'` on every component | Bloats bundle, loses RSC benefits | Default to Server Components |
|
|
190
|
+
| `useEffect` for data fetching | Waterfall, no SSR, loading state | Fetch in Server Components |
|
|
191
|
+
| Sequential `await` for independent data | Each waits on previous (waterfall) | `Promise.all()` |
|
|
192
|
+
| `localStorage` in Server Component | Doesn't exist on server, hydration mismatch | Move to Client Component |
|
|
193
|
+
| Barrel exports (`index.ts`) | Defeats tree-shaking, slow cold start | Import directly from source file |
|
|
194
|
+
| `next/router` (Pages Router) | Legacy | `next/navigation` (App Router) |
|
|
195
|
+
| Missing `loading.tsx` | No loading UI, blank screen | Add `loading.tsx` per route segment |
|
|
196
|
+
| Missing `error.tsx` | Unhandled errors crash entire page | Add `error.tsx` error boundaries |
|
|
197
|
+
| Fetch in Client Component for initial data | Extra round trip, no SSR | Pass data from Server Component as props |
|
|
198
|
+
| `console.log` in Server Components | Logs on server, not browser | Use proper logging (pino, winston) |
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Testing
|
|
203
|
+
|
|
204
|
+
| Layer | Tool | Purpose |
|
|
205
|
+
|-------|------|---------|
|
|
206
|
+
| **Unit** | Vitest + Testing Library | Components, hooks, utils |
|
|
207
|
+
| **Integration** | Vitest + MSW | API mocking, server actions |
|
|
208
|
+
| **E2E** | Playwright | Full user flows |
|
|
209
|
+
| **Visual** | Chromatic / Percy | Visual regression |
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Deployment & Distribution
|
|
214
|
+
|
|
215
|
+
### Vercel (recommended for Next.js)
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
# Deploy
|
|
219
|
+
vercel deploy # Preview
|
|
220
|
+
vercel --prod # Production
|
|
221
|
+
|
|
222
|
+
# Environment variables
|
|
223
|
+
vercel env add # Add env var
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Self-hosted
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
# Build
|
|
230
|
+
next build
|
|
231
|
+
|
|
232
|
+
# Start (requires Node.js server)
|
|
233
|
+
next start
|
|
234
|
+
|
|
235
|
+
# Docker
|
|
236
|
+
FROM node:20-alpine
|
|
237
|
+
COPY . .
|
|
238
|
+
RUN npm ci && npm run build
|
|
239
|
+
CMD ["npm", "start"]
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Static Export
|
|
243
|
+
|
|
244
|
+
```js
|
|
245
|
+
// next.config.js
|
|
246
|
+
module.exports = { output: 'export' }
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Generates static HTML — deployable to any CDN (Cloudflare Pages, Netlify, S3).
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Quick Reference — Granular Rules
|
|
254
|
+
|
|
255
|
+
Individual rule files in `react-rules/` with detailed incorrect/correct
|
|
256
|
+
code examples. Read the specific rule when working in that area.
|
|
257
|
+
|
|
258
|
+
> Source: [Vercel agent-skills](https://github.com/vercel-labs/agent-skills/tree/main/skills/react-best-practices)
|
|
259
|
+
|
|
260
|
+
### CRITICAL — Eliminating Waterfalls
|
|
261
|
+
|
|
262
|
+
- [async-parallel.md](react-rules/async-parallel.md) — Parallel data fetching
|
|
263
|
+
- [async-suspense-boundaries.md](react-rules/async-suspense-boundaries.md) — Suspense for streaming
|
|
264
|
+
- [async-defer-await.md](react-rules/async-defer-await.md) — Defer non-critical awaits
|
|
265
|
+
- [async-dependencies.md](react-rules/async-dependencies.md) — Minimize async dependencies
|
|
266
|
+
- [async-api-routes.md](react-rules/async-api-routes.md) — API route optimization
|
|
267
|
+
|
|
268
|
+
### CRITICAL — Bundle Size
|
|
269
|
+
|
|
270
|
+
- [bundle-dynamic-imports.md](react-rules/bundle-dynamic-imports.md) — Dynamic imports for code splitting
|
|
271
|
+
- [bundle-barrel-imports.md](react-rules/bundle-barrel-imports.md) — Avoid barrel exports
|
|
272
|
+
- [bundle-conditional.md](react-rules/bundle-conditional.md) — Conditional imports
|
|
273
|
+
- [bundle-defer-third-party.md](react-rules/bundle-defer-third-party.md) — Defer third-party scripts
|
|
274
|
+
- [bundle-preload.md](react-rules/bundle-preload.md) — Preload critical resources
|
|
275
|
+
|
|
276
|
+
### HIGH — Server-Side Performance
|
|
277
|
+
|
|
278
|
+
- [server-parallel-fetching.md](react-rules/server-parallel-fetching.md) — Parallel server fetching
|
|
279
|
+
- [server-cache-react.md](react-rules/server-cache-react.md) — React cache for dedup
|
|
280
|
+
- [server-cache-lru.md](react-rules/server-cache-lru.md) — LRU cache for hot data
|
|
281
|
+
- [server-hoist-static-io.md](react-rules/server-hoist-static-io.md) — Hoist static I/O
|
|
282
|
+
- [server-dedup-props.md](react-rules/server-dedup-props.md) — Dedup prop fetching
|
|
283
|
+
- [server-after-nonblocking.md](react-rules/server-after-nonblocking.md) — Non-blocking after()
|
|
284
|
+
- [server-auth-actions.md](react-rules/server-auth-actions.md) — Auth in server actions
|
|
285
|
+
- [server-serialization.md](react-rules/server-serialization.md) — Serialization optimization
|
|
286
|
+
|
|
287
|
+
### MEDIUM-HIGH — Client-Side Data
|
|
288
|
+
|
|
289
|
+
- [client-swr-dedup.md](react-rules/client-swr-dedup.md) — SWR deduplication
|
|
290
|
+
- [client-event-listeners.md](react-rules/client-event-listeners.md) — Event listener cleanup
|
|
291
|
+
- [client-localstorage-schema.md](react-rules/client-localstorage-schema.md) — localStorage versioning
|
|
292
|
+
- [client-passive-event-listeners.md](react-rules/client-passive-event-listeners.md) — Passive listeners
|
|
293
|
+
|
|
294
|
+
### MEDIUM — Re-render Optimization
|
|
295
|
+
|
|
296
|
+
- [rerender-memo.md](react-rules/rerender-memo.md) — React.memo usage
|
|
297
|
+
- [rerender-derived-state.md](react-rules/rerender-derived-state.md) — Derived state pattern
|
|
298
|
+
- [rerender-derived-state-no-effect.md](react-rules/rerender-derived-state-no-effect.md) — No useEffect for derived state
|
|
299
|
+
- [rerender-functional-setstate.md](react-rules/rerender-functional-setstate.md) — Functional setState
|
|
300
|
+
- [rerender-lazy-state-init.md](react-rules/rerender-lazy-state-init.md) — Lazy state initialization
|
|
301
|
+
- [rerender-no-inline-components.md](react-rules/rerender-no-inline-components.md) — No inline components
|
|
302
|
+
- [rerender-transitions.md](react-rules/rerender-transitions.md) — useTransition for heavy updates
|
|
303
|
+
- [rerender-use-deferred-value.md](react-rules/rerender-use-deferred-value.md) — useDeferredValue
|
|
304
|
+
- [rerender-use-ref-transient-values.md](react-rules/rerender-use-ref-transient-values.md) — useRef for transient values
|
|
305
|
+
- [rerender-split-combined-hooks.md](react-rules/rerender-split-combined-hooks.md) — Split combined hooks
|
|
306
|
+
- [rerender-defer-reads.md](react-rules/rerender-defer-reads.md) — Defer expensive reads
|
|
307
|
+
- [rerender-dependencies.md](react-rules/rerender-dependencies.md) — Dependency optimization
|
|
308
|
+
- [rerender-memo-with-default-value.md](react-rules/rerender-memo-with-default-value.md) — Memo with defaults
|
|
309
|
+
- [rerender-move-effect-to-event.md](react-rules/rerender-move-effect-to-event.md) — Move effects to events
|
|
310
|
+
- [rerender-simple-expression-in-memo.md](react-rules/rerender-simple-expression-in-memo.md) — Simple expressions
|
|
311
|
+
|
|
312
|
+
### MEDIUM — Rendering Performance
|
|
313
|
+
|
|
314
|
+
- [rendering-conditional-render.md](react-rules/rendering-conditional-render.md) — Conditional rendering
|
|
315
|
+
- [rendering-hoist-jsx.md](react-rules/rendering-hoist-jsx.md) — Hoist static JSX
|
|
316
|
+
- [rendering-content-visibility.md](react-rules/rendering-content-visibility.md) — CSS content-visibility
|
|
317
|
+
- [rendering-resource-hints.md](react-rules/rendering-resource-hints.md) — Resource hints
|
|
318
|
+
- [rendering-script-defer-async.md](react-rules/rendering-script-defer-async.md) — Script defer/async
|
|
319
|
+
- [rendering-hydration-no-flicker.md](react-rules/rendering-hydration-no-flicker.md) — No hydration flicker
|
|
320
|
+
- [rendering-hydration-suppress-warning.md](react-rules/rendering-hydration-suppress-warning.md) — Suppress hydration warnings
|
|
321
|
+
- [rendering-usetransition-loading.md](react-rules/rendering-usetransition-loading.md) — useTransition loading
|
|
322
|
+
- [rendering-activity.md](react-rules/rendering-activity.md) — Activity API
|
|
323
|
+
- [rendering-animate-svg-wrapper.md](react-rules/rendering-animate-svg-wrapper.md) — SVG animation
|
|
324
|
+
- [rendering-svg-precision.md](react-rules/rendering-svg-precision.md) — SVG precision
|
|
325
|
+
|
|
326
|
+
### LOW — JavaScript & Advanced
|
|
327
|
+
|
|
328
|
+
- [js-early-exit.md](react-rules/js-early-exit.md) — Early exit patterns
|
|
329
|
+
- [js-set-map-lookups.md](react-rules/js-set-map-lookups.md) — Set/Map for lookups
|
|
330
|
+
- [js-index-maps.md](react-rules/js-index-maps.md) — Index maps
|
|
331
|
+
- [js-cache-function-results.md](react-rules/js-cache-function-results.md) — Cache function results
|
|
332
|
+
- [js-flatmap-filter.md](react-rules/js-flatmap-filter.md) — flatMap over filter+map
|
|
333
|
+
- [js-combine-iterations.md](react-rules/js-combine-iterations.md) — Combine iterations
|
|
334
|
+
- [js-hoist-regexp.md](react-rules/js-hoist-regexp.md) — Hoist RegExp
|
|
335
|
+
- [js-length-check-first.md](react-rules/js-length-check-first.md) — Length check first
|
|
336
|
+
- [js-tosorted-immutable.md](react-rules/js-tosorted-immutable.md) — toSorted immutable
|
|
337
|
+
- [js-min-max-loop.md](react-rules/js-min-max-loop.md) — Min/max in loops
|
|
338
|
+
- [js-cache-property-access.md](react-rules/js-cache-property-access.md) — Cache property access
|
|
339
|
+
- [js-cache-storage.md](react-rules/js-cache-storage.md) — Cache Storage API
|
|
340
|
+
- [js-batch-dom-css.md](react-rules/js-batch-dom-css.md) — Batch DOM/CSS updates
|
|
341
|
+
- [advanced-event-handler-refs.md](react-rules/advanced-event-handler-refs.md) — Event handler refs
|
|
342
|
+
- [advanced-init-once.md](react-rules/advanced-init-once.md) — Init once pattern
|
|
343
|
+
- [advanced-use-latest.md](react-rules/advanced-use-latest.md) — useLatest pattern
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Sections
|
|
2
|
+
|
|
3
|
+
This file defines all sections, their ordering, impact levels, and descriptions.
|
|
4
|
+
The section ID (in parentheses) is the filename prefix used to group rules.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. Eliminating Waterfalls (async)
|
|
9
|
+
|
|
10
|
+
**Impact:** CRITICAL
|
|
11
|
+
**Description:** Waterfalls are the #1 performance killer. Each sequential await adds full network latency. Eliminating them yields the largest gains.
|
|
12
|
+
|
|
13
|
+
## 2. Bundle Size Optimization (bundle)
|
|
14
|
+
|
|
15
|
+
**Impact:** CRITICAL
|
|
16
|
+
**Description:** Reducing initial bundle size improves Time to Interactive and Largest Contentful Paint.
|
|
17
|
+
|
|
18
|
+
## 3. Server-Side Performance (server)
|
|
19
|
+
|
|
20
|
+
**Impact:** HIGH
|
|
21
|
+
**Description:** Optimizing server-side rendering and data fetching eliminates server-side waterfalls and reduces response times.
|
|
22
|
+
|
|
23
|
+
## 4. Client-Side Data Fetching (client)
|
|
24
|
+
|
|
25
|
+
**Impact:** MEDIUM-HIGH
|
|
26
|
+
**Description:** Automatic deduplication and efficient data fetching patterns reduce redundant network requests.
|
|
27
|
+
|
|
28
|
+
## 5. Re-render Optimization (rerender)
|
|
29
|
+
|
|
30
|
+
**Impact:** MEDIUM
|
|
31
|
+
**Description:** Reducing unnecessary re-renders minimizes wasted computation and improves UI responsiveness.
|
|
32
|
+
|
|
33
|
+
## 6. Rendering Performance (rendering)
|
|
34
|
+
|
|
35
|
+
**Impact:** MEDIUM
|
|
36
|
+
**Description:** Optimizing the rendering process reduces the work the browser needs to do.
|
|
37
|
+
|
|
38
|
+
## 7. JavaScript Performance (js)
|
|
39
|
+
|
|
40
|
+
**Impact:** LOW-MEDIUM
|
|
41
|
+
**Description:** Micro-optimizations for hot paths can add up to meaningful improvements.
|
|
42
|
+
|
|
43
|
+
## 8. Advanced Patterns (advanced)
|
|
44
|
+
|
|
45
|
+
**Impact:** LOW
|
|
46
|
+
**Description:** Advanced patterns for specific cases that require careful implementation.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Rule Title Here
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: Optional description of impact (e.g., "20-50% improvement")
|
|
5
|
+
tags: tag1, tag2
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Rule Title Here
|
|
9
|
+
|
|
10
|
+
**Impact: MEDIUM (optional impact description)**
|
|
11
|
+
|
|
12
|
+
Brief explanation of the rule and why it matters. This should be clear and concise, explaining the performance implications.
|
|
13
|
+
|
|
14
|
+
**Incorrect (description of what's wrong):**
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
// Bad code example here
|
|
18
|
+
const bad = example()
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Correct (description of what's right):**
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
// Good code example here
|
|
25
|
+
const good = example()
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Reference: [Link to documentation or resource](https://example.com)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Store Event Handlers in Refs
|
|
3
|
+
impact: LOW
|
|
4
|
+
impactDescription: stable subscriptions
|
|
5
|
+
tags: advanced, hooks, refs, event-handlers, optimization
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Store Event Handlers in Refs
|
|
9
|
+
|
|
10
|
+
Store callbacks in refs when used in effects that shouldn't re-subscribe on callback changes.
|
|
11
|
+
|
|
12
|
+
**Incorrect (re-subscribes on every render):**
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
function useWindowEvent(event: string, handler: (e) => void) {
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
window.addEventListener(event, handler)
|
|
18
|
+
return () => window.removeEventListener(event, handler)
|
|
19
|
+
}, [event, handler])
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Correct (stable subscription):**
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
function useWindowEvent(event: string, handler: (e) => void) {
|
|
27
|
+
const handlerRef = useRef(handler)
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
handlerRef.current = handler
|
|
30
|
+
}, [handler])
|
|
31
|
+
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
const listener = (e) => handlerRef.current(e)
|
|
34
|
+
window.addEventListener(event, listener)
|
|
35
|
+
return () => window.removeEventListener(event, listener)
|
|
36
|
+
}, [event])
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Alternative: use `useEffectEvent` if you're on latest React:**
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import { useEffectEvent } from 'react'
|
|
44
|
+
|
|
45
|
+
function useWindowEvent(event: string, handler: (e) => void) {
|
|
46
|
+
const onEvent = useEffectEvent(handler)
|
|
47
|
+
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
window.addEventListener(event, onEvent)
|
|
50
|
+
return () => window.removeEventListener(event, onEvent)
|
|
51
|
+
}, [event])
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`useEffectEvent` provides a cleaner API for the same pattern: it creates a stable function reference that always calls the latest version of the handler.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Initialize App Once, Not Per Mount
|
|
3
|
+
impact: LOW-MEDIUM
|
|
4
|
+
impactDescription: avoids duplicate init in development
|
|
5
|
+
tags: initialization, useEffect, app-startup, side-effects
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Initialize App Once, Not Per Mount
|
|
9
|
+
|
|
10
|
+
Do not put app-wide initialization that must run once per app load inside `useEffect([])` of a component. Components can remount and effects will re-run. Use a module-level guard or top-level init in the entry module instead.
|
|
11
|
+
|
|
12
|
+
**Incorrect (runs twice in dev, re-runs on remount):**
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
function Comp() {
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
loadFromStorage()
|
|
18
|
+
checkAuthToken()
|
|
19
|
+
}, [])
|
|
20
|
+
|
|
21
|
+
// ...
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Correct (once per app load):**
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
let didInit = false
|
|
29
|
+
|
|
30
|
+
function Comp() {
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
if (didInit) return
|
|
33
|
+
didInit = true
|
|
34
|
+
loadFromStorage()
|
|
35
|
+
checkAuthToken()
|
|
36
|
+
}, [])
|
|
37
|
+
|
|
38
|
+
// ...
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Reference: [Initializing the application](https://react.dev/learn/you-might-not-need-an-effect#initializing-the-application)
|