Add custom Claude Code upgrades and restore all skills

Added 16 custom skills:
- ralph (RalphLoop autonomous agent)
- brainstorming (with Ralph integration)
- dispatching-parallel-agents
- autonomous-loop
- multi-ai-brainstorm
- cognitive-context, cognitive-core, cognitive-planner, cognitive-safety
- tool-discovery-agent
- ui-ux-pro-max (full design system)
- wordpress-ai
- agent-pipeline-builder
- dev-browser
- planning-with-files
- playwright-skill

Also organized remaining skills that were at root level into skills/ folder.

Total: 272 skills from skills.sh + 16 custom upgrades

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
admin
2026-01-23 18:10:15 +00:00
Unverified
parent b723e2bd7d
commit 7b42ebd2b0
100 changed files with 30094 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,Widgets,Use StatelessWidget when possible,Immutable widgets are simpler,StatelessWidget for static UI,StatefulWidget for everything,class MyWidget extends StatelessWidget,class MyWidget extends StatefulWidget (static),Medium,https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html
2,Widgets,Keep widgets small,Single responsibility principle,Extract widgets into smaller pieces,Large build methods,Column(children: [Header() Content()]),500+ line build method,Medium,
3,Widgets,Use const constructors,Compile-time constants for performance,const MyWidget() when possible,Non-const for static widgets,const Text('Hello'),Text('Hello') for literals,High,https://dart.dev/guides/language/language-tour#constant-constructors
4,Widgets,Prefer composition over inheritance,Combine widgets using children,Compose widgets,Extend widget classes,Container(child: MyContent()),class MyContainer extends Container,Medium,
5,State,Use setState correctly,Minimal state in StatefulWidget,setState for UI state changes,setState for business logic,setState(() { _counter++; }),Complex logic in setState,Medium,https://api.flutter.dev/flutter/widgets/State/setState.html
6,State,Avoid setState in build,Never call setState during build,setState in callbacks only,setState in build method,onPressed: () => setState(() {}),build() { setState(); },High,
7,State,Use state management for complex apps,Provider Riverpod BLoC,State management for shared state,setState for global state,Provider.of<MyState>(context),Global setState calls,Medium,
8,State,Prefer Riverpod or Provider,Recommended state solutions,Riverpod for new projects,InheritedWidget manually,ref.watch(myProvider),Custom InheritedWidget,Medium,https://riverpod.dev/
9,State,Dispose resources,Clean up controllers and subscriptions,dispose() for cleanup,Memory leaks from subscriptions,@override void dispose() { controller.dispose(); },No dispose implementation,High,
10,Layout,Use Column and Row,Basic layout widgets,Column Row for linear layouts,Stack for simple layouts,"Column(children: [Text(), Button()])",Stack for vertical list,Medium,https://api.flutter.dev/flutter/widgets/Column-class.html
11,Layout,Use Expanded and Flexible,Control flex behavior,Expanded to fill space,Fixed sizes in flex containers,Expanded(child: Container()),Container(width: 200) in Row,Medium,
12,Layout,Use SizedBox for spacing,Consistent spacing,SizedBox for gaps,Container for spacing only,SizedBox(height: 16),Container(height: 16),Low,
13,Layout,Use LayoutBuilder for responsive,Respond to constraints,LayoutBuilder for adaptive layouts,Fixed sizes for responsive,LayoutBuilder(builder: (context constraints) {}),Container(width: 375),Medium,https://api.flutter.dev/flutter/widgets/LayoutBuilder-class.html
14,Layout,Avoid deep nesting,Keep widget tree shallow,Extract deeply nested widgets,10+ levels of nesting,Extract widget to method or class,Column(Row(Column(Row(...)))),Medium,
15,Lists,Use ListView.builder,Lazy list building,ListView.builder for long lists,ListView with children for large lists,"ListView.builder(itemCount: 100, itemBuilder: ...)",ListView(children: items.map(...).toList()),High,https://api.flutter.dev/flutter/widgets/ListView-class.html
16,Lists,Provide itemExtent when known,Skip measurement,itemExtent for fixed height items,No itemExtent for uniform lists,ListView.builder(itemExtent: 50),ListView.builder without itemExtent,Medium,
17,Lists,Use keys for stateful items,Preserve widget state,Key for stateful list items,No key for dynamic lists,ListTile(key: ValueKey(item.id)),ListTile without key,High,
18,Lists,Use SliverList for custom scroll,Custom scroll effects,CustomScrollView with Slivers,Nested ListViews,CustomScrollView(slivers: [SliverList()]),ListView inside ListView,Medium,https://api.flutter.dev/flutter/widgets/SliverList-class.html
19,Navigation,Use Navigator 2.0 or GoRouter,Declarative routing,go_router for navigation,Navigator.push for complex apps,GoRouter(routes: [...]),Navigator.push everywhere,Medium,https://pub.dev/packages/go_router
20,Navigation,Use named routes,Organized navigation,Named routes for clarity,Anonymous routes,Navigator.pushNamed(context '/home'),Navigator.push(context MaterialPageRoute()),Low,
21,Navigation,Handle back button (PopScope),Android back behavior and predictive back (Android 14+),Use PopScope widget (WillPopScope is deprecated),Use WillPopScope,"PopScope(canPop: false, onPopInvoked: (didPop) => ...)",WillPopScope(onWillPop: ...),High,https://api.flutter.dev/flutter/widgets/PopScope-class.html
22,Navigation,Pass typed arguments,Type-safe route arguments,Typed route arguments,Dynamic arguments,MyRoute(id: '123'),arguments: {'id': '123'},Medium,
23,Async,Use FutureBuilder,Async UI building,FutureBuilder for async data,setState for async,FutureBuilder(future: fetchData()),fetchData().then((d) => setState()),Medium,https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
24,Async,Use StreamBuilder,Stream UI building,StreamBuilder for streams,Manual stream subscription,StreamBuilder(stream: myStream),stream.listen in initState,Medium,https://api.flutter.dev/flutter/widgets/StreamBuilder-class.html
25,Async,Handle loading and error states,Complete async UI states,ConnectionState checks,Only success state,if (snapshot.connectionState == ConnectionState.waiting),No loading indicator,High,
26,Async,Cancel subscriptions,Clean up stream subscriptions,Cancel in dispose,Memory leaks,subscription.cancel() in dispose,No subscription cleanup,High,
27,Theming,Use ThemeData,Consistent theming,ThemeData for app theme,Hardcoded colors,Theme.of(context).primaryColor,Color(0xFF123456) everywhere,Medium,https://api.flutter.dev/flutter/material/ThemeData-class.html
28,Theming,Use ColorScheme,Material 3 color system,ColorScheme for colors,Individual color properties,colorScheme: ColorScheme.fromSeed(),primaryColor: Colors.blue,Medium,
29,Theming,Access theme via context,Dynamic theme access,Theme.of(context),Static theme reference,Theme.of(context).textTheme.bodyLarge,TextStyle(fontSize: 16),Medium,
30,Theming,Support dark mode,Respect system theme,darkTheme in MaterialApp,Light theme only,"MaterialApp(theme: light, darkTheme: dark)",MaterialApp(theme: light),Medium,
31,Animation,Use implicit animations,Simple animations,AnimatedContainer AnimatedOpacity,Explicit for simple transitions,AnimatedContainer(duration: Duration()),AnimationController for fade,Low,https://api.flutter.dev/flutter/widgets/AnimatedContainer-class.html
32,Animation,Use AnimationController for complex,Fine-grained control,AnimationController with Ticker,Implicit for complex sequences,AnimationController(vsync: this),AnimatedContainer for staggered,Medium,
33,Animation,Dispose AnimationControllers,Clean up animation resources,dispose() for controllers,Memory leaks,controller.dispose() in dispose,No controller disposal,High,
34,Animation,Use Hero for transitions,Shared element transitions,Hero for navigation animations,Manual shared element,Hero(tag: 'image' child: Image()),Custom shared element animation,Low,https://api.flutter.dev/flutter/widgets/Hero-class.html
35,Forms,Use Form widget,Form validation,Form with GlobalKey,Individual validation,Form(key: _formKey child: ...),TextField without Form,Medium,https://api.flutter.dev/flutter/widgets/Form-class.html
36,Forms,Use TextEditingController,Control text input,Controller for text fields,onChanged for all text,final controller = TextEditingController(),onChanged: (v) => setState(),Medium,
37,Forms,Validate on submit,Form validation flow,_formKey.currentState!.validate(),Skip validation,if (_formKey.currentState!.validate()),Submit without validation,High,
38,Forms,Dispose controllers,Clean up text controllers,dispose() for controllers,Memory leaks,controller.dispose() in dispose,No controller disposal,High,
39,Performance,Use const widgets,Reduce rebuilds,const for static widgets,No const for literals,const Icon(Icons.add),Icon(Icons.add),High,
40,Performance,Avoid rebuilding entire tree,Minimal rebuild scope,Isolate changing widgets,setState on parent,Consumer only around changing widget,setState on root widget,High,
41,Performance,Use RepaintBoundary,Isolate repaints,RepaintBoundary for animations,Full screen repaints,RepaintBoundary(child: AnimatedWidget()),Animation without boundary,Medium,https://api.flutter.dev/flutter/widgets/RepaintBoundary-class.html
42,Performance,Profile with DevTools,Measure before optimizing,Flutter DevTools profiling,Guess at performance,DevTools performance tab,Optimize without measuring,Medium,https://docs.flutter.dev/tools/devtools
43,Accessibility,Use Semantics widget,Screen reader support,Semantics for accessibility,Missing accessibility info,Semantics(label: 'Submit button'),GestureDetector without semantics,High,https://api.flutter.dev/flutter/widgets/Semantics-class.html
44,Accessibility,Support large fonts,MediaQuery text scaling,MediaQuery.textScaleFactor,Fixed font sizes,style: Theme.of(context).textTheme,TextStyle(fontSize: 14),High,
45,Accessibility,Test with screen readers,TalkBack and VoiceOver,Test accessibility regularly,Skip accessibility testing,Regular TalkBack testing,No screen reader testing,High,
46,Testing,Use widget tests,Test widget behavior,WidgetTester for UI tests,Unit tests only,testWidgets('...' (tester) async {}),Only test() for UI,Medium,https://docs.flutter.dev/testing
47,Testing,Use integration tests,Full app testing,integration_test package,Manual testing only,IntegrationTestWidgetsFlutterBinding,Manual E2E testing,Medium,
48,Testing,Mock dependencies,Isolate tests,Mockito or mocktail,Real dependencies in tests,when(mock.method()).thenReturn(),Real API calls in tests,Medium,
49,Platform,Use Platform checks,Platform-specific code,Platform.isIOS Platform.isAndroid,Same code for all platforms,if (Platform.isIOS) {},Hardcoded iOS behavior,Medium,
50,Platform,Use kIsWeb for web,Web platform detection,kIsWeb for web checks,Platform for web,if (kIsWeb) {},Platform.isWeb (doesn't exist),Medium,
51,Packages,Use pub.dev packages,Community packages,Popular maintained packages,Custom implementations,cached_network_image,Custom image cache,Medium,https://pub.dev/
52,Packages,Check package quality,Quality before adding,Pub points and popularity,Any package without review,100+ pub points,Unmaintained packages,Medium,
1 No Category Guideline Description Do Don't Code Good Code Bad Severity Docs URL
2 1 Widgets Use StatelessWidget when possible Immutable widgets are simpler StatelessWidget for static UI StatefulWidget for everything class MyWidget extends StatelessWidget class MyWidget extends StatefulWidget (static) Medium https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html
3 2 Widgets Keep widgets small Single responsibility principle Extract widgets into smaller pieces Large build methods Column(children: [Header() Content()]) 500+ line build method Medium
4 3 Widgets Use const constructors Compile-time constants for performance const MyWidget() when possible Non-const for static widgets const Text('Hello') Text('Hello') for literals High https://dart.dev/guides/language/language-tour#constant-constructors
5 4 Widgets Prefer composition over inheritance Combine widgets using children Compose widgets Extend widget classes Container(child: MyContent()) class MyContainer extends Container Medium
6 5 State Use setState correctly Minimal state in StatefulWidget setState for UI state changes setState for business logic setState(() { _counter++; }) Complex logic in setState Medium https://api.flutter.dev/flutter/widgets/State/setState.html
7 6 State Avoid setState in build Never call setState during build setState in callbacks only setState in build method onPressed: () => setState(() {}) build() { setState(); } High
8 7 State Use state management for complex apps Provider Riverpod BLoC State management for shared state setState for global state Provider.of<MyState>(context) Global setState calls Medium
9 8 State Prefer Riverpod or Provider Recommended state solutions Riverpod for new projects InheritedWidget manually ref.watch(myProvider) Custom InheritedWidget Medium https://riverpod.dev/
10 9 State Dispose resources Clean up controllers and subscriptions dispose() for cleanup Memory leaks from subscriptions @override void dispose() { controller.dispose(); } No dispose implementation High
11 10 Layout Use Column and Row Basic layout widgets Column Row for linear layouts Stack for simple layouts Column(children: [Text(), Button()]) Stack for vertical list Medium https://api.flutter.dev/flutter/widgets/Column-class.html
12 11 Layout Use Expanded and Flexible Control flex behavior Expanded to fill space Fixed sizes in flex containers Expanded(child: Container()) Container(width: 200) in Row Medium
13 12 Layout Use SizedBox for spacing Consistent spacing SizedBox for gaps Container for spacing only SizedBox(height: 16) Container(height: 16) Low
14 13 Layout Use LayoutBuilder for responsive Respond to constraints LayoutBuilder for adaptive layouts Fixed sizes for responsive LayoutBuilder(builder: (context constraints) {}) Container(width: 375) Medium https://api.flutter.dev/flutter/widgets/LayoutBuilder-class.html
15 14 Layout Avoid deep nesting Keep widget tree shallow Extract deeply nested widgets 10+ levels of nesting Extract widget to method or class Column(Row(Column(Row(...)))) Medium
16 15 Lists Use ListView.builder Lazy list building ListView.builder for long lists ListView with children for large lists ListView.builder(itemCount: 100, itemBuilder: ...) ListView(children: items.map(...).toList()) High https://api.flutter.dev/flutter/widgets/ListView-class.html
17 16 Lists Provide itemExtent when known Skip measurement itemExtent for fixed height items No itemExtent for uniform lists ListView.builder(itemExtent: 50) ListView.builder without itemExtent Medium
18 17 Lists Use keys for stateful items Preserve widget state Key for stateful list items No key for dynamic lists ListTile(key: ValueKey(item.id)) ListTile without key High
19 18 Lists Use SliverList for custom scroll Custom scroll effects CustomScrollView with Slivers Nested ListViews CustomScrollView(slivers: [SliverList()]) ListView inside ListView Medium https://api.flutter.dev/flutter/widgets/SliverList-class.html
20 19 Navigation Use Navigator 2.0 or GoRouter Declarative routing go_router for navigation Navigator.push for complex apps GoRouter(routes: [...]) Navigator.push everywhere Medium https://pub.dev/packages/go_router
21 20 Navigation Use named routes Organized navigation Named routes for clarity Anonymous routes Navigator.pushNamed(context '/home') Navigator.push(context MaterialPageRoute()) Low
22 21 Navigation Handle back button (PopScope) Android back behavior and predictive back (Android 14+) Use PopScope widget (WillPopScope is deprecated) Use WillPopScope PopScope(canPop: false, onPopInvoked: (didPop) => ...) WillPopScope(onWillPop: ...) High https://api.flutter.dev/flutter/widgets/PopScope-class.html
23 22 Navigation Pass typed arguments Type-safe route arguments Typed route arguments Dynamic arguments MyRoute(id: '123') arguments: {'id': '123'} Medium
24 23 Async Use FutureBuilder Async UI building FutureBuilder for async data setState for async FutureBuilder(future: fetchData()) fetchData().then((d) => setState()) Medium https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
25 24 Async Use StreamBuilder Stream UI building StreamBuilder for streams Manual stream subscription StreamBuilder(stream: myStream) stream.listen in initState Medium https://api.flutter.dev/flutter/widgets/StreamBuilder-class.html
26 25 Async Handle loading and error states Complete async UI states ConnectionState checks Only success state if (snapshot.connectionState == ConnectionState.waiting) No loading indicator High
27 26 Async Cancel subscriptions Clean up stream subscriptions Cancel in dispose Memory leaks subscription.cancel() in dispose No subscription cleanup High
28 27 Theming Use ThemeData Consistent theming ThemeData for app theme Hardcoded colors Theme.of(context).primaryColor Color(0xFF123456) everywhere Medium https://api.flutter.dev/flutter/material/ThemeData-class.html
29 28 Theming Use ColorScheme Material 3 color system ColorScheme for colors Individual color properties colorScheme: ColorScheme.fromSeed() primaryColor: Colors.blue Medium
30 29 Theming Access theme via context Dynamic theme access Theme.of(context) Static theme reference Theme.of(context).textTheme.bodyLarge TextStyle(fontSize: 16) Medium
31 30 Theming Support dark mode Respect system theme darkTheme in MaterialApp Light theme only MaterialApp(theme: light, darkTheme: dark) MaterialApp(theme: light) Medium
32 31 Animation Use implicit animations Simple animations AnimatedContainer AnimatedOpacity Explicit for simple transitions AnimatedContainer(duration: Duration()) AnimationController for fade Low https://api.flutter.dev/flutter/widgets/AnimatedContainer-class.html
33 32 Animation Use AnimationController for complex Fine-grained control AnimationController with Ticker Implicit for complex sequences AnimationController(vsync: this) AnimatedContainer for staggered Medium
34 33 Animation Dispose AnimationControllers Clean up animation resources dispose() for controllers Memory leaks controller.dispose() in dispose No controller disposal High
35 34 Animation Use Hero for transitions Shared element transitions Hero for navigation animations Manual shared element Hero(tag: 'image' child: Image()) Custom shared element animation Low https://api.flutter.dev/flutter/widgets/Hero-class.html
36 35 Forms Use Form widget Form validation Form with GlobalKey Individual validation Form(key: _formKey child: ...) TextField without Form Medium https://api.flutter.dev/flutter/widgets/Form-class.html
37 36 Forms Use TextEditingController Control text input Controller for text fields onChanged for all text final controller = TextEditingController() onChanged: (v) => setState() Medium
38 37 Forms Validate on submit Form validation flow _formKey.currentState!.validate() Skip validation if (_formKey.currentState!.validate()) Submit without validation High
39 38 Forms Dispose controllers Clean up text controllers dispose() for controllers Memory leaks controller.dispose() in dispose No controller disposal High
40 39 Performance Use const widgets Reduce rebuilds const for static widgets No const for literals const Icon(Icons.add) Icon(Icons.add) High
41 40 Performance Avoid rebuilding entire tree Minimal rebuild scope Isolate changing widgets setState on parent Consumer only around changing widget setState on root widget High
42 41 Performance Use RepaintBoundary Isolate repaints RepaintBoundary for animations Full screen repaints RepaintBoundary(child: AnimatedWidget()) Animation without boundary Medium https://api.flutter.dev/flutter/widgets/RepaintBoundary-class.html
43 42 Performance Profile with DevTools Measure before optimizing Flutter DevTools profiling Guess at performance DevTools performance tab Optimize without measuring Medium https://docs.flutter.dev/tools/devtools
44 43 Accessibility Use Semantics widget Screen reader support Semantics for accessibility Missing accessibility info Semantics(label: 'Submit button') GestureDetector without semantics High https://api.flutter.dev/flutter/widgets/Semantics-class.html
45 44 Accessibility Support large fonts MediaQuery text scaling MediaQuery.textScaleFactor Fixed font sizes style: Theme.of(context).textTheme TextStyle(fontSize: 14) High
46 45 Accessibility Test with screen readers TalkBack and VoiceOver Test accessibility regularly Skip accessibility testing Regular TalkBack testing No screen reader testing High
47 46 Testing Use widget tests Test widget behavior WidgetTester for UI tests Unit tests only testWidgets('...' (tester) async {}) Only test() for UI Medium https://docs.flutter.dev/testing
48 47 Testing Use integration tests Full app testing integration_test package Manual testing only IntegrationTestWidgetsFlutterBinding Manual E2E testing Medium
49 48 Testing Mock dependencies Isolate tests Mockito or mocktail Real dependencies in tests when(mock.method()).thenReturn() Real API calls in tests Medium
50 49 Platform Use Platform checks Platform-specific code Platform.isIOS Platform.isAndroid Same code for all platforms if (Platform.isIOS) {} Hardcoded iOS behavior Medium
51 50 Platform Use kIsWeb for web Web platform detection kIsWeb for web checks Platform for web if (kIsWeb) {} Platform.isWeb (doesn't exist) Medium
52 51 Packages Use pub.dev packages Community packages Popular maintained packages Custom implementations cached_network_image Custom image cache Medium https://pub.dev/
53 52 Packages Check package quality Quality before adding Pub points and popularity Any package without review 100+ pub points Unmaintained packages Medium

View File

@@ -0,0 +1,56 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,Animation,Use Tailwind animate utilities,Built-in animations are optimized and respect reduced-motion,Use animate-pulse animate-spin animate-ping,Custom @keyframes for simple effects,animate-pulse,@keyframes pulse {...},Medium,https://tailwindcss.com/docs/animation
2,Animation,Limit bounce animations,Continuous bounce is distracting and causes motion sickness,Use animate-bounce sparingly on CTAs only,Multiple bounce animations on page,Single CTA with animate-bounce,5+ elements with animate-bounce,High,
3,Animation,Transition duration,Use appropriate transition speeds for UI feedback,duration-150 to duration-300 for UI,duration-1000 or longer for UI elements,transition-all duration-200,transition-all duration-1000,Medium,https://tailwindcss.com/docs/transition-duration
4,Animation,Hover transitions,Add smooth transitions on hover state changes,Add transition class with hover states,Instant hover changes without transition,hover:bg-gray-100 transition-colors,hover:bg-gray-100 (no transition),Low,
5,Z-Index,Use Tailwind z-* scale,Consistent stacking context with predefined scale,z-0 z-10 z-20 z-30 z-40 z-50,Arbitrary z-index values,z-50 for modals,z-[9999],Medium,https://tailwindcss.com/docs/z-index
6,Z-Index,Fixed elements z-index,Fixed navigation and modals need explicit z-index,z-50 for nav z-40 for dropdowns,Relying on DOM order for stacking,fixed top-0 z-50,fixed top-0 (no z-index),High,
7,Z-Index,Negative z-index for backgrounds,Use negative z-index for decorative backgrounds,z-[-1] for background elements,Positive z-index for backgrounds,-z-10 for decorative,z-10 for background,Low,
8,Layout,Container max-width,Limit content width for readability,max-w-7xl mx-auto for main content,Full-width content on large screens,max-w-7xl mx-auto px-4,w-full (no max-width),Medium,https://tailwindcss.com/docs/container
9,Layout,Responsive padding,Adjust padding for different screen sizes,px-4 md:px-6 lg:px-8,Same padding all sizes,px-4 sm:px-6 lg:px-8,px-8 (same all sizes),Medium,
10,Layout,Grid gaps,Use consistent gap utilities for spacing,gap-4 gap-6 gap-8,Margins on individual items,grid gap-6,grid with mb-4 on each item,Medium,https://tailwindcss.com/docs/gap
11,Layout,Flexbox alignment,Use flex utilities for alignment,items-center justify-between,Multiple nested wrappers,flex items-center justify-between,Nested divs for alignment,Low,
12,Images,Aspect ratio,Maintain consistent image aspect ratios,aspect-video aspect-square,No aspect ratio on containers,aspect-video rounded-lg,No aspect control,Medium,https://tailwindcss.com/docs/aspect-ratio
13,Images,Object fit,Control image scaling within containers,object-cover object-contain,Stretched distorted images,object-cover w-full h-full,No object-fit,Medium,https://tailwindcss.com/docs/object-fit
14,Images,Lazy loading,Defer loading of off-screen images,loading='lazy' on images,All images eager load,<img loading='lazy'>,<img> without lazy,High,
15,Images,Responsive images,Serve appropriate image sizes,srcset and sizes attributes,Same large image all devices,srcset with multiple sizes,4000px image everywhere,High,
16,Typography,Prose plugin,Use @tailwindcss/typography for rich text,prose prose-lg for article content,Custom styles for markdown,prose prose-lg max-w-none,Custom text styling,Medium,https://tailwindcss.com/docs/typography-plugin
17,Typography,Line height,Use appropriate line height for readability,leading-relaxed for body text,Default tight line height,leading-relaxed (1.625),leading-none or leading-tight,Medium,https://tailwindcss.com/docs/line-height
18,Typography,Font size scale,Use consistent text size scale,text-sm text-base text-lg text-xl,Arbitrary font sizes,text-lg,text-[17px],Low,https://tailwindcss.com/docs/font-size
19,Typography,Text truncation,Handle long text gracefully,truncate or line-clamp-*,Overflow breaking layout,line-clamp-2,No overflow handling,Medium,https://tailwindcss.com/docs/text-overflow
20,Colors,Opacity utilities,Use color opacity utilities,bg-black/50 text-white/80,Separate opacity class,bg-black/50,bg-black opacity-50,Low,https://tailwindcss.com/docs/background-color
21,Colors,Dark mode,Support dark mode with dark: prefix,dark:bg-gray-900 dark:text-white,No dark mode support,dark:bg-gray-900,Only light theme,Medium,https://tailwindcss.com/docs/dark-mode
22,Colors,Semantic colors,Use semantic color naming in config,primary secondary danger success,Generic color names in components,bg-primary,bg-blue-500 everywhere,Medium,
23,Spacing,Consistent spacing scale,Use Tailwind spacing scale consistently,p-4 m-6 gap-8,Arbitrary pixel values,p-4 (1rem),p-[15px],Low,https://tailwindcss.com/docs/customizing-spacing
24,Spacing,Negative margins,Use sparingly for overlapping effects,-mt-4 for overlapping elements,Negative margins for layout fixing,-mt-8 for card overlap,-m-2 to fix spacing issues,Medium,
25,Spacing,Space between,Use space-y-* for vertical lists,space-y-4 on flex/grid column,Margin on each child,space-y-4,Each child has mb-4,Low,https://tailwindcss.com/docs/space
26,Forms,Focus states,Always show focus indicators,focus:ring-2 focus:ring-blue-500,Remove focus outline,focus:ring-2 focus:ring-offset-2,focus:outline-none (no replacement),High,
27,Forms,Input sizing,Consistent input dimensions,h-10 px-3 for inputs,Inconsistent input heights,h-10 w-full px-3,Various heights per input,Medium,
28,Forms,Disabled states,Clear disabled styling,disabled:opacity-50 disabled:cursor-not-allowed,No disabled indication,disabled:opacity-50,Same style as enabled,Medium,
29,Forms,Placeholder styling,Style placeholder text appropriately,placeholder:text-gray-400,Dark placeholder text,placeholder:text-gray-400,Default dark placeholder,Low,
30,Responsive,Mobile-first approach,Start with mobile styles and add breakpoints,Default mobile + md: lg: xl:,Desktop-first approach,text-sm md:text-base,text-base max-md:text-sm,Medium,https://tailwindcss.com/docs/responsive-design
31,Responsive,Breakpoint testing,Test at standard breakpoints,320 375 768 1024 1280 1536,Only test on development device,Test all breakpoints,Single device testing,High,
32,Responsive,Hidden/shown utilities,Control visibility per breakpoint,hidden md:block,Different content per breakpoint,hidden md:flex,Separate mobile/desktop components,Low,https://tailwindcss.com/docs/display
33,Buttons,Button sizing,Consistent button dimensions,px-4 py-2 or px-6 py-3,Inconsistent button sizes,px-4 py-2 text-sm,Various padding per button,Medium,
34,Buttons,Touch targets,Minimum 44px touch target on mobile,min-h-[44px] on mobile,Small buttons on mobile,min-h-[44px] min-w-[44px],h-8 w-8 on mobile,High,
35,Buttons,Loading states,Show loading feedback,disabled + spinner icon,Clickable during loading,<Button disabled><Spinner/></Button>,Button without loading state,High,
36,Buttons,Icon buttons,Accessible icon-only buttons,aria-label on icon buttons,Icon button without label,<button aria-label='Close'><XIcon/></button>,<button><XIcon/></button>,High,
37,Cards,Card structure,Consistent card styling,rounded-lg shadow-md p-6,Inconsistent card styles,rounded-2xl shadow-lg p-6,Mixed card styling,Low,
38,Cards,Card hover states,Interactive cards should have hover feedback,hover:shadow-lg transition-shadow,No hover on clickable cards,hover:shadow-xl transition-shadow,Static cards that are clickable,Medium,
39,Cards,Card spacing,Consistent internal card spacing,space-y-4 for card content,Inconsistent internal spacing,space-y-4 or p-6,Mixed mb-2 mb-4 mb-6,Low,
40,Accessibility,Screen reader text,Provide context for screen readers,sr-only for hidden labels,Missing context for icons,<span class='sr-only'>Close menu</span>,No label for icon button,High,https://tailwindcss.com/docs/screen-readers
41,Accessibility,Focus visible,Show focus only for keyboard users,focus-visible:ring-2,Focus on all interactions,focus-visible:ring-2,focus:ring-2 (shows on click too),Medium,
42,Accessibility,Reduced motion,Respect user motion preferences,motion-reduce:animate-none,Ignore motion preferences,motion-reduce:transition-none,No reduced motion support,High,https://tailwindcss.com/docs/hover-focus-and-other-states#prefers-reduced-motion
43,Performance,Configure content paths,Tailwind needs to know where classes are used,Use 'content' array in config,Use deprecated 'purge' option (v2),"content: ['./src/**/*.{js,ts,jsx,tsx}']",purge: [...],High,https://tailwindcss.com/docs/content-configuration
44,Performance,JIT mode,Use JIT for faster builds and smaller bundles,JIT enabled (default in v3),Full CSS in development,Tailwind v3 defaults,Tailwind v2 without JIT,Medium,
45,Performance,Avoid @apply bloat,Use @apply sparingly,Direct utilities in HTML,Heavy @apply usage,class='px-4 py-2 rounded',@apply px-4 py-2 rounded;,Low,https://tailwindcss.com/docs/reusing-styles
46,Plugins,Official plugins,Use official Tailwind plugins,@tailwindcss/forms typography aspect-ratio,Custom implementations,@tailwindcss/forms,Custom form reset CSS,Medium,https://tailwindcss.com/docs/plugins
47,Plugins,Custom utilities,Create utilities for repeated patterns,Custom utility in config,Repeated arbitrary values,Custom shadow utility,"shadow-[0_4px_20px_rgba(0,0,0,0.1)] everywhere",Medium,
48,Layout,Container Queries,Use @container for component-based responsiveness,Use @container and @lg: etc.,Media queries for component internals,@container @lg:grid-cols-2,@media (min-width: ...) inside component,Medium,https://github.com/tailwindlabs/tailwindcss-container-queries
49,Interactivity,Group and Peer,Style based on parent/sibling state,group-hover peer-checked,JS for simple state interactions,group-hover:text-blue-500,onMouseEnter={() => setHover(true)},Low,https://tailwindcss.com/docs/hover-focus-and-other-states#styling-based-on-parent-state
50,Customization,Arbitrary Values,Use [] for one-off values,w-[350px] for specific needs,Creating config for single use,top-[117px] (if strictly needed),style={{ top: '117px' }},Low,https://tailwindcss.com/docs/adding-custom-styles#using-arbitrary-values
51,Colors,Theme color variables,Define colors in Tailwind theme and use directly,bg-primary text-success border-cta,bg-[var(--color-primary)] text-[var(--color-success)],bg-primary,bg-[var(--color-primary)],Medium,https://tailwindcss.com/docs/customizing-colors
52,Colors,Use bg-linear-to-* for gradients,Tailwind v4 uses bg-linear-to-* syntax for gradients,bg-linear-to-r bg-linear-to-b,bg-gradient-to-* (deprecated in v4),bg-linear-to-r from-blue-500 to-purple-500,bg-gradient-to-r from-blue-500 to-purple-500,Medium,https://tailwindcss.com/docs/background-image
53,Layout,Use shrink-0 shorthand,Shorter class name for flex-shrink-0,shrink-0 shrink,flex-shrink-0 flex-shrink,shrink-0,flex-shrink-0,Low,https://tailwindcss.com/docs/flex-shrink
54,Layout,Use size-* for square dimensions,Single utility for equal width and height,size-4 size-8 size-12,Separate h-* w-* for squares,size-6,h-6 w-6,Low,https://tailwindcss.com/docs/size
55,Images,SVG explicit dimensions,Add width/height attributes to SVGs to prevent layout shift before CSS loads,<svg class='size-6' width='24' height='24'>,SVG without explicit dimensions,<svg class='size-6' width='24' height='24'>,<svg class='size-6'>,High,
1 No Category Guideline Description Do Don't Code Good Code Bad Severity Docs URL
2 1 Animation Use Tailwind animate utilities Built-in animations are optimized and respect reduced-motion Use animate-pulse animate-spin animate-ping Custom @keyframes for simple effects animate-pulse @keyframes pulse {...} Medium https://tailwindcss.com/docs/animation
3 2 Animation Limit bounce animations Continuous bounce is distracting and causes motion sickness Use animate-bounce sparingly on CTAs only Multiple bounce animations on page Single CTA with animate-bounce 5+ elements with animate-bounce High
4 3 Animation Transition duration Use appropriate transition speeds for UI feedback duration-150 to duration-300 for UI duration-1000 or longer for UI elements transition-all duration-200 transition-all duration-1000 Medium https://tailwindcss.com/docs/transition-duration
5 4 Animation Hover transitions Add smooth transitions on hover state changes Add transition class with hover states Instant hover changes without transition hover:bg-gray-100 transition-colors hover:bg-gray-100 (no transition) Low
6 5 Z-Index Use Tailwind z-* scale Consistent stacking context with predefined scale z-0 z-10 z-20 z-30 z-40 z-50 Arbitrary z-index values z-50 for modals z-[9999] Medium https://tailwindcss.com/docs/z-index
7 6 Z-Index Fixed elements z-index Fixed navigation and modals need explicit z-index z-50 for nav z-40 for dropdowns Relying on DOM order for stacking fixed top-0 z-50 fixed top-0 (no z-index) High
8 7 Z-Index Negative z-index for backgrounds Use negative z-index for decorative backgrounds z-[-1] for background elements Positive z-index for backgrounds -z-10 for decorative z-10 for background Low
9 8 Layout Container max-width Limit content width for readability max-w-7xl mx-auto for main content Full-width content on large screens max-w-7xl mx-auto px-4 w-full (no max-width) Medium https://tailwindcss.com/docs/container
10 9 Layout Responsive padding Adjust padding for different screen sizes px-4 md:px-6 lg:px-8 Same padding all sizes px-4 sm:px-6 lg:px-8 px-8 (same all sizes) Medium
11 10 Layout Grid gaps Use consistent gap utilities for spacing gap-4 gap-6 gap-8 Margins on individual items grid gap-6 grid with mb-4 on each item Medium https://tailwindcss.com/docs/gap
12 11 Layout Flexbox alignment Use flex utilities for alignment items-center justify-between Multiple nested wrappers flex items-center justify-between Nested divs for alignment Low
13 12 Images Aspect ratio Maintain consistent image aspect ratios aspect-video aspect-square No aspect ratio on containers aspect-video rounded-lg No aspect control Medium https://tailwindcss.com/docs/aspect-ratio
14 13 Images Object fit Control image scaling within containers object-cover object-contain Stretched distorted images object-cover w-full h-full No object-fit Medium https://tailwindcss.com/docs/object-fit
15 14 Images Lazy loading Defer loading of off-screen images loading='lazy' on images All images eager load <img loading='lazy'> <img> without lazy High
16 15 Images Responsive images Serve appropriate image sizes srcset and sizes attributes Same large image all devices srcset with multiple sizes 4000px image everywhere High
17 16 Typography Prose plugin Use @tailwindcss/typography for rich text prose prose-lg for article content Custom styles for markdown prose prose-lg max-w-none Custom text styling Medium https://tailwindcss.com/docs/typography-plugin
18 17 Typography Line height Use appropriate line height for readability leading-relaxed for body text Default tight line height leading-relaxed (1.625) leading-none or leading-tight Medium https://tailwindcss.com/docs/line-height
19 18 Typography Font size scale Use consistent text size scale text-sm text-base text-lg text-xl Arbitrary font sizes text-lg text-[17px] Low https://tailwindcss.com/docs/font-size
20 19 Typography Text truncation Handle long text gracefully truncate or line-clamp-* Overflow breaking layout line-clamp-2 No overflow handling Medium https://tailwindcss.com/docs/text-overflow
21 20 Colors Opacity utilities Use color opacity utilities bg-black/50 text-white/80 Separate opacity class bg-black/50 bg-black opacity-50 Low https://tailwindcss.com/docs/background-color
22 21 Colors Dark mode Support dark mode with dark: prefix dark:bg-gray-900 dark:text-white No dark mode support dark:bg-gray-900 Only light theme Medium https://tailwindcss.com/docs/dark-mode
23 22 Colors Semantic colors Use semantic color naming in config primary secondary danger success Generic color names in components bg-primary bg-blue-500 everywhere Medium
24 23 Spacing Consistent spacing scale Use Tailwind spacing scale consistently p-4 m-6 gap-8 Arbitrary pixel values p-4 (1rem) p-[15px] Low https://tailwindcss.com/docs/customizing-spacing
25 24 Spacing Negative margins Use sparingly for overlapping effects -mt-4 for overlapping elements Negative margins for layout fixing -mt-8 for card overlap -m-2 to fix spacing issues Medium
26 25 Spacing Space between Use space-y-* for vertical lists space-y-4 on flex/grid column Margin on each child space-y-4 Each child has mb-4 Low https://tailwindcss.com/docs/space
27 26 Forms Focus states Always show focus indicators focus:ring-2 focus:ring-blue-500 Remove focus outline focus:ring-2 focus:ring-offset-2 focus:outline-none (no replacement) High
28 27 Forms Input sizing Consistent input dimensions h-10 px-3 for inputs Inconsistent input heights h-10 w-full px-3 Various heights per input Medium
29 28 Forms Disabled states Clear disabled styling disabled:opacity-50 disabled:cursor-not-allowed No disabled indication disabled:opacity-50 Same style as enabled Medium
30 29 Forms Placeholder styling Style placeholder text appropriately placeholder:text-gray-400 Dark placeholder text placeholder:text-gray-400 Default dark placeholder Low
31 30 Responsive Mobile-first approach Start with mobile styles and add breakpoints Default mobile + md: lg: xl: Desktop-first approach text-sm md:text-base text-base max-md:text-sm Medium https://tailwindcss.com/docs/responsive-design
32 31 Responsive Breakpoint testing Test at standard breakpoints 320 375 768 1024 1280 1536 Only test on development device Test all breakpoints Single device testing High
33 32 Responsive Hidden/shown utilities Control visibility per breakpoint hidden md:block Different content per breakpoint hidden md:flex Separate mobile/desktop components Low https://tailwindcss.com/docs/display
34 33 Buttons Button sizing Consistent button dimensions px-4 py-2 or px-6 py-3 Inconsistent button sizes px-4 py-2 text-sm Various padding per button Medium
35 34 Buttons Touch targets Minimum 44px touch target on mobile min-h-[44px] on mobile Small buttons on mobile min-h-[44px] min-w-[44px] h-8 w-8 on mobile High
36 35 Buttons Loading states Show loading feedback disabled + spinner icon Clickable during loading <Button disabled><Spinner/></Button> Button without loading state High
37 36 Buttons Icon buttons Accessible icon-only buttons aria-label on icon buttons Icon button without label <button aria-label='Close'><XIcon/></button> <button><XIcon/></button> High
38 37 Cards Card structure Consistent card styling rounded-lg shadow-md p-6 Inconsistent card styles rounded-2xl shadow-lg p-6 Mixed card styling Low
39 38 Cards Card hover states Interactive cards should have hover feedback hover:shadow-lg transition-shadow No hover on clickable cards hover:shadow-xl transition-shadow Static cards that are clickable Medium
40 39 Cards Card spacing Consistent internal card spacing space-y-4 for card content Inconsistent internal spacing space-y-4 or p-6 Mixed mb-2 mb-4 mb-6 Low
41 40 Accessibility Screen reader text Provide context for screen readers sr-only for hidden labels Missing context for icons <span class='sr-only'>Close menu</span> No label for icon button High https://tailwindcss.com/docs/screen-readers
42 41 Accessibility Focus visible Show focus only for keyboard users focus-visible:ring-2 Focus on all interactions focus-visible:ring-2 focus:ring-2 (shows on click too) Medium
43 42 Accessibility Reduced motion Respect user motion preferences motion-reduce:animate-none Ignore motion preferences motion-reduce:transition-none No reduced motion support High https://tailwindcss.com/docs/hover-focus-and-other-states#prefers-reduced-motion
44 43 Performance Configure content paths Tailwind needs to know where classes are used Use 'content' array in config Use deprecated 'purge' option (v2) content: ['./src/**/*.{js,ts,jsx,tsx}'] purge: [...] High https://tailwindcss.com/docs/content-configuration
45 44 Performance JIT mode Use JIT for faster builds and smaller bundles JIT enabled (default in v3) Full CSS in development Tailwind v3 defaults Tailwind v2 without JIT Medium
46 45 Performance Avoid @apply bloat Use @apply sparingly Direct utilities in HTML Heavy @apply usage class='px-4 py-2 rounded' @apply px-4 py-2 rounded; Low https://tailwindcss.com/docs/reusing-styles
47 46 Plugins Official plugins Use official Tailwind plugins @tailwindcss/forms typography aspect-ratio Custom implementations @tailwindcss/forms Custom form reset CSS Medium https://tailwindcss.com/docs/plugins
48 47 Plugins Custom utilities Create utilities for repeated patterns Custom utility in config Repeated arbitrary values Custom shadow utility shadow-[0_4px_20px_rgba(0,0,0,0.1)] everywhere Medium
49 48 Layout Container Queries Use @container for component-based responsiveness Use @container and @lg: etc. Media queries for component internals @container @lg:grid-cols-2 @media (min-width: ...) inside component Medium https://github.com/tailwindlabs/tailwindcss-container-queries
50 49 Interactivity Group and Peer Style based on parent/sibling state group-hover peer-checked JS for simple state interactions group-hover:text-blue-500 onMouseEnter={() => setHover(true)} Low https://tailwindcss.com/docs/hover-focus-and-other-states#styling-based-on-parent-state
51 50 Customization Arbitrary Values Use [] for one-off values w-[350px] for specific needs Creating config for single use top-[117px] (if strictly needed) style={{ top: '117px' }} Low https://tailwindcss.com/docs/adding-custom-styles#using-arbitrary-values
52 51 Colors Theme color variables Define colors in Tailwind theme and use directly bg-primary text-success border-cta bg-[var(--color-primary)] text-[var(--color-success)] bg-primary bg-[var(--color-primary)] Medium https://tailwindcss.com/docs/customizing-colors
53 52 Colors Use bg-linear-to-* for gradients Tailwind v4 uses bg-linear-to-* syntax for gradients bg-linear-to-r bg-linear-to-b bg-gradient-to-* (deprecated in v4) bg-linear-to-r from-blue-500 to-purple-500 bg-gradient-to-r from-blue-500 to-purple-500 Medium https://tailwindcss.com/docs/background-image
54 53 Layout Use shrink-0 shorthand Shorter class name for flex-shrink-0 shrink-0 shrink flex-shrink-0 flex-shrink shrink-0 flex-shrink-0 Low https://tailwindcss.com/docs/flex-shrink
55 54 Layout Use size-* for square dimensions Single utility for equal width and height size-4 size-8 size-12 Separate h-* w-* for squares size-6 h-6 w-6 Low https://tailwindcss.com/docs/size
56 55 Images SVG explicit dimensions Add width/height attributes to SVGs to prevent layout shift before CSS loads <svg class='size-6' width='24' height='24'> SVG without explicit dimensions <svg class='size-6' width='24' height='24'> <svg class='size-6'> High

View File

@@ -0,0 +1,53 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,Composable,Pure UI composables,Composable functions should only render UI,Accept state and callbacks,Calling usecase/repo,Pure UI composable,Business logic in UI,High,https://developer.android.com/jetpack/compose/mental-model
2,Composable,Small composables,Each composable has single responsibility,Split into components,Huge composable,Reusable UI,Monolithic UI,Medium,
3,Composable,Stateless by default,Prefer stateless composables,Hoist state,Local mutable state,Stateless UI,Hidden state,High,https://developer.android.com/jetpack/compose/state#state-hoisting
4,State,Single source of truth,UI state comes from one source,StateFlow from VM,Multiple states,Unified UiState,Scattered state,High,https://developer.android.com/topic/architecture/ui-layer
5,State,Model UI State,Use sealed interface/data class,UiState.Loading,Boolean flags,Explicit state,Flag hell,High,
6,State,remember only UI state,remember for UI-only state,"Scroll, animation",Business state,Correct remember,Misuse remember,High,https://developer.android.com/jetpack/compose/state
7,State,rememberSaveable,Persist state across config,rememberSaveable,remember,State survives,State lost,High,https://developer.android.com/jetpack/compose/state#restore-ui-state
8,State,derivedStateOf,Optimize recomposition,derivedStateOf,Recompute always,Optimized,Jank,Medium,https://developer.android.com/jetpack/compose/performance
9,SideEffect,LaunchedEffect keys,Use correct keys,LaunchedEffect(id),LaunchedEffect(Unit),Scoped effect,Infinite loop,High,https://developer.android.com/jetpack/compose/side-effects
10,SideEffect,rememberUpdatedState,Avoid stale lambdas,rememberUpdatedState,Capture directly,Safe callback,Stale state,Medium,https://developer.android.com/jetpack/compose/side-effects
11,SideEffect,DisposableEffect,Clean up resources,onDispose,No cleanup,No leak,Memory leak,High,
12,Architecture,Unidirectional data flow,UI → VM → State,onEvent,Two-way binding,Predictable flow,Hard debug,High,https://developer.android.com/topic/architecture
13,Architecture,No business logic in UI,Logic belongs to VM,Collect state,Call repo,Clean UI,Fat UI,High,
14,Architecture,Expose immutable state,Expose StateFlow,asStateFlow,Mutable exposed,Safe API,State mutation,High,
15,Lifecycle,Lifecycle-aware collect,Use collectAsStateWithLifecycle,Lifecycle aware,collectAsState,No leak,Leak,High,https://developer.android.com/jetpack/compose/lifecycle
16,Navigation,Event-based navigation,VM emits navigation event,"VM: Channel + receiveAsFlow(), V: Collect with Dispatchers.Main.immediate",Nav in UI,Decoupled nav,Using State / SharedFlow for navigation -> event is replayed and navigation fires again (StateFlow),High,https://developer.android.com/jetpack/compose/navigation
17,Navigation,Typed routes,Use sealed routes,sealed class Route,String routes,Type-safe,Runtime crash,Medium,
18,Performance,Stable parameters,Prefer immutable/stable params,@Immutable,Mutable params,Stable recomposition,Extra recomposition,High,https://developer.android.com/jetpack/compose/performance
19,Performance,Use key in Lazy,Provide stable keys,key=id,No key,Stable list,Item jump,High,
20,Performance,Avoid heavy work,No heavy computation in UI,Precompute in VM,Compute in UI,Smooth UI,Jank,High,
21,Performance,Remember expensive objects,remember heavy objects,remember,Recreate each recomposition,Efficient,Wasteful,Medium,
22,Theming,Design system,Centralized theme,Material3 tokens,Hardcoded values,Consistent UI,Inconsistent,High,https://developer.android.com/jetpack/compose/themes
23,Theming,Dark mode support,Theme-based colors,colorScheme,Fixed color,Adaptive UI,Broken dark,Medium,
24,Layout,Prefer Modifier over extra layouts,Use Modifier to adjust layout instead of adding wrapper composables,Use Modifier.padding(),Wrap content with extra Box,Padding via modifier,Box just for padding,High,https://developer.android.com/jetpack/compose/modifiers
25,Layout,Avoid deep layout nesting,Deep layout trees increase measure & layout cost,Keep layout flat,Box ? Column ? Box ? Row,Flat hierarchy,Deep nested tree,High,
26,Layout,Use Row/Column for linear layout,Linear layouts are simpler and more performant,Use Row / Column,Custom layout for simple cases,Row/Column usage,Over-engineered layout,High,
27,Layout,Use Box only for overlapping content,Box should be used only when children overlap,Stack elements,Use Box as Column,Proper overlay,Misused Box,Medium,
28,Layout,Prefer LazyColumn over Column scroll,Lazy layouts are virtualized and efficient,LazyColumn,Column.verticalScroll(),Lazy list,Scrollable Column,High,https://developer.android.com/jetpack/compose/lists
29,Layout,Avoid nested scroll containers,Nested scrolling causes UX & performance issues,Single scroll container,Scroll inside scroll,One scroll per screen,Nested scroll,High,
30,Layout,Avoid fillMaxSize by default,fillMaxSize may break parent constraints,Use exact size,Fill max everywhere,Constraint-aware size,Overfilled layout,Medium,
31,Layout,Avoid intrinsic size unless necessary,Intrinsic measurement is expensive,Explicit sizing,IntrinsicSize.Min,Predictable layout,Expensive measure,High,https://developer.android.com/jetpack/compose/layout/intrinsics
32,Layout,Use Arrangement and Alignment APIs,Declare layout intent explicitly,Use Arrangement / Alignment,Manual spacing hacks,Declarative spacing,Magic spacing,High,
33,Layout,Extract reusable layout patterns,Repeated layouts should be shared,Create layout composable,Copy-paste layouts,Reusable scaffold,Duplicated layout,High,
34,Theming,No hardcoded text style,Use typography,MaterialTheme.typography,Hardcode sp,Scalable,Inconsistent,Medium,
35,Testing,Stateless UI testing,Composable easy to test,Pass state,Hidden state,Testable,Hard test,High,https://developer.android.com/jetpack/compose/testing
36,Testing,Use testTag,Stable UI selectors,Modifier.testTag,Find by text,Stable tests,Flaky tests,Medium,
37,Preview,Multiple previews,Preview multiple states,@Preview,Single preview,Better dev UX,Misleading,Low,https://developer.android.com/jetpack/compose/tooling/preview
38,DI,Inject VM via Hilt,Use hiltViewModel,@HiltViewModel,Manual VM,Clean DI,Coupling,High,https://developer.android.com/training/dependency-injection/hilt-jetpack
39,DI,No DI in UI,Inject in VM,Constructor inject,Inject composable,Proper scope,Wrong scope,High,
40,Accessibility,Content description,Accessible UI,contentDescription,Ignore a11y,Inclusive,A11y fail,Medium,https://developer.android.com/jetpack/compose/accessibility
41,Accessibility,Semantics,Use semantics API,Modifier.semantics,None,Testable a11y,Invisible,Medium,
42,Animation,Compose animation APIs,Use animate*AsState,AnimatedVisibility,Manual anim,Smooth,Jank,Medium,https://developer.android.com/jetpack/compose/animation
43,Animation,Avoid animation logic in VM,Animation is UI concern,Animate in UI,Animate in VM,Correct layering,Mixed concern,Low,
44,Modularization,Feature-based UI modules,UI per feature,:feature:ui,God module,Scalable,Tight coupling,High,https://developer.android.com/topic/modularization
45,Modularization,Public UI contracts,Expose minimal UI API,Interface/Route,Expose impl,Encapsulated,Leaky module,Medium,
46,State,Snapshot state only,Use Compose state,mutableStateOf,Custom observable,Compose aware,Buggy UI,Medium,
47,State,Avoid mutable collections,Immutable list/map,PersistentList,MutableList,Stable UI,Silent bug,High,
48,Lifecycle,RememberCoroutineScope usage,Only for UI jobs,UI coroutine,Long jobs,Scoped job,Leak,Medium,https://developer.android.com/jetpack/compose/side-effects#remembercoroutinescope
49,Interop,Interop View carefully,Use AndroidView,Isolated usage,Mix everywhere,Safe interop,Messy UI,Low,https://developer.android.com/jetpack/compose/interop
50,Interop,Avoid legacy patterns,No LiveData in UI,StateFlow,LiveData,Modern stack,Legacy debt,Medium,
51,Debug,Use layout inspector,Inspect recomposition,Tools,Blind debug,Fast debug,Guessing,Low,https://developer.android.com/studio/debug/layout-inspector
52,Debug,Enable recomposition counts,Track recomposition,Debug flags,Ignore,Performance aware,Hidden jank,Low,
1 No Category Guideline Description Do Don't Code Good Code Bad Severity Docs URL
2 1 Composable Pure UI composables Composable functions should only render UI Accept state and callbacks Calling usecase/repo Pure UI composable Business logic in UI High https://developer.android.com/jetpack/compose/mental-model
3 2 Composable Small composables Each composable has single responsibility Split into components Huge composable Reusable UI Monolithic UI Medium
4 3 Composable Stateless by default Prefer stateless composables Hoist state Local mutable state Stateless UI Hidden state High https://developer.android.com/jetpack/compose/state#state-hoisting
5 4 State Single source of truth UI state comes from one source StateFlow from VM Multiple states Unified UiState Scattered state High https://developer.android.com/topic/architecture/ui-layer
6 5 State Model UI State Use sealed interface/data class UiState.Loading Boolean flags Explicit state Flag hell High
7 6 State remember only UI state remember for UI-only state Scroll, animation Business state Correct remember Misuse remember High https://developer.android.com/jetpack/compose/state
8 7 State rememberSaveable Persist state across config rememberSaveable remember State survives State lost High https://developer.android.com/jetpack/compose/state#restore-ui-state
9 8 State derivedStateOf Optimize recomposition derivedStateOf Recompute always Optimized Jank Medium https://developer.android.com/jetpack/compose/performance
10 9 SideEffect LaunchedEffect keys Use correct keys LaunchedEffect(id) LaunchedEffect(Unit) Scoped effect Infinite loop High https://developer.android.com/jetpack/compose/side-effects
11 10 SideEffect rememberUpdatedState Avoid stale lambdas rememberUpdatedState Capture directly Safe callback Stale state Medium https://developer.android.com/jetpack/compose/side-effects
12 11 SideEffect DisposableEffect Clean up resources onDispose No cleanup No leak Memory leak High
13 12 Architecture Unidirectional data flow UI → VM → State onEvent Two-way binding Predictable flow Hard debug High https://developer.android.com/topic/architecture
14 13 Architecture No business logic in UI Logic belongs to VM Collect state Call repo Clean UI Fat UI High
15 14 Architecture Expose immutable state Expose StateFlow asStateFlow Mutable exposed Safe API State mutation High
16 15 Lifecycle Lifecycle-aware collect Use collectAsStateWithLifecycle Lifecycle aware collectAsState No leak Leak High https://developer.android.com/jetpack/compose/lifecycle
17 16 Navigation Event-based navigation VM emits navigation event VM: Channel + receiveAsFlow(), V: Collect with Dispatchers.Main.immediate Nav in UI Decoupled nav Using State / SharedFlow for navigation -> event is replayed and navigation fires again (StateFlow) High https://developer.android.com/jetpack/compose/navigation
18 17 Navigation Typed routes Use sealed routes sealed class Route String routes Type-safe Runtime crash Medium
19 18 Performance Stable parameters Prefer immutable/stable params @Immutable Mutable params Stable recomposition Extra recomposition High https://developer.android.com/jetpack/compose/performance
20 19 Performance Use key in Lazy Provide stable keys key=id No key Stable list Item jump High
21 20 Performance Avoid heavy work No heavy computation in UI Precompute in VM Compute in UI Smooth UI Jank High
22 21 Performance Remember expensive objects remember heavy objects remember Recreate each recomposition Efficient Wasteful Medium
23 22 Theming Design system Centralized theme Material3 tokens Hardcoded values Consistent UI Inconsistent High https://developer.android.com/jetpack/compose/themes
24 23 Theming Dark mode support Theme-based colors colorScheme Fixed color Adaptive UI Broken dark Medium
25 24 Layout Prefer Modifier over extra layouts Use Modifier to adjust layout instead of adding wrapper composables Use Modifier.padding() Wrap content with extra Box Padding via modifier Box just for padding High https://developer.android.com/jetpack/compose/modifiers
26 25 Layout Avoid deep layout nesting Deep layout trees increase measure & layout cost Keep layout flat Box ? Column ? Box ? Row Flat hierarchy Deep nested tree High
27 26 Layout Use Row/Column for linear layout Linear layouts are simpler and more performant Use Row / Column Custom layout for simple cases Row/Column usage Over-engineered layout High
28 27 Layout Use Box only for overlapping content Box should be used only when children overlap Stack elements Use Box as Column Proper overlay Misused Box Medium
29 28 Layout Prefer LazyColumn over Column scroll Lazy layouts are virtualized and efficient LazyColumn Column.verticalScroll() Lazy list Scrollable Column High https://developer.android.com/jetpack/compose/lists
30 29 Layout Avoid nested scroll containers Nested scrolling causes UX & performance issues Single scroll container Scroll inside scroll One scroll per screen Nested scroll High
31 30 Layout Avoid fillMaxSize by default fillMaxSize may break parent constraints Use exact size Fill max everywhere Constraint-aware size Overfilled layout Medium
32 31 Layout Avoid intrinsic size unless necessary Intrinsic measurement is expensive Explicit sizing IntrinsicSize.Min Predictable layout Expensive measure High https://developer.android.com/jetpack/compose/layout/intrinsics
33 32 Layout Use Arrangement and Alignment APIs Declare layout intent explicitly Use Arrangement / Alignment Manual spacing hacks Declarative spacing Magic spacing High
34 33 Layout Extract reusable layout patterns Repeated layouts should be shared Create layout composable Copy-paste layouts Reusable scaffold Duplicated layout High
35 34 Theming No hardcoded text style Use typography MaterialTheme.typography Hardcode sp Scalable Inconsistent Medium
36 35 Testing Stateless UI testing Composable easy to test Pass state Hidden state Testable Hard test High https://developer.android.com/jetpack/compose/testing
37 36 Testing Use testTag Stable UI selectors Modifier.testTag Find by text Stable tests Flaky tests Medium
38 37 Preview Multiple previews Preview multiple states @Preview Single preview Better dev UX Misleading Low https://developer.android.com/jetpack/compose/tooling/preview
39 38 DI Inject VM via Hilt Use hiltViewModel @HiltViewModel Manual VM Clean DI Coupling High https://developer.android.com/training/dependency-injection/hilt-jetpack
40 39 DI No DI in UI Inject in VM Constructor inject Inject composable Proper scope Wrong scope High
41 40 Accessibility Content description Accessible UI contentDescription Ignore a11y Inclusive A11y fail Medium https://developer.android.com/jetpack/compose/accessibility
42 41 Accessibility Semantics Use semantics API Modifier.semantics None Testable a11y Invisible Medium
43 42 Animation Compose animation APIs Use animate*AsState AnimatedVisibility Manual anim Smooth Jank Medium https://developer.android.com/jetpack/compose/animation
44 43 Animation Avoid animation logic in VM Animation is UI concern Animate in UI Animate in VM Correct layering Mixed concern Low
45 44 Modularization Feature-based UI modules UI per feature :feature:ui God module Scalable Tight coupling High https://developer.android.com/topic/modularization
46 45 Modularization Public UI contracts Expose minimal UI API Interface/Route Expose impl Encapsulated Leaky module Medium
47 46 State Snapshot state only Use Compose state mutableStateOf Custom observable Compose aware Buggy UI Medium
48 47 State Avoid mutable collections Immutable list/map PersistentList MutableList Stable UI Silent bug High
49 48 Lifecycle RememberCoroutineScope usage Only for UI jobs UI coroutine Long jobs Scoped job Leak Medium https://developer.android.com/jetpack/compose/side-effects#remembercoroutinescope
50 49 Interop Interop View carefully Use AndroidView Isolated usage Mix everywhere Safe interop Messy UI Low https://developer.android.com/jetpack/compose/interop
51 50 Interop Avoid legacy patterns No LiveData in UI StateFlow LiveData Modern stack Legacy debt Medium
52 51 Debug Use layout inspector Inspect recomposition Tools Blind debug Fast debug Guessing Low https://developer.android.com/studio/debug/layout-inspector
53 52 Debug Enable recomposition counts Track recomposition Debug flags Ignore Performance aware Hidden jank Low

View File

@@ -0,0 +1,53 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,Routing,Use App Router for new projects,App Router is the recommended approach in Next.js 14+,app/ directory with page.tsx,pages/ for new projects,app/dashboard/page.tsx,pages/dashboard.tsx,Medium,https://nextjs.org/docs/app
2,Routing,Use file-based routing,Create routes by adding files in app directory,page.tsx for routes layout.tsx for layouts,Manual route configuration,app/blog/[slug]/page.tsx,Custom router setup,Medium,https://nextjs.org/docs/app/building-your-application/routing
3,Routing,Colocate related files,Keep components styles tests with their routes,Component files alongside page.tsx,Separate components folder,app/dashboard/_components/,components/dashboard/,Low,
4,Routing,Use route groups for organization,Group routes without affecting URL,Parentheses for route groups,Nested folders affecting URL,(marketing)/about/page.tsx,marketing/about/page.tsx,Low,https://nextjs.org/docs/app/building-your-application/routing/route-groups
5,Routing,Handle loading states,Use loading.tsx for route loading UI,loading.tsx alongside page.tsx,Manual loading state management,app/dashboard/loading.tsx,useState for loading in page,Medium,https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming
6,Routing,Handle errors with error.tsx,Catch errors at route level,error.tsx with reset function,try/catch in every component,app/dashboard/error.tsx,try/catch in page component,High,https://nextjs.org/docs/app/building-your-application/routing/error-handling
7,Rendering,Use Server Components by default,Server Components reduce client JS bundle,Keep components server by default,Add 'use client' unnecessarily,export default function Page(),('use client') for static content,High,https://nextjs.org/docs/app/building-your-application/rendering/server-components
8,Rendering,Mark Client Components explicitly,'use client' for interactive components,Add 'use client' only when needed,Server Component with hooks/events,('use client') for onClick useState,No directive with useState,High,https://nextjs.org/docs/app/building-your-application/rendering/client-components
9,Rendering,Push Client Components down,Keep Client Components as leaf nodes,Client wrapper for interactive parts only,Mark page as Client Component,<InteractiveButton/> in Server Page,('use client') on page.tsx,High,
10,Rendering,Use streaming for better UX,Stream content with Suspense boundaries,Suspense for slow data fetches,Wait for all data before render,<Suspense><SlowComponent/></Suspense>,await allData then render,Medium,https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming
11,Rendering,Choose correct rendering strategy,SSG for static SSR for dynamic ISR for semi-static,generateStaticParams for known paths,SSR for static content,export const revalidate = 3600,fetch without cache config,Medium,
12,DataFetching,Fetch data in Server Components,Fetch directly in async Server Components,async function Page() { const data = await fetch() },useEffect for initial data,const data = await fetch(url),useEffect(() => fetch(url)),High,https://nextjs.org/docs/app/building-your-application/data-fetching
13,DataFetching,Configure caching explicitly (Next.js 15+),Next.js 15 changed defaults to uncached for fetch,Explicitly set cache: 'force-cache' for static data,Assume default is cached (it's not in Next.js 15),fetch(url { cache: 'force-cache' }),fetch(url) // Uncached in v15,High,https://nextjs.org/docs/app/building-your-application/upgrading/version-15
14,DataFetching,Deduplicate fetch requests,React and Next.js dedupe same requests,Same fetch call in multiple components,Manual request deduplication,Multiple components fetch same URL,Custom cache layer,Low,
15,DataFetching,Use Server Actions for mutations,Server Actions for form submissions,action={serverAction} in forms,API route for every mutation,<form action={createPost}>,<form onSubmit={callApiRoute}>,Medium,https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations
16,DataFetching,Revalidate data appropriately,Use revalidatePath/revalidateTag after mutations,Revalidate after Server Action,'use client' with manual refetch,revalidatePath('/posts'),router.refresh() everywhere,Medium,https://nextjs.org/docs/app/building-your-application/caching#revalidating
17,Images,Use next/image for optimization,Automatic image optimization and lazy loading,<Image> component for all images,<img> tags directly,<Image src={} alt={} width={} height={}>,<img src={}/>,High,https://nextjs.org/docs/app/building-your-application/optimizing/images
18,Images,Provide width and height,Prevent layout shift with dimensions,width and height props or fill,Missing dimensions,<Image width={400} height={300}/>,<Image src={url}/>,High,
19,Images,Use fill for responsive images,Fill container with object-fit,fill prop with relative parent,Fixed dimensions for responsive,"<Image fill className=""object-cover""/>",<Image width={window.width}/>,Medium,
20,Images,Configure remote image domains,Whitelist external image sources,remotePatterns in next.config.js,Allow all domains,remotePatterns: [{ hostname: 'cdn.example.com' }],domains: ['*'],High,https://nextjs.org/docs/app/api-reference/components/image#remotepatterns
21,Images,Use priority for LCP images,Mark above-fold images as priority,priority prop on hero images,All images with priority,<Image priority src={hero}/>,<Image priority/> on every image,Medium,
22,Fonts,Use next/font for fonts,Self-hosted fonts with zero layout shift,next/font/google or next/font/local,External font links,import { Inter } from 'next/font/google',"<link href=""fonts.googleapis.com""/>",Medium,https://nextjs.org/docs/app/building-your-application/optimizing/fonts
23,Fonts,Apply font to layout,Set font in root layout for consistency,className on body in layout.tsx,Font in individual pages,<body className={inter.className}>,Each page imports font,Low,
24,Fonts,Use variable fonts,Variable fonts reduce bundle size,Single variable font file,Multiple font weights as files,Inter({ subsets: ['latin'] }),Inter_400 Inter_500 Inter_700,Low,
25,Metadata,Use generateMetadata for dynamic,Generate metadata based on params,export async function generateMetadata(),Hardcoded metadata everywhere,generateMetadata({ params }),export const metadata = {},Medium,https://nextjs.org/docs/app/building-your-application/optimizing/metadata
26,Metadata,Include OpenGraph images,Add OG images for social sharing,opengraph-image.tsx or og property,Missing social preview images,opengraph: { images: ['/og.png'] },No OG configuration,Medium,
27,Metadata,Use metadata API,Export metadata object for static metadata,export const metadata = {},Manual head tags,export const metadata = { title: 'Page' },<head><title>Page</title></head>,Medium,
28,API,Use Route Handlers for APIs,app/api routes for API endpoints,app/api/users/route.ts,pages/api for new projects,export async function GET(request),export default function handler,Medium,https://nextjs.org/docs/app/building-your-application/routing/route-handlers
29,API,Return proper Response objects,Use NextResponse for API responses,NextResponse.json() for JSON,Plain objects or res.json(),return NextResponse.json({ data }),return { data },Medium,
30,API,Handle HTTP methods explicitly,Export named functions for methods,Export GET POST PUT DELETE,Single handler for all methods,export async function POST(),switch(req.method),Low,
31,API,Validate request body,Validate input before processing,Zod or similar for validation,Trust client input,const body = schema.parse(await req.json()),const body = await req.json(),High,
32,Middleware,Use middleware for auth,Protect routes with middleware.ts,middleware.ts at root,Auth check in every page,export function middleware(request),if (!session) redirect in page,Medium,https://nextjs.org/docs/app/building-your-application/routing/middleware
33,Middleware,Match specific paths,Configure middleware matcher,config.matcher for specific routes,Run middleware on all routes,matcher: ['/dashboard/:path*'],No matcher config,Medium,
34,Middleware,Keep middleware edge-compatible,Middleware runs on Edge runtime,Edge-compatible code only,Node.js APIs in middleware,Edge-compatible auth check,fs.readFile in middleware,High,
35,Environment,Use NEXT_PUBLIC prefix,Client-accessible env vars need prefix,NEXT_PUBLIC_ for client vars,Server vars exposed to client,NEXT_PUBLIC_API_URL,API_SECRET in client code,High,https://nextjs.org/docs/app/building-your-application/configuring/environment-variables
36,Environment,Validate env vars,Check required env vars exist,Validate on startup,Undefined env at runtime,if (!process.env.DATABASE_URL) throw,process.env.DATABASE_URL (might be undefined),High,
37,Environment,Use .env.local for secrets,Local env file for development secrets,.env.local gitignored,Secrets in .env committed,.env.local with secrets,.env with DATABASE_PASSWORD,High,
38,Performance,Analyze bundle size,Use @next/bundle-analyzer,Bundle analyzer in dev,Ship large bundles blindly,ANALYZE=true npm run build,No bundle analysis,Medium,https://nextjs.org/docs/app/building-your-application/optimizing/bundle-analyzer
39,Performance,Use dynamic imports,Code split with next/dynamic,dynamic() for heavy components,Import everything statically,const Chart = dynamic(() => import('./Chart')),import Chart from './Chart',Medium,https://nextjs.org/docs/app/building-your-application/optimizing/lazy-loading
40,Performance,Avoid layout shifts,Reserve space for dynamic content,Skeleton loaders aspect ratios,Content popping in,"<Skeleton className=""h-48""/>",No placeholder for async content,High,
41,Performance,Use Partial Prerendering,Combine static and dynamic in one route,Static shell with Suspense holes,Full dynamic or static pages,Static header + dynamic content,Entire page SSR,Low,https://nextjs.org/docs/app/building-your-application/rendering/partial-prerendering
42,Link,Use next/link for navigation,Client-side navigation with prefetching,"<Link href=""""> for internal links",<a> for internal navigation,"<Link href=""/about"">About</Link>","<a href=""/about"">About</a>",High,https://nextjs.org/docs/app/api-reference/components/link
43,Link,Prefetch strategically,Control prefetching behavior,prefetch={false} for low-priority,Prefetch all links,<Link prefetch={false}>,Default prefetch on every link,Low,
44,Link,Use scroll option appropriately,Control scroll behavior on navigation,scroll={false} for tabs pagination,Always scroll to top,<Link scroll={false}>,Manual scroll management,Low,
45,Config,Use next.config.js correctly,Configure Next.js behavior,Proper config options,Deprecated or wrong options,images: { remotePatterns: [] },images: { domains: [] },Medium,https://nextjs.org/docs/app/api-reference/next-config-js
46,Config,Enable strict mode,Catch potential issues early,reactStrictMode: true,Strict mode disabled,reactStrictMode: true,reactStrictMode: false,Medium,
47,Config,Configure redirects and rewrites,Use config for URL management,redirects() rewrites() in config,Manual redirect handling,redirects: async () => [...],res.redirect in pages,Medium,https://nextjs.org/docs/app/api-reference/next-config-js/redirects
48,Deployment,Use Vercel for easiest deploy,Vercel optimized for Next.js,Deploy to Vercel,Self-host without knowledge,vercel deploy,Complex Docker setup for simple app,Low,https://nextjs.org/docs/app/building-your-application/deploying
49,Deployment,Configure output for self-hosting,Set output option for deployment target,output: 'standalone' for Docker,Default output for containers,output: 'standalone',No output config for Docker,Medium,https://nextjs.org/docs/app/building-your-application/deploying#self-hosting
50,Security,Sanitize user input,Never trust user input,Escape sanitize validate all input,Direct interpolation of user data,DOMPurify.sanitize(userInput),dangerouslySetInnerHTML={{ __html: userInput }},High,
51,Security,Use CSP headers,Content Security Policy for XSS protection,Configure CSP in next.config.js,No security headers,headers() with CSP,No CSP configuration,High,https://nextjs.org/docs/app/building-your-application/configuring/content-security-policy
52,Security,Validate Server Action input,Server Actions are public endpoints,Validate and authorize in Server Action,Trust Server Action input,Auth check + validation in action,Direct database call without check,High,
1 No Category Guideline Description Do Don't Code Good Code Bad Severity Docs URL
2 1 Routing Use App Router for new projects App Router is the recommended approach in Next.js 14+ app/ directory with page.tsx pages/ for new projects app/dashboard/page.tsx pages/dashboard.tsx Medium https://nextjs.org/docs/app
3 2 Routing Use file-based routing Create routes by adding files in app directory page.tsx for routes layout.tsx for layouts Manual route configuration app/blog/[slug]/page.tsx Custom router setup Medium https://nextjs.org/docs/app/building-your-application/routing
4 3 Routing Colocate related files Keep components styles tests with their routes Component files alongside page.tsx Separate components folder app/dashboard/_components/ components/dashboard/ Low
5 4 Routing Use route groups for organization Group routes without affecting URL Parentheses for route groups Nested folders affecting URL (marketing)/about/page.tsx marketing/about/page.tsx Low https://nextjs.org/docs/app/building-your-application/routing/route-groups
6 5 Routing Handle loading states Use loading.tsx for route loading UI loading.tsx alongside page.tsx Manual loading state management app/dashboard/loading.tsx useState for loading in page Medium https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming
7 6 Routing Handle errors with error.tsx Catch errors at route level error.tsx with reset function try/catch in every component app/dashboard/error.tsx try/catch in page component High https://nextjs.org/docs/app/building-your-application/routing/error-handling
8 7 Rendering Use Server Components by default Server Components reduce client JS bundle Keep components server by default Add 'use client' unnecessarily export default function Page() ('use client') for static content High https://nextjs.org/docs/app/building-your-application/rendering/server-components
9 8 Rendering Mark Client Components explicitly 'use client' for interactive components Add 'use client' only when needed Server Component with hooks/events ('use client') for onClick useState No directive with useState High https://nextjs.org/docs/app/building-your-application/rendering/client-components
10 9 Rendering Push Client Components down Keep Client Components as leaf nodes Client wrapper for interactive parts only Mark page as Client Component <InteractiveButton/> in Server Page ('use client') on page.tsx High
11 10 Rendering Use streaming for better UX Stream content with Suspense boundaries Suspense for slow data fetches Wait for all data before render <Suspense><SlowComponent/></Suspense> await allData then render Medium https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming
12 11 Rendering Choose correct rendering strategy SSG for static SSR for dynamic ISR for semi-static generateStaticParams for known paths SSR for static content export const revalidate = 3600 fetch without cache config Medium
13 12 DataFetching Fetch data in Server Components Fetch directly in async Server Components async function Page() { const data = await fetch() } useEffect for initial data const data = await fetch(url) useEffect(() => fetch(url)) High https://nextjs.org/docs/app/building-your-application/data-fetching
14 13 DataFetching Configure caching explicitly (Next.js 15+) Next.js 15 changed defaults to uncached for fetch Explicitly set cache: 'force-cache' for static data Assume default is cached (it's not in Next.js 15) fetch(url { cache: 'force-cache' }) fetch(url) // Uncached in v15 High https://nextjs.org/docs/app/building-your-application/upgrading/version-15
15 14 DataFetching Deduplicate fetch requests React and Next.js dedupe same requests Same fetch call in multiple components Manual request deduplication Multiple components fetch same URL Custom cache layer Low
16 15 DataFetching Use Server Actions for mutations Server Actions for form submissions action={serverAction} in forms API route for every mutation <form action={createPost}> <form onSubmit={callApiRoute}> Medium https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations
17 16 DataFetching Revalidate data appropriately Use revalidatePath/revalidateTag after mutations Revalidate after Server Action 'use client' with manual refetch revalidatePath('/posts') router.refresh() everywhere Medium https://nextjs.org/docs/app/building-your-application/caching#revalidating
18 17 Images Use next/image for optimization Automatic image optimization and lazy loading <Image> component for all images <img> tags directly <Image src={} alt={} width={} height={}> <img src={}/> High https://nextjs.org/docs/app/building-your-application/optimizing/images
19 18 Images Provide width and height Prevent layout shift with dimensions width and height props or fill Missing dimensions <Image width={400} height={300}/> <Image src={url}/> High
20 19 Images Use fill for responsive images Fill container with object-fit fill prop with relative parent Fixed dimensions for responsive <Image fill className="object-cover"/> <Image width={window.width}/> Medium
21 20 Images Configure remote image domains Whitelist external image sources remotePatterns in next.config.js Allow all domains remotePatterns: [{ hostname: 'cdn.example.com' }] domains: ['*'] High https://nextjs.org/docs/app/api-reference/components/image#remotepatterns
22 21 Images Use priority for LCP images Mark above-fold images as priority priority prop on hero images All images with priority <Image priority src={hero}/> <Image priority/> on every image Medium
23 22 Fonts Use next/font for fonts Self-hosted fonts with zero layout shift next/font/google or next/font/local External font links import { Inter } from 'next/font/google' <link href="fonts.googleapis.com"/> Medium https://nextjs.org/docs/app/building-your-application/optimizing/fonts
24 23 Fonts Apply font to layout Set font in root layout for consistency className on body in layout.tsx Font in individual pages <body className={inter.className}> Each page imports font Low
25 24 Fonts Use variable fonts Variable fonts reduce bundle size Single variable font file Multiple font weights as files Inter({ subsets: ['latin'] }) Inter_400 Inter_500 Inter_700 Low
26 25 Metadata Use generateMetadata for dynamic Generate metadata based on params export async function generateMetadata() Hardcoded metadata everywhere generateMetadata({ params }) export const metadata = {} Medium https://nextjs.org/docs/app/building-your-application/optimizing/metadata
27 26 Metadata Include OpenGraph images Add OG images for social sharing opengraph-image.tsx or og property Missing social preview images opengraph: { images: ['/og.png'] } No OG configuration Medium
28 27 Metadata Use metadata API Export metadata object for static metadata export const metadata = {} Manual head tags export const metadata = { title: 'Page' } <head><title>Page</title></head> Medium
29 28 API Use Route Handlers for APIs app/api routes for API endpoints app/api/users/route.ts pages/api for new projects export async function GET(request) export default function handler Medium https://nextjs.org/docs/app/building-your-application/routing/route-handlers
30 29 API Return proper Response objects Use NextResponse for API responses NextResponse.json() for JSON Plain objects or res.json() return NextResponse.json({ data }) return { data } Medium
31 30 API Handle HTTP methods explicitly Export named functions for methods Export GET POST PUT DELETE Single handler for all methods export async function POST() switch(req.method) Low
32 31 API Validate request body Validate input before processing Zod or similar for validation Trust client input const body = schema.parse(await req.json()) const body = await req.json() High
33 32 Middleware Use middleware for auth Protect routes with middleware.ts middleware.ts at root Auth check in every page export function middleware(request) if (!session) redirect in page Medium https://nextjs.org/docs/app/building-your-application/routing/middleware
34 33 Middleware Match specific paths Configure middleware matcher config.matcher for specific routes Run middleware on all routes matcher: ['/dashboard/:path*'] No matcher config Medium
35 34 Middleware Keep middleware edge-compatible Middleware runs on Edge runtime Edge-compatible code only Node.js APIs in middleware Edge-compatible auth check fs.readFile in middleware High
36 35 Environment Use NEXT_PUBLIC prefix Client-accessible env vars need prefix NEXT_PUBLIC_ for client vars Server vars exposed to client NEXT_PUBLIC_API_URL API_SECRET in client code High https://nextjs.org/docs/app/building-your-application/configuring/environment-variables
37 36 Environment Validate env vars Check required env vars exist Validate on startup Undefined env at runtime if (!process.env.DATABASE_URL) throw process.env.DATABASE_URL (might be undefined) High
38 37 Environment Use .env.local for secrets Local env file for development secrets .env.local gitignored Secrets in .env committed .env.local with secrets .env with DATABASE_PASSWORD High
39 38 Performance Analyze bundle size Use @next/bundle-analyzer Bundle analyzer in dev Ship large bundles blindly ANALYZE=true npm run build No bundle analysis Medium https://nextjs.org/docs/app/building-your-application/optimizing/bundle-analyzer
40 39 Performance Use dynamic imports Code split with next/dynamic dynamic() for heavy components Import everything statically const Chart = dynamic(() => import('./Chart')) import Chart from './Chart' Medium https://nextjs.org/docs/app/building-your-application/optimizing/lazy-loading
41 40 Performance Avoid layout shifts Reserve space for dynamic content Skeleton loaders aspect ratios Content popping in <Skeleton className="h-48"/> No placeholder for async content High
42 41 Performance Use Partial Prerendering Combine static and dynamic in one route Static shell with Suspense holes Full dynamic or static pages Static header + dynamic content Entire page SSR Low https://nextjs.org/docs/app/building-your-application/rendering/partial-prerendering
43 42 Link Use next/link for navigation Client-side navigation with prefetching <Link href=""> for internal links <a> for internal navigation <Link href="/about">About</Link> <a href="/about">About</a> High https://nextjs.org/docs/app/api-reference/components/link
44 43 Link Prefetch strategically Control prefetching behavior prefetch={false} for low-priority Prefetch all links <Link prefetch={false}> Default prefetch on every link Low
45 44 Link Use scroll option appropriately Control scroll behavior on navigation scroll={false} for tabs pagination Always scroll to top <Link scroll={false}> Manual scroll management Low
46 45 Config Use next.config.js correctly Configure Next.js behavior Proper config options Deprecated or wrong options images: { remotePatterns: [] } images: { domains: [] } Medium https://nextjs.org/docs/app/api-reference/next-config-js
47 46 Config Enable strict mode Catch potential issues early reactStrictMode: true Strict mode disabled reactStrictMode: true reactStrictMode: false Medium
48 47 Config Configure redirects and rewrites Use config for URL management redirects() rewrites() in config Manual redirect handling redirects: async () => [...] res.redirect in pages Medium https://nextjs.org/docs/app/api-reference/next-config-js/redirects
49 48 Deployment Use Vercel for easiest deploy Vercel optimized for Next.js Deploy to Vercel Self-host without knowledge vercel deploy Complex Docker setup for simple app Low https://nextjs.org/docs/app/building-your-application/deploying
50 49 Deployment Configure output for self-hosting Set output option for deployment target output: 'standalone' for Docker Default output for containers output: 'standalone' No output config for Docker Medium https://nextjs.org/docs/app/building-your-application/deploying#self-hosting
51 50 Security Sanitize user input Never trust user input Escape sanitize validate all input Direct interpolation of user data DOMPurify.sanitize(userInput) dangerouslySetInnerHTML={{ __html: userInput }} High
52 51 Security Use CSP headers Content Security Policy for XSS protection Configure CSP in next.config.js No security headers headers() with CSP No CSP configuration High https://nextjs.org/docs/app/building-your-application/configuring/content-security-policy
53 52 Security Validate Server Action input Server Actions are public endpoints Validate and authorize in Server Action Trust Server Action input Auth check + validation in action Direct database call without check High

View File

@@ -0,0 +1,51 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,Installation,Add Nuxt UI module,Install and configure Nuxt UI in your Nuxt project,pnpm add @nuxt/ui and add to modules,Manual component imports,"modules: ['@nuxt/ui']","import { UButton } from '@nuxt/ui'",High,https://ui.nuxt.com/docs/getting-started/installation/nuxt
2,Installation,Import Tailwind and Nuxt UI CSS,Required CSS imports in main.css file,@import tailwindcss and @import @nuxt/ui,Skip CSS imports,"@import ""tailwindcss""; @import ""@nuxt/ui"";",No CSS imports,High,https://ui.nuxt.com/docs/getting-started/installation/nuxt
3,Installation,Wrap app with UApp component,UApp provides global configs for Toast Tooltip and overlays,<UApp> wrapper in app.vue,Skip UApp wrapper,<UApp><NuxtPage/></UApp>,<NuxtPage/> without wrapper,High,https://ui.nuxt.com/docs/components/app
4,Components,Use U prefix for components,All Nuxt UI components use U prefix by default,UButton UInput UModal,Button Input Modal,<UButton>Click</UButton>,<Button>Click</Button>,Medium,https://ui.nuxt.com/docs/getting-started/installation/nuxt
5,Components,Use semantic color props,Use semantic colors like primary secondary error,color="primary" color="error",Hardcoded colors,"<UButton color=""primary"">","<UButton class=""bg-green-500"">",Medium,https://ui.nuxt.com/docs/getting-started/theme/design-system
6,Components,Use variant prop for styling,Nuxt UI provides solid outline soft subtle ghost link variants,variant="soft" variant="outline",Custom button classes,"<UButton variant=""soft"">","<UButton class=""border bg-transparent"">",Medium,https://ui.nuxt.com/docs/components/button
7,Components,Use size prop consistently,Components support xs sm md lg xl sizes,size="sm" size="lg",Arbitrary sizing classes,"<UButton size=""lg"">","<UButton class=""text-xl px-6"">",Low,https://ui.nuxt.com/docs/components/button
8,Icons,Use icon prop with Iconify format,Nuxt UI supports Iconify icons via icon prop,icon="lucide:home" icon="heroicons:user",i-lucide-home format,"<UButton icon=""lucide:home"">","<UButton icon=""i-lucide-home"">",Medium,https://ui.nuxt.com/docs/getting-started/integrations/icons/nuxt
9,Icons,Use leadingIcon and trailingIcon,Position icons with dedicated props for clarity,leadingIcon="lucide:plus" trailingIcon="lucide:arrow-right",Manual icon positioning,"<UButton leadingIcon=""lucide:plus"">","<UButton><Icon name=""lucide:plus""/>Add</UButton>",Low,https://ui.nuxt.com/docs/components/button
10,Theming,Configure colors in app.config.ts,Runtime color configuration without restart,ui.colors.primary in app.config.ts,Hardcoded colors in components,"defineAppConfig({ ui: { colors: { primary: 'blue' } } })","<UButton class=""bg-blue-500"">",High,https://ui.nuxt.com/docs/getting-started/theme/design-system
11,Theming,Use @theme directive for custom colors,Define design tokens in CSS with Tailwind @theme,@theme { --color-brand-500: #xxx },Inline color definitions,@theme { --color-brand-500: #ef4444; },:style="{ color: '#ef4444' }",Medium,https://ui.nuxt.com/docs/getting-started/theme/design-system
12,Theming,Extend semantic colors in nuxt.config,Register new colors like tertiary in theme.colors,theme.colors array in ui config,Use undefined colors,"ui: { theme: { colors: ['primary', 'tertiary'] } }","<UButton color=""tertiary""> without config",Medium,https://ui.nuxt.com/docs/getting-started/theme/design-system
13,Forms,Use UForm with schema validation,UForm supports Zod Yup Joi Valibot schemas,:schema prop with validation schema,Manual form validation,"<UForm :schema=""schema"" :state=""state"">",Manual @blur validation,High,https://ui.nuxt.com/docs/components/form
14,Forms,Use UFormField for field wrapper,Provides label error message and validation display,UFormField with name prop,Manual error handling,"<UFormField name=""email"" label=""Email"">",<div><label>Email</label><UInput/><span>error</span></div>,Medium,https://ui.nuxt.com/docs/components/form-field
15,Forms,Handle form submit with @submit,UForm emits submit event with validated data,@submit handler on UForm,@click on submit button,"<UForm @submit=""onSubmit"">","<UButton @click=""onSubmit"">",Medium,https://ui.nuxt.com/docs/components/form
16,Forms,Use validateOn prop for validation timing,Control when validation triggers (blur change input),validateOn="['blur']" for performance,Always validate on input,"<UForm :validateOn=""['blur', 'change']"">","<UForm> (validates on every keystroke)",Low,https://ui.nuxt.com/docs/components/form
17,Overlays,Use v-model:open for overlay control,Modal Slideover Drawer use v-model:open,v-model:open for controlled state,Manual show/hide logic,"<UModal v-model:open=""isOpen"">",<UModal v-if="isOpen">,Medium,https://ui.nuxt.com/docs/components/modal
18,Overlays,Use useOverlay composable for programmatic overlays,Open overlays programmatically without template refs,useOverlay().open(MyModal),Template ref and manual control,"const overlay = useOverlay(); overlay.open(MyModal, { props })","const modal = ref(); modal.value.open()",Medium,https://ui.nuxt.com/docs/components/modal
19,Overlays,Use title and description props,Built-in header support for overlays,title="Confirm" description="Are you sure?",Manual header content,"<UModal title=""Confirm"" description=""Are you sure?"">","<UModal><template #header><h2>Confirm</h2></template>",Low,https://ui.nuxt.com/docs/components/modal
20,Dashboard,Use UDashboardSidebar for navigation,Provides collapsible resizable sidebar with mobile support,UDashboardSidebar with header default footer slots,Custom sidebar implementation,<UDashboardSidebar><template #header>...</template></UDashboardSidebar>,<aside class="w-64 border-r">,Medium,https://ui.nuxt.com/docs/components/dashboard-sidebar
21,Dashboard,Use UDashboardGroup for layout,Wraps dashboard components with sidebar state management,UDashboardGroup > UDashboardSidebar + UDashboardPanel,Manual layout flex containers,<UDashboardGroup><UDashboardSidebar/><UDashboardPanel/></UDashboardGroup>,"<div class=""flex""><aside/><main/></div>",Medium,https://ui.nuxt.com/docs/components/dashboard-group
22,Dashboard,Use UDashboardNavbar for top navigation,Responsive navbar with mobile menu support,UDashboardNavbar in dashboard layout,Custom navbar implementation,<UDashboardNavbar :links="navLinks"/>,<nav class="border-b">,Low,https://ui.nuxt.com/docs/components/dashboard-navbar
23,Tables,Use UTable with data and columns props,Powered by TanStack Table with built-in features,:data and :columns props,Manual table markup,"<UTable :data=""users"" :columns=""columns""/>","<table><tr v-for=""user in users"">",High,https://ui.nuxt.com/docs/components/table
24,Tables,Define columns with accessorKey,Column definitions use accessorKey for data binding,accessorKey: 'email' in column def,String column names only,"{ accessorKey: 'email', header: 'Email' }","['name', 'email']",Medium,https://ui.nuxt.com/docs/components/table
25,Tables,Use cell slot for custom rendering,Customize cell content with scoped slots,#cell-columnName slot,Override entire table,<template #cell-status="{ row }">,Manual column render function,Medium,https://ui.nuxt.com/docs/components/table
26,Tables,Enable sorting with sortable column option,Add sortable: true to column definition,sortable: true in column,Manual sort implementation,"{ accessorKey: 'name', sortable: true }",@click="sortBy('name')",Low,https://ui.nuxt.com/docs/components/table
27,Navigation,Use UNavigationMenu for nav links,Horizontal or vertical navigation with dropdown support,UNavigationMenu with items array,Manual nav with v-for,"<UNavigationMenu :items=""navItems""/>","<nav><a v-for=""item in items"">",Medium,https://ui.nuxt.com/docs/components/navigation-menu
28,Navigation,Use UBreadcrumb for page hierarchy,Automatic breadcrumb with NuxtLink support,:items array with label and to,Manual breadcrumb links,"<UBreadcrumb :items=""breadcrumbs""/>","<nav><span v-for=""crumb in crumbs"">",Low,https://ui.nuxt.com/docs/components/breadcrumb
29,Navigation,Use UTabs for tabbed content,Tab navigation with content panels,UTabs with items containing slot content,Manual tab state,"<UTabs :items=""tabs""/>","<div><button @click=""tab=1"">",Medium,https://ui.nuxt.com/docs/components/tabs
30,Feedback,Use useToast for notifications,Composable for toast notifications,useToast().add({ title description }),Alert components for toasts,"const toast = useToast(); toast.add({ title: 'Saved' })",<UAlert v-if="showSuccess">,High,https://ui.nuxt.com/docs/components/toast
31,Feedback,Use UAlert for inline messages,Static alert messages with icon and actions,UAlert with title description color,Toast for static messages,"<UAlert title=""Warning"" color=""warning""/>",useToast for inline alerts,Medium,https://ui.nuxt.com/docs/components/alert
32,Feedback,Use USkeleton for loading states,Placeholder content during data loading,USkeleton with appropriate size,Spinner for content loading,<USkeleton class="h-4 w-32"/>,<UIcon name="lucide:loader" class="animate-spin"/>,Low,https://ui.nuxt.com/docs/components/skeleton
33,Color Mode,Use UColorModeButton for theme toggle,Built-in light/dark mode toggle button,UColorModeButton component,Manual color mode logic,<UColorModeButton/>,"<button @click=""toggleColorMode"">",Low,https://ui.nuxt.com/docs/components/color-mode-button
34,Color Mode,Use UColorModeSelect for theme picker,Dropdown to select system light or dark mode,UColorModeSelect component,Custom select for theme,<UColorModeSelect/>,"<USelect v-model=""colorMode"" :items=""modes""/>",Low,https://ui.nuxt.com/docs/components/color-mode-select
35,Customization,Use ui prop for component styling,Override component styles via ui prop,ui prop with slot class overrides,Global CSS overrides,"<UButton :ui=""{ base: 'rounded-full' }""/>",<UButton class="!rounded-full"/>,Medium,https://ui.nuxt.com/docs/getting-started/theme/components
36,Customization,Configure default variants in nuxt.config,Set default color and size for all components,theme.defaultVariants in ui config,Repeat props on every component,"ui: { theme: { defaultVariants: { color: 'neutral' } } }","<UButton color=""neutral""> everywhere",Medium,https://ui.nuxt.com/docs/getting-started/installation/nuxt
37,Customization,Use app.config.ts for theme overrides,Runtime theme customization,defineAppConfig with ui key,nuxt.config for runtime values,"defineAppConfig({ ui: { button: { defaultVariants: { size: 'sm' } } } })","nuxt.config ui.button.size: 'sm'",Medium,https://ui.nuxt.com/docs/getting-started/theme/components
38,Performance,Enable component detection,Tree-shake unused component CSS,experimental.componentDetection: true,Include all component CSS,"ui: { experimental: { componentDetection: true } }","ui: {} (includes all CSS)",Low,https://ui.nuxt.com/docs/getting-started/installation/nuxt
39,Performance,Use UTable virtualize for large data,Enable virtualization for 1000+ rows,:virtualize prop on UTable,Render all rows,"<UTable :data=""largeData"" virtualize/>","<UTable :data=""largeData""/>",Medium,https://ui.nuxt.com/docs/components/table
40,Accessibility,Use semantic component props,Components have built-in ARIA support,Use title description label props,Skip accessibility props,"<UModal title=""Settings"">","<UModal><h2>Settings</h2>",Medium,https://ui.nuxt.com/docs/components/modal
41,Accessibility,Use UFormField for form accessibility,Automatic label-input association,UFormField wraps inputs,Manual id and for attributes,"<UFormField label=""Email""><UInput/></UFormField>","<label for=""email"">Email</label><UInput id=""email""/>",High,https://ui.nuxt.com/docs/components/form-field
42,Content,Use UContentToc for table of contents,Automatic TOC with active heading highlight,UContentToc with :links,Manual TOC implementation,"<UContentToc :links=""toc""/>","<nav><a v-for=""heading in headings"">",Low,https://ui.nuxt.com/docs/components/content-toc
43,Content,Use UContentSearch for docs search,Command palette for documentation search,UContentSearch with Nuxt Content,Custom search implementation,<UContentSearch/>,<UCommandPalette :groups="searchResults"/>,Low,https://ui.nuxt.com/docs/components/content-search
44,AI/Chat,Use UChatMessages for chat UI,Designed for Vercel AI SDK integration,UChatMessages with messages array,Custom chat message list,"<UChatMessages :messages=""messages""/>","<div v-for=""msg in messages"">",Medium,https://ui.nuxt.com/docs/components/chat-messages
45,AI/Chat,Use UChatPrompt for input,Enhanced textarea for AI prompts,UChatPrompt with v-model,Basic textarea,<UChatPrompt v-model="prompt"/>,<UTextarea v-model="prompt"/>,Medium,https://ui.nuxt.com/docs/components/chat-prompt
46,Editor,Use UEditor for rich text,TipTap-based editor with toolbar support,UEditor with v-model:content,Custom TipTap setup,"<UEditor v-model:content=""content""/>",Manual TipTap initialization,Medium,https://ui.nuxt.com/docs/components/editor
47,Links,Use to prop for navigation,UButton and ULink support NuxtLink to prop,to="/dashboard" for internal links,href for internal navigation,"<UButton to=""/dashboard"">","<UButton href=""/dashboard"">",Medium,https://ui.nuxt.com/docs/components/button
48,Links,Use external prop for outside links,Explicitly mark external links,target="_blank" with external URLs,Forget rel="noopener","<UButton to=""https://example.com"" target=""_blank"">","<UButton href=""https://..."">",Low,https://ui.nuxt.com/docs/components/link
49,Loading,Use loadingAuto on buttons,Automatic loading state from @click promise,loadingAuto prop on UButton,Manual loading state,"<UButton loadingAuto @click=""async () => await save()"">","<UButton :loading=""isLoading"" @click=""save"">",Low,https://ui.nuxt.com/docs/components/button
50,Loading,Use UForm loadingAuto,Auto-disable form during submit,loadingAuto on UForm (default true),Manual form disabled state,"<UForm @submit=""handleSubmit"">","<UForm :disabled=""isSubmitting"">",Low,https://ui.nuxt.com/docs/components/form
Can't render this file because it contains an unexpected character in line 6 and column 94.

View File

@@ -0,0 +1,59 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,Routing,Use file-based routing,Create routes by adding files in pages directory,pages/ directory with index.vue,Manual route configuration,pages/dashboard/index.vue,Custom router setup,Medium,https://nuxt.com/docs/getting-started/routing
2,Routing,Use dynamic route parameters,Create dynamic routes with bracket syntax,[id].vue for dynamic params,Hardcoded routes for dynamic content,pages/posts/[id].vue,pages/posts/post1.vue,Medium,https://nuxt.com/docs/getting-started/routing
3,Routing,Use catch-all routes,Handle multiple path segments with [...slug],[...slug].vue for catch-all,Multiple nested dynamic routes,pages/[...slug].vue,pages/[a]/[b]/[c].vue,Low,https://nuxt.com/docs/getting-started/routing
4,Routing,Define page metadata with definePageMeta,Set page-level configuration and middleware,definePageMeta for layout middleware title,Manual route meta configuration,"definePageMeta({ layout: 'admin', middleware: 'auth' })",router.beforeEach for page config,High,https://nuxt.com/docs/api/utils/define-page-meta
5,Routing,Use validate for route params,Validate dynamic route parameters before rendering,validate function in definePageMeta,Manual validation in setup,"definePageMeta({ validate: (route) => /^\d+$/.test(route.params.id) })",if (!valid) navigateTo('/404'),Medium,https://nuxt.com/docs/api/utils/define-page-meta
6,Rendering,Use SSR by default,Server-side rendering is enabled by default,Keep ssr: true (default),Disable SSR unnecessarily,ssr: true (default),ssr: false for all pages,High,https://nuxt.com/docs/guide/concepts/rendering
7,Rendering,Use .client suffix for client-only components,Mark components to render only on client,ComponentName.client.vue suffix,v-if with process.client check,Comments.client.vue,<div v-if="process.client"><Comments/></div>,Medium,https://nuxt.com/docs/guide/directory-structure/components
8,Rendering,Use .server suffix for server-only components,Mark components to render only on server,ComponentName.server.vue suffix,Manual server check,HeavyMarkdown.server.vue,v-if="process.server",Low,https://nuxt.com/docs/guide/directory-structure/components
9,DataFetching,Use useFetch for simple data fetching,Wrapper around useAsyncData for URL fetching,useFetch for API calls,$fetch in onMounted,"const { data } = await useFetch('/api/posts')","onMounted(async () => { data.value = await $fetch('/api/posts') })",High,https://nuxt.com/docs/api/composables/use-fetch
10,DataFetching,Use useAsyncData for complex fetching,Fine-grained control over async data,useAsyncData for CMS or custom fetching,useFetch for non-URL data sources,"const { data } = await useAsyncData('posts', () => cms.getPosts())","const { data } = await useFetch(() => cms.getPosts())",Medium,https://nuxt.com/docs/api/composables/use-async-data
11,DataFetching,Use $fetch for non-reactive requests,$fetch for event handlers and non-component code,$fetch in event handlers or server routes,useFetch in click handlers,"async function submit() { await $fetch('/api/submit', { method: 'POST' }) }","async function submit() { await useFetch('/api/submit') }",High,https://nuxt.com/docs/api/utils/dollarfetch
12,DataFetching,Use lazy option for non-blocking fetch,Defer data fetching for better initial load,lazy: true for below-fold content,Blocking fetch for non-critical data,"useFetch('/api/comments', { lazy: true })",await useFetch('/api/comments') for footer,Medium,https://nuxt.com/docs/api/composables/use-fetch
13,DataFetching,Use server option to control fetch location,Choose where data is fetched,server: false for client-only data,Server fetch for user-specific client data,"useFetch('/api/user-preferences', { server: false })",useFetch for localStorage-dependent data,Medium,https://nuxt.com/docs/api/composables/use-fetch
14,DataFetching,Use pick to reduce payload size,Select only needed fields from response,pick option for large responses,Fetching entire objects when few fields needed,"useFetch('/api/user', { pick: ['id', 'name'] })",useFetch('/api/user') then destructure,Low,https://nuxt.com/docs/api/composables/use-fetch
15,DataFetching,Use transform for data manipulation,Transform data before storing in state,transform option for data shaping,Manual transformation after fetch,"useFetch('/api/posts', { transform: (posts) => posts.map(p => p.title) })",const titles = data.value.map(p => p.title),Low,https://nuxt.com/docs/api/composables/use-fetch
16,DataFetching,Handle loading and error states,Always handle pending and error states,Check status pending error refs,Ignoring loading states,"<div v-if=""status === 'pending'"">Loading...</div>",No loading indicator,High,https://nuxt.com/docs/getting-started/data-fetching
17,Lifecycle,Avoid side effects in script setup root,Move side effects to lifecycle hooks,Side effects in onMounted,setInterval in root script setup,"onMounted(() => { interval = setInterval(...) })","<script setup>setInterval(...)</script>",High,https://nuxt.com/docs/guide/concepts/nuxt-lifecycle
18,Lifecycle,Use onMounted for DOM access,Access DOM only after component is mounted,onMounted for DOM manipulation,Direct DOM access in setup,"onMounted(() => { document.getElementById('el') })","<script setup>document.getElementById('el')</script>",High,https://nuxt.com/docs/api/composables/on-mounted
19,Lifecycle,Use nextTick for post-render access,Wait for DOM updates before accessing elements,await nextTick() after state changes,Immediate DOM access after state change,"count.value++; await nextTick(); el.value.focus()","count.value++; el.value.focus()",Medium,https://nuxt.com/docs/api/utils/next-tick
20,Lifecycle,Use onPrehydrate for pre-hydration logic,Run code before Nuxt hydrates the page,onPrehydrate for client setup,onMounted for hydration-critical code,"onPrehydrate(() => { console.log(window) })",onMounted for pre-hydration needs,Low,https://nuxt.com/docs/api/composables/on-prehydrate
21,Server,Use server/api for API routes,Create API endpoints in server/api directory,server/api/users.ts for /api/users,Manual Express setup,server/api/hello.ts -> /api/hello,app.get('/api/hello'),High,https://nuxt.com/docs/guide/directory-structure/server
22,Server,Use defineEventHandler for handlers,Define server route handlers,defineEventHandler for all handlers,export default function,"export default defineEventHandler((event) => { return { hello: 'world' } })","export default function(req, res) {}",High,https://nuxt.com/docs/guide/directory-structure/server
23,Server,Use server/routes for non-api routes,Routes without /api prefix,server/routes for custom paths,server/api for non-api routes,server/routes/sitemap.xml.ts,server/api/sitemap.xml.ts,Medium,https://nuxt.com/docs/guide/directory-structure/server
24,Server,Use getQuery and readBody for input,Access query params and request body,getQuery(event) readBody(event),Direct event access,"const { id } = getQuery(event)",event.node.req.query,Medium,https://nuxt.com/docs/guide/directory-structure/server
25,Server,Validate server input,Always validate input in server handlers,Zod or similar for validation,Trust client input,"const body = await readBody(event); schema.parse(body)",const body = await readBody(event),High,https://nuxt.com/docs/guide/directory-structure/server
26,State,Use useState for shared reactive state,SSR-friendly shared state across components,useState for cross-component state,ref for shared state,"const count = useState('count', () => 0)",const count = ref(0) in composable,High,https://nuxt.com/docs/api/composables/use-state
27,State,Use unique keys for useState,Prevent state conflicts with unique keys,Descriptive unique keys for each state,Generic or duplicate keys,"useState('user-preferences', () => ({}))",useState('data') in multiple places,Medium,https://nuxt.com/docs/api/composables/use-state
28,State,Use Pinia for complex state,Pinia for advanced state management,@pinia/nuxt for complex apps,Custom state management,useMainStore() with Pinia,Custom reactive store implementation,Medium,https://nuxt.com/docs/getting-started/state-management
29,State,Use callOnce for one-time async operations,Ensure async operations run only once,callOnce for store initialization,Direct await in component,"await callOnce(store.fetch)",await store.fetch() on every render,Medium,https://nuxt.com/docs/api/utils/call-once
30,SEO,Use useSeoMeta for SEO tags,Type-safe SEO meta tag management,useSeoMeta for meta tags,useHead for simple meta,"useSeoMeta({ title: 'Home', ogTitle: 'Home', description: '...' })","useHead({ meta: [{ name: 'description', content: '...' }] })",High,https://nuxt.com/docs/api/composables/use-seo-meta
31,SEO,Use reactive values in useSeoMeta,Dynamic SEO tags with refs or getters,Computed getters for dynamic values,Static values for dynamic content,"useSeoMeta({ title: () => post.value.title })","useSeoMeta({ title: post.value.title })",Medium,https://nuxt.com/docs/api/composables/use-seo-meta
32,SEO,Use useHead for non-meta head elements,Scripts styles links in head,useHead for scripts and links,useSeoMeta for scripts,"useHead({ script: [{ src: '/analytics.js' }] })","useSeoMeta({ script: '...' })",Medium,https://nuxt.com/docs/api/composables/use-head
33,SEO,Include OpenGraph tags,Add OG tags for social sharing,ogTitle ogDescription ogImage,Missing social preview,"useSeoMeta({ ogImage: '/og.png', twitterCard: 'summary_large_image' })",No OG configuration,Medium,https://nuxt.com/docs/api/composables/use-seo-meta
34,Middleware,Use defineNuxtRouteMiddleware,Define route middleware properly,defineNuxtRouteMiddleware wrapper,export default function,"export default defineNuxtRouteMiddleware((to, from) => {})","export default function(to, from) {}",High,https://nuxt.com/docs/guide/directory-structure/middleware
35,Middleware,Use navigateTo for redirects,Redirect in middleware with navigateTo,return navigateTo('/login'),router.push in middleware,"if (!auth) return navigateTo('/login')","if (!auth) router.push('/login')",High,https://nuxt.com/docs/api/utils/navigate-to
36,Middleware,Reference middleware in definePageMeta,Apply middleware to specific pages,middleware array in definePageMeta,Global middleware for page-specific,definePageMeta({ middleware: ['auth'] }),Global auth check for one page,Medium,https://nuxt.com/docs/guide/directory-structure/middleware
37,Middleware,Use .global suffix for global middleware,Apply middleware to all routes,auth.global.ts for app-wide auth,Manual middleware on every page,middleware/auth.global.ts,middleware: ['auth'] on every page,Medium,https://nuxt.com/docs/guide/directory-structure/middleware
38,ErrorHandling,Use createError for errors,Create errors with proper status codes,createError with statusCode,throw new Error,"throw createError({ statusCode: 404, statusMessage: 'Not Found' })",throw new Error('Not Found'),High,https://nuxt.com/docs/api/utils/create-error
39,ErrorHandling,Use NuxtErrorBoundary for local errors,Handle errors within component subtree,NuxtErrorBoundary for component errors,Global error page for local errors,"<NuxtErrorBoundary @error=""log""><template #error=""{ error }"">",error.vue for component errors,Medium,https://nuxt.com/docs/getting-started/error-handling
40,ErrorHandling,Use clearError to recover from errors,Clear error state and optionally redirect,clearError({ redirect: '/' }),Manual error state reset,clearError({ redirect: '/home' }),error.value = null,Medium,https://nuxt.com/docs/api/utils/clear-error
41,ErrorHandling,Use short statusMessage,Keep statusMessage brief for security,Short generic messages,Detailed error info in statusMessage,"createError({ statusCode: 400, statusMessage: 'Bad Request' })","createError({ statusMessage: 'Invalid user ID: 123' })",High,https://nuxt.com/docs/getting-started/error-handling
42,Link,Use NuxtLink for internal navigation,Client-side navigation with prefetching,<NuxtLink to> for internal links,<a href> for internal links,<NuxtLink to="/about">About</NuxtLink>,<a href="/about">About</a>,High,https://nuxt.com/docs/api/components/nuxt-link
43,Link,Configure prefetch behavior,Control when prefetching occurs,prefetchOn for interaction-based,Default prefetch for low-priority,"<NuxtLink prefetch-on=""interaction"">",Always default prefetch,Low,https://nuxt.com/docs/api/components/nuxt-link
44,Link,Use useRouter for programmatic navigation,Navigate programmatically,useRouter().push() for navigation,Direct window.location,"const router = useRouter(); router.push('/dashboard')",window.location.href = '/dashboard',Medium,https://nuxt.com/docs/api/composables/use-router
45,Link,Use navigateTo in composables,Navigate outside components,navigateTo() in middleware or plugins,useRouter in non-component code,return navigateTo('/login'),router.push in middleware,Medium,https://nuxt.com/docs/api/utils/navigate-to
46,AutoImports,Leverage auto-imports,Use auto-imported composables directly,Direct use of ref computed useFetch,Manual imports for Nuxt composables,"const count = ref(0)","import { ref } from 'vue'; const count = ref(0)",Medium,https://nuxt.com/docs/guide/concepts/auto-imports
47,AutoImports,Use #imports for explicit imports,Explicit imports when needed,#imports for clarity or disabled auto-imports,"import from 'vue' when auto-import enabled","import { ref } from '#imports'","import { ref } from 'vue'",Low,https://nuxt.com/docs/guide/concepts/auto-imports
48,AutoImports,Configure third-party auto-imports,Add external package auto-imports,imports.presets in nuxt.config,Manual imports everywhere,"imports: { presets: [{ from: 'vue-i18n', imports: ['useI18n'] }] }",import { useI18n } everywhere,Low,https://nuxt.com/docs/guide/concepts/auto-imports
49,Plugins,Use defineNuxtPlugin,Define plugins properly,defineNuxtPlugin wrapper,export default function,"export default defineNuxtPlugin((nuxtApp) => {})","export default function(ctx) {}",High,https://nuxt.com/docs/guide/directory-structure/plugins
50,Plugins,Use provide for injection,Provide helpers across app,return { provide: {} } for type safety,nuxtApp.provide without types,"return { provide: { hello: (name) => `Hello ${name}!` } }","nuxtApp.provide('hello', fn)",Medium,https://nuxt.com/docs/guide/directory-structure/plugins
51,Plugins,Use .client or .server suffix,Control plugin execution environment,plugin.client.ts for client-only,if (process.client) checks,analytics.client.ts,"if (process.client) { // analytics }",Medium,https://nuxt.com/docs/guide/directory-structure/plugins
52,Environment,Use runtimeConfig for env vars,Access environment variables safely,runtimeConfig in nuxt.config,process.env directly,"runtimeConfig: { apiSecret: '', public: { apiBase: '' } }",process.env.API_SECRET in components,High,https://nuxt.com/docs/guide/going-further/runtime-config
53,Environment,Use NUXT_ prefix for env override,Override config with environment variables,NUXT_API_SECRET NUXT_PUBLIC_API_BASE,Custom env var names,NUXT_PUBLIC_API_BASE=https://api.example.com,API_BASE=https://api.example.com,High,https://nuxt.com/docs/guide/going-further/runtime-config
54,Environment,Access public config with useRuntimeConfig,Get public config in components,useRuntimeConfig().public,Direct process.env access,const config = useRuntimeConfig(); config.public.apiBase,process.env.NUXT_PUBLIC_API_BASE,High,https://nuxt.com/docs/api/composables/use-runtime-config
55,Environment,Keep secrets in private config,Server-only secrets in runtimeConfig root,runtimeConfig.apiSecret (server only),Secrets in public config,runtimeConfig: { dbPassword: '' },runtimeConfig: { public: { dbPassword: '' } },High,https://nuxt.com/docs/guide/going-further/runtime-config
56,Performance,Use Lazy prefix for code splitting,Lazy load components with Lazy prefix,<LazyComponent> for below-fold,Eager load all components,<LazyMountainsList v-if="show"/>,<MountainsList/> for hidden content,Medium,https://nuxt.com/docs/guide/directory-structure/components
57,Performance,Use useLazyFetch for non-blocking data,Alias for useFetch with lazy: true,useLazyFetch for secondary data,useFetch for all requests,"const { data } = useLazyFetch('/api/comments')",await useFetch for comments section,Medium,https://nuxt.com/docs/api/composables/use-lazy-fetch
58,Performance,Use lazy hydration for interactivity,Delay component hydration until needed,LazyComponent with hydration strategy,Immediate hydration for all,<LazyModal hydrate-on-visible/>,<Modal/> in footer,Low,https://nuxt.com/docs/guide/going-further/experimental-features
Can't render this file because it contains an unexpected character in line 8 and column 193.

View File

@@ -0,0 +1,52 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,Components,Use functional components,Hooks-based components are standard,Functional components with hooks,Class components,const App = () => { },class App extends Component,Medium,https://reactnative.dev/docs/intro-react
2,Components,Keep components small,Single responsibility principle,Split into smaller components,Large monolithic components,<Header /><Content /><Footer />,500+ line component,Medium,
3,Components,Use TypeScript,Type safety for props and state,TypeScript for new projects,JavaScript without types,const Button: FC<Props> = () => { },const Button = (props) => { },Medium,
4,Components,Colocate component files,Keep related files together,Component folder with styles,Flat structure,components/Button/index.tsx styles.ts,components/Button.tsx styles/button.ts,Low,
5,Styling,Use StyleSheet.create,Optimized style objects,StyleSheet for all styles,Inline style objects,StyleSheet.create({ container: {} }),style={{ margin: 10 }},High,https://reactnative.dev/docs/stylesheet
6,Styling,Avoid inline styles,Prevent object recreation,Styles in StyleSheet,Inline style objects in render,style={styles.container},"style={{ margin: 10, padding: 5 }}",Medium,
7,Styling,Use flexbox for layout,React Native uses flexbox,flexDirection alignItems justifyContent,Absolute positioning everywhere,flexDirection: 'row',position: 'absolute' everywhere,Medium,https://reactnative.dev/docs/flexbox
8,Styling,Handle platform differences,Platform-specific styles,Platform.select or .ios/.android files,Same styles for both platforms,"Platform.select({ ios: {}, android: {} })",Hardcoded iOS values,Medium,https://reactnative.dev/docs/platform-specific-code
9,Styling,Use responsive dimensions,Scale for different screens,Dimensions or useWindowDimensions,Fixed pixel values,useWindowDimensions(),width: 375,Medium,
10,Navigation,Use React Navigation,Standard navigation library,React Navigation for routing,Manual navigation management,createStackNavigator(),Custom navigation state,Medium,https://reactnavigation.org/
11,Navigation,Type navigation params,Type-safe navigation,Typed navigation props,Untyped navigation,"navigation.navigate<RootStackParamList>('Home', { id })","navigation.navigate('Home', { id })",Medium,
12,Navigation,Use deep linking,Support URL-based navigation,Configure linking prop,No deep link support,linking: { prefixes: [] },No linking configuration,Medium,https://reactnavigation.org/docs/deep-linking/
13,Navigation,Handle back button,Android back button handling,useFocusEffect with BackHandler,Ignore back button,BackHandler.addEventListener,No back handler,High,
14,State,Use useState for local state,Simple component state,useState for UI state,Class component state,"const [count, setCount] = useState(0)",this.state = { count: 0 },Medium,
15,State,Use useReducer for complex state,Complex state logic,useReducer for related state,Multiple useState for related values,useReducer(reducer initialState),5+ useState calls,Medium,
16,State,Use context sparingly,Context for global state,Context for theme auth locale,Context for frequently changing data,ThemeContext for app theme,Context for list item data,Medium,
17,State,Consider Zustand or Redux,External state management,Zustand for simple Redux for complex,useState for global state,create((set) => ({ })),Prop drilling global state,Medium,
18,Lists,Use FlatList for long lists,Virtualized list rendering,FlatList for 50+ items,ScrollView with map,<FlatList data={items} />,<ScrollView>{items.map()}</ScrollView>,High,https://reactnative.dev/docs/flatlist
19,Lists,Provide keyExtractor,Unique keys for list items,keyExtractor with stable ID,Index as key,keyExtractor={(item) => item.id},"keyExtractor={(_, index) => index}",High,
20,Lists,Optimize renderItem,Memoize list item components,React.memo for list items,Inline render function,renderItem={({ item }) => <MemoizedItem item={item} />},renderItem={({ item }) => <View>...</View>},High,
21,Lists,Use getItemLayout for fixed height,Skip measurement for performance,getItemLayout when height known,Dynamic measurement for fixed items,"getItemLayout={(_, index) => ({ length: 50, offset: 50 * index, index })}",No getItemLayout for fixed height,Medium,
22,Lists,Implement windowSize,Control render window,Smaller windowSize for memory,Default windowSize for large lists,windowSize={5},windowSize={21} for huge lists,Medium,
23,Performance,Use React.memo,Prevent unnecessary re-renders,memo for pure components,No memoization,export default memo(MyComponent),export default MyComponent,Medium,
24,Performance,Use useCallback for handlers,Stable function references,useCallback for props,New function on every render,"useCallback(() => {}, [deps])",() => handlePress(),Medium,
25,Performance,Use useMemo for expensive ops,Cache expensive calculations,useMemo for heavy computations,Recalculate every render,"useMemo(() => expensive(), [deps])",const result = expensive(),Medium,
26,Performance,Avoid anonymous functions in JSX,Prevent re-renders,Named handlers or useCallback,Inline arrow functions,onPress={handlePress},onPress={() => doSomething()},Medium,
27,Performance,Use Hermes engine,Improved startup and memory,Enable Hermes in build,JavaScriptCore for new projects,hermes_enabled: true,hermes_enabled: false,Medium,https://reactnative.dev/docs/hermes
28,Images,Use expo-image,Modern performant image component for React Native,"Use expo-image for caching, blurring, and performance",Use default Image for heavy lists or unmaintained libraries,<Image source={url} cachePolicy='memory-disk' /> (expo-image),<FastImage source={url} />,Medium,https://docs.expo.dev/versions/latest/sdk/image/
29,Images,Specify image dimensions,Prevent layout shifts,width and height for remote images,No dimensions for network images,<Image style={{ width: 100 height: 100 }} />,<Image source={{ uri }} /> no size,High,
30,Images,Use resizeMode,Control image scaling,resizeMode cover contain,Stretch images,"resizeMode=""cover""",No resizeMode,Low,
31,Forms,Use controlled inputs,State-controlled form fields,value + onChangeText,Uncontrolled inputs,<TextInput value={text} onChangeText={setText} />,<TextInput defaultValue={text} />,Medium,
32,Forms,Handle keyboard,Manage keyboard visibility,KeyboardAvoidingView,Content hidden by keyboard,"<KeyboardAvoidingView behavior=""padding"">",No keyboard handling,High,https://reactnative.dev/docs/keyboardavoidingview
33,Forms,Use proper keyboard types,Appropriate keyboard for input,keyboardType for input type,Default keyboard for all,"keyboardType=""email-address""","keyboardType=""default"" for email",Low,
34,Touch,Use Pressable,Modern touch handling,Pressable for touch interactions,TouchableOpacity for new code,<Pressable onPress={} />,<TouchableOpacity onPress={} />,Low,https://reactnative.dev/docs/pressable
35,Touch,Provide touch feedback,Visual feedback on press,Ripple or opacity change,No feedback on press,android_ripple={{ color: 'gray' }},No press feedback,Medium,
36,Touch,Set hitSlop for small targets,Increase touch area,hitSlop for icons and small buttons,Tiny touch targets,hitSlop={{ top: 10 bottom: 10 }},44x44 with no hitSlop,Medium,
37,Animation,Use Reanimated,High-performance animations,react-native-reanimated,Animated API for complex,useSharedValue useAnimatedStyle,Animated.timing for gesture,Medium,https://docs.swmansion.com/react-native-reanimated/
38,Animation,Run on UI thread,worklets for smooth animation,Run animations on UI thread,JS thread animations,runOnUI(() => {}),Animated on JS thread,High,
39,Animation,Use gesture handler,Native gesture recognition,react-native-gesture-handler,JS-based gesture handling,<GestureDetector>,<View onTouchMove={} />,Medium,https://docs.swmansion.com/react-native-gesture-handler/
40,Async,Handle loading states,Show loading indicators,ActivityIndicator during load,Empty screen during load,{isLoading ? <ActivityIndicator /> : <Content />},No loading state,Medium,
41,Async,Handle errors gracefully,Error boundaries and fallbacks,Error UI for failed requests,Crash on error,{error ? <ErrorView /> : <Content />},No error handling,High,
42,Async,Cancel async operations,Cleanup on unmount,AbortController or cleanup,Memory leaks from async,useEffect cleanup,No cleanup for subscriptions,High,
43,Accessibility,Add accessibility labels,Describe UI elements,accessibilityLabel for all interactive,Missing labels,"accessibilityLabel=""Submit form""",<Pressable> without label,High,https://reactnative.dev/docs/accessibility
44,Accessibility,Use accessibility roles,Semantic meaning,accessibilityRole for elements,Wrong roles,"accessibilityRole=""button""",No role for button,Medium,
45,Accessibility,Support screen readers,Test with TalkBack/VoiceOver,Test with screen readers,Skip accessibility testing,Regular TalkBack testing,No screen reader testing,High,
46,Testing,Use React Native Testing Library,Component testing,render and fireEvent,Enzyme or manual testing,render(<Component />),shallow(<Component />),Medium,https://callstack.github.io/react-native-testing-library/
47,Testing,Test on real devices,Real device behavior,Test on iOS and Android devices,Simulator only,Device testing in CI,Simulator only testing,High,
48,Testing,Use Detox for E2E,End-to-end testing,Detox for critical flows,Manual E2E testing,detox test,Manual testing only,Medium,https://wix.github.io/Detox/
49,Native,Use native modules carefully,Bridge has overhead,Batch native calls,Frequent bridge crossing,Batch updates,Call native on every keystroke,High,
50,Native,Use Expo when possible,Simplified development,Expo for standard features,Bare RN for simple apps,expo install package,react-native link package,Low,https://docs.expo.dev/
51,Native,Handle permissions,Request permissions properly,Check and request permissions,Assume permissions granted,PermissionsAndroid.request(),Access without permission check,High,https://reactnative.dev/docs/permissionsandroid
1 No Category Guideline Description Do Don't Code Good Code Bad Severity Docs URL
2 1 Components Use functional components Hooks-based components are standard Functional components with hooks Class components const App = () => { } class App extends Component Medium https://reactnative.dev/docs/intro-react
3 2 Components Keep components small Single responsibility principle Split into smaller components Large monolithic components <Header /><Content /><Footer /> 500+ line component Medium
4 3 Components Use TypeScript Type safety for props and state TypeScript for new projects JavaScript without types const Button: FC<Props> = () => { } const Button = (props) => { } Medium
5 4 Components Colocate component files Keep related files together Component folder with styles Flat structure components/Button/index.tsx styles.ts components/Button.tsx styles/button.ts Low
6 5 Styling Use StyleSheet.create Optimized style objects StyleSheet for all styles Inline style objects StyleSheet.create({ container: {} }) style={{ margin: 10 }} High https://reactnative.dev/docs/stylesheet
7 6 Styling Avoid inline styles Prevent object recreation Styles in StyleSheet Inline style objects in render style={styles.container} style={{ margin: 10, padding: 5 }} Medium
8 7 Styling Use flexbox for layout React Native uses flexbox flexDirection alignItems justifyContent Absolute positioning everywhere flexDirection: 'row' position: 'absolute' everywhere Medium https://reactnative.dev/docs/flexbox
9 8 Styling Handle platform differences Platform-specific styles Platform.select or .ios/.android files Same styles for both platforms Platform.select({ ios: {}, android: {} }) Hardcoded iOS values Medium https://reactnative.dev/docs/platform-specific-code
10 9 Styling Use responsive dimensions Scale for different screens Dimensions or useWindowDimensions Fixed pixel values useWindowDimensions() width: 375 Medium
11 10 Navigation Use React Navigation Standard navigation library React Navigation for routing Manual navigation management createStackNavigator() Custom navigation state Medium https://reactnavigation.org/
12 11 Navigation Type navigation params Type-safe navigation Typed navigation props Untyped navigation navigation.navigate<RootStackParamList>('Home', { id }) navigation.navigate('Home', { id }) Medium
13 12 Navigation Use deep linking Support URL-based navigation Configure linking prop No deep link support linking: { prefixes: [] } No linking configuration Medium https://reactnavigation.org/docs/deep-linking/
14 13 Navigation Handle back button Android back button handling useFocusEffect with BackHandler Ignore back button BackHandler.addEventListener No back handler High
15 14 State Use useState for local state Simple component state useState for UI state Class component state const [count, setCount] = useState(0) this.state = { count: 0 } Medium
16 15 State Use useReducer for complex state Complex state logic useReducer for related state Multiple useState for related values useReducer(reducer initialState) 5+ useState calls Medium
17 16 State Use context sparingly Context for global state Context for theme auth locale Context for frequently changing data ThemeContext for app theme Context for list item data Medium
18 17 State Consider Zustand or Redux External state management Zustand for simple Redux for complex useState for global state create((set) => ({ })) Prop drilling global state Medium
19 18 Lists Use FlatList for long lists Virtualized list rendering FlatList for 50+ items ScrollView with map <FlatList data={items} /> <ScrollView>{items.map()}</ScrollView> High https://reactnative.dev/docs/flatlist
20 19 Lists Provide keyExtractor Unique keys for list items keyExtractor with stable ID Index as key keyExtractor={(item) => item.id} keyExtractor={(_, index) => index} High
21 20 Lists Optimize renderItem Memoize list item components React.memo for list items Inline render function renderItem={({ item }) => <MemoizedItem item={item} />} renderItem={({ item }) => <View>...</View>} High
22 21 Lists Use getItemLayout for fixed height Skip measurement for performance getItemLayout when height known Dynamic measurement for fixed items getItemLayout={(_, index) => ({ length: 50, offset: 50 * index, index })} No getItemLayout for fixed height Medium
23 22 Lists Implement windowSize Control render window Smaller windowSize for memory Default windowSize for large lists windowSize={5} windowSize={21} for huge lists Medium
24 23 Performance Use React.memo Prevent unnecessary re-renders memo for pure components No memoization export default memo(MyComponent) export default MyComponent Medium
25 24 Performance Use useCallback for handlers Stable function references useCallback for props New function on every render useCallback(() => {}, [deps]) () => handlePress() Medium
26 25 Performance Use useMemo for expensive ops Cache expensive calculations useMemo for heavy computations Recalculate every render useMemo(() => expensive(), [deps]) const result = expensive() Medium
27 26 Performance Avoid anonymous functions in JSX Prevent re-renders Named handlers or useCallback Inline arrow functions onPress={handlePress} onPress={() => doSomething()} Medium
28 27 Performance Use Hermes engine Improved startup and memory Enable Hermes in build JavaScriptCore for new projects hermes_enabled: true hermes_enabled: false Medium https://reactnative.dev/docs/hermes
29 28 Images Use expo-image Modern performant image component for React Native Use expo-image for caching, blurring, and performance Use default Image for heavy lists or unmaintained libraries <Image source={url} cachePolicy='memory-disk' /> (expo-image) <FastImage source={url} /> Medium https://docs.expo.dev/versions/latest/sdk/image/
30 29 Images Specify image dimensions Prevent layout shifts width and height for remote images No dimensions for network images <Image style={{ width: 100 height: 100 }} /> <Image source={{ uri }} /> no size High
31 30 Images Use resizeMode Control image scaling resizeMode cover contain Stretch images resizeMode="cover" No resizeMode Low
32 31 Forms Use controlled inputs State-controlled form fields value + onChangeText Uncontrolled inputs <TextInput value={text} onChangeText={setText} /> <TextInput defaultValue={text} /> Medium
33 32 Forms Handle keyboard Manage keyboard visibility KeyboardAvoidingView Content hidden by keyboard <KeyboardAvoidingView behavior="padding"> No keyboard handling High https://reactnative.dev/docs/keyboardavoidingview
34 33 Forms Use proper keyboard types Appropriate keyboard for input keyboardType for input type Default keyboard for all keyboardType="email-address" keyboardType="default" for email Low
35 34 Touch Use Pressable Modern touch handling Pressable for touch interactions TouchableOpacity for new code <Pressable onPress={} /> <TouchableOpacity onPress={} /> Low https://reactnative.dev/docs/pressable
36 35 Touch Provide touch feedback Visual feedback on press Ripple or opacity change No feedback on press android_ripple={{ color: 'gray' }} No press feedback Medium
37 36 Touch Set hitSlop for small targets Increase touch area hitSlop for icons and small buttons Tiny touch targets hitSlop={{ top: 10 bottom: 10 }} 44x44 with no hitSlop Medium
38 37 Animation Use Reanimated High-performance animations react-native-reanimated Animated API for complex useSharedValue useAnimatedStyle Animated.timing for gesture Medium https://docs.swmansion.com/react-native-reanimated/
39 38 Animation Run on UI thread worklets for smooth animation Run animations on UI thread JS thread animations runOnUI(() => {}) Animated on JS thread High
40 39 Animation Use gesture handler Native gesture recognition react-native-gesture-handler JS-based gesture handling <GestureDetector> <View onTouchMove={} /> Medium https://docs.swmansion.com/react-native-gesture-handler/
41 40 Async Handle loading states Show loading indicators ActivityIndicator during load Empty screen during load {isLoading ? <ActivityIndicator /> : <Content />} No loading state Medium
42 41 Async Handle errors gracefully Error boundaries and fallbacks Error UI for failed requests Crash on error {error ? <ErrorView /> : <Content />} No error handling High
43 42 Async Cancel async operations Cleanup on unmount AbortController or cleanup Memory leaks from async useEffect cleanup No cleanup for subscriptions High
44 43 Accessibility Add accessibility labels Describe UI elements accessibilityLabel for all interactive Missing labels accessibilityLabel="Submit form" <Pressable> without label High https://reactnative.dev/docs/accessibility
45 44 Accessibility Use accessibility roles Semantic meaning accessibilityRole for elements Wrong roles accessibilityRole="button" No role for button Medium
46 45 Accessibility Support screen readers Test with TalkBack/VoiceOver Test with screen readers Skip accessibility testing Regular TalkBack testing No screen reader testing High
47 46 Testing Use React Native Testing Library Component testing render and fireEvent Enzyme or manual testing render(<Component />) shallow(<Component />) Medium https://callstack.github.io/react-native-testing-library/
48 47 Testing Test on real devices Real device behavior Test on iOS and Android devices Simulator only Device testing in CI Simulator only testing High
49 48 Testing Use Detox for E2E End-to-end testing Detox for critical flows Manual E2E testing detox test Manual testing only Medium https://wix.github.io/Detox/
50 49 Native Use native modules carefully Bridge has overhead Batch native calls Frequent bridge crossing Batch updates Call native on every keystroke High
51 50 Native Use Expo when possible Simplified development Expo for standard features Bare RN for simple apps expo install package react-native link package Low https://docs.expo.dev/
52 51 Native Handle permissions Request permissions properly Check and request permissions Assume permissions granted PermissionsAndroid.request() Access without permission check High https://reactnative.dev/docs/permissionsandroid

View File

@@ -0,0 +1,54 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,State,Use useState for local state,Simple component state should use useState hook,useState for form inputs toggles counters,Class components this.state,"const [count, setCount] = useState(0)",this.state = { count: 0 },Medium,https://react.dev/reference/react/useState
2,State,Lift state up when needed,Share state between siblings by lifting to parent,Lift shared state to common ancestor,Prop drilling through many levels,Parent holds state passes down,Deep prop chains,Medium,https://react.dev/learn/sharing-state-between-components
3,State,Use useReducer for complex state,Complex state logic benefits from reducer pattern,useReducer for state with multiple sub-values,Multiple useState for related values,useReducer with action types,5+ useState calls that update together,Medium,https://react.dev/reference/react/useReducer
4,State,Avoid unnecessary state,Derive values from existing state when possible,Compute derived values in render,Store derivable values in state,const total = items.reduce(...),"const [total, setTotal] = useState(0)",High,https://react.dev/learn/choosing-the-state-structure
5,State,Initialize state lazily,Use function form for expensive initial state,useState(() => computeExpensive()),useState(computeExpensive()),useState(() => JSON.parse(data)),useState(JSON.parse(data)),Medium,https://react.dev/reference/react/useState#avoiding-recreating-the-initial-state
6,Effects,Clean up effects,Return cleanup function for subscriptions timers,Return cleanup function in useEffect,No cleanup for subscriptions,useEffect(() => { sub(); return unsub; }),useEffect(() => { subscribe(); }),High,https://react.dev/reference/react/useEffect#connecting-to-an-external-system
7,Effects,Specify dependencies correctly,Include all values used inside effect in deps array,All referenced values in dependency array,Empty deps with external references,[value] when using value in effect,[] when using props/state in effect,High,https://react.dev/reference/react/useEffect#specifying-reactive-dependencies
8,Effects,Avoid unnecessary effects,Don't use effects for transforming data or events,Transform data during render handle events directly,useEffect for derived state or event handling,const filtered = items.filter(...),useEffect(() => setFiltered(items.filter(...))),High,https://react.dev/learn/you-might-not-need-an-effect
9,Effects,Use refs for non-reactive values,Store values that don't trigger re-renders in refs,useRef for interval IDs DOM elements,useState for values that don't need render,const intervalRef = useRef(null),"const [intervalId, setIntervalId] = useState()",Medium,https://react.dev/reference/react/useRef
10,Rendering,Use keys properly,Stable unique keys for list items,Use stable IDs as keys,Array index as key for dynamic lists,key={item.id},key={index},High,https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key
11,Rendering,Memoize expensive calculations,Use useMemo for costly computations,useMemo for expensive filtering/sorting,Recalculate every render,"useMemo(() => expensive(), [deps])",const result = expensiveCalc(),Medium,https://react.dev/reference/react/useMemo
12,Rendering,Memoize callbacks passed to children,Use useCallback for functions passed as props,useCallback for handlers passed to memoized children,New function reference every render,"useCallback(() => {}, [deps])",const handler = () => {},Medium,https://react.dev/reference/react/useCallback
13,Rendering,Use React.memo wisely,Wrap components that render often with same props,memo for pure components with stable props,memo everything or nothing,memo(ExpensiveList),memo(SimpleButton),Low,https://react.dev/reference/react/memo
14,Rendering,Avoid inline object/array creation in JSX,Create objects outside render or memoize,Define style objects outside component,Inline objects in props,<div style={styles.container}>,<div style={{ margin: 10 }}>,Medium,
15,Components,Keep components small and focused,Single responsibility for each component,One concern per component,Large multi-purpose components,<UserAvatar /><UserName />,<UserCard /> with 500 lines,Medium,
16,Components,Use composition over inheritance,Compose components using children and props,Use children prop for flexibility,Inheritance hierarchies,<Card>{content}</Card>,class SpecialCard extends Card,Medium,https://react.dev/learn/thinking-in-react
17,Components,Colocate related code,Keep related components and hooks together,Related files in same directory,Flat structure with many files,components/User/UserCard.tsx,components/UserCard.tsx + hooks/useUser.ts,Low,
18,Components,Use fragments to avoid extra DOM,Fragment or <> for multiple elements without wrapper,<> for grouping without DOM node,Extra div wrappers,<>{items.map(...)}</>,<div>{items.map(...)}</div>,Low,https://react.dev/reference/react/Fragment
19,Props,Destructure props,Destructure props for cleaner component code,Destructure in function signature,props.name props.value throughout,"function User({ name, age })",function User(props),Low,
20,Props,Provide default props values,Use default parameters or defaultProps,Default values in destructuring,Undefined checks throughout,function Button({ size = 'md' }),if (size === undefined) size = 'md',Low,
21,Props,Avoid prop drilling,Use context or composition for deeply nested data,Context for global data composition for UI,Passing props through 5+ levels,<UserContext.Provider>,<A user={u}><B user={u}><C user={u}>,Medium,https://react.dev/learn/passing-data-deeply-with-context
22,Props,Validate props with TypeScript,Use TypeScript interfaces for prop types,interface Props { name: string },PropTypes or no validation,interface ButtonProps { onClick: () => void },Button.propTypes = {},Medium,
23,Events,Use synthetic events correctly,React normalizes events across browsers,e.preventDefault() e.stopPropagation(),Access native event unnecessarily,onClick={(e) => e.preventDefault()},onClick={(e) => e.nativeEvent.preventDefault()},Low,https://react.dev/reference/react-dom/components/common#react-event-object
24,Events,Avoid binding in render,Use arrow functions in class or hooks,Arrow functions in functional components,bind in render or constructor,const handleClick = () => {},this.handleClick.bind(this),Medium,
25,Events,Pass event handlers not call results,Pass function reference not invocation,onClick={handleClick},onClick={handleClick()} causing immediate call,onClick={handleClick},onClick={handleClick()},High,
26,Forms,Controlled components for forms,Use state to control form inputs,value + onChange for inputs,Uncontrolled inputs with refs,<input value={val} onChange={setVal}>,<input ref={inputRef}>,Medium,https://react.dev/reference/react-dom/components/input#controlling-an-input-with-a-state-variable
27,Forms,Handle form submission properly,Prevent default and handle in submit handler,onSubmit with preventDefault,onClick on submit button only,<form onSubmit={handleSubmit}>,<button onClick={handleSubmit}>,Medium,
28,Forms,Debounce rapid input changes,Debounce search/filter inputs,useDeferredValue or debounce for search,Filter on every keystroke,useDeferredValue(searchTerm),useEffect filtering on every change,Medium,https://react.dev/reference/react/useDeferredValue
29,Hooks,Follow rules of hooks,Only call hooks at top level and in React functions,Hooks at component top level,Hooks in conditions loops or callbacks,"const [x, setX] = useState()","if (cond) { const [x, setX] = useState() }",High,https://react.dev/reference/rules/rules-of-hooks
30,Hooks,Custom hooks for reusable logic,Extract shared stateful logic to custom hooks,useCustomHook for reusable patterns,Duplicate hook logic across components,const { data } = useFetch(url),Duplicate useEffect/useState in components,Medium,https://react.dev/learn/reusing-logic-with-custom-hooks
31,Hooks,Name custom hooks with use prefix,Custom hooks must start with use,useFetch useForm useAuth,fetchData or getData for hook,function useFetch(url),function fetchData(url),High,
32,Context,Use context for global data,Context for theme auth locale,Context for app-wide state,Context for frequently changing data,<ThemeContext.Provider>,Context for form field values,Medium,https://react.dev/learn/passing-data-deeply-with-context
33,Context,Split contexts by concern,Separate contexts for different domains,ThemeContext + AuthContext,One giant AppContext,<ThemeProvider><AuthProvider>,<AppProvider value={{theme user...}}>,Medium,
34,Context,Memoize context values,Prevent unnecessary re-renders with useMemo,useMemo for context value object,New object reference every render,"value={useMemo(() => ({...}), [])}","value={{ user, theme }}",High,
35,Performance,Use React DevTools Profiler,Profile to identify performance bottlenecks,Profile before optimizing,Optimize without measuring,React DevTools Profiler,Guessing at bottlenecks,Medium,https://react.dev/learn/react-developer-tools
36,Performance,Lazy load components,Use React.lazy for code splitting,lazy() for routes and heavy components,Import everything upfront,const Page = lazy(() => import('./Page')),import Page from './Page',Medium,https://react.dev/reference/react/lazy
37,Performance,Virtualize long lists,Use windowing for lists over 100 items,react-window or react-virtual,Render thousands of DOM nodes,<VirtualizedList items={items}/>,{items.map(i => <Item />)},High,
38,Performance,Batch state updates,React 18 auto-batches but be aware,Let React batch related updates,Manual batching with flushSync,setA(1); setB(2); // batched,flushSync(() => setA(1)),Low,https://react.dev/learn/queueing-a-series-of-state-updates
39,ErrorHandling,Use error boundaries,Catch JavaScript errors in component tree,ErrorBoundary wrapping sections,Let errors crash entire app,<ErrorBoundary><App/></ErrorBoundary>,No error handling,High,https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary
40,ErrorHandling,Handle async errors,Catch errors in async operations,try/catch in async handlers,Unhandled promise rejections,try { await fetch() } catch(e) {},await fetch() // no catch,High,
41,Testing,Test behavior not implementation,Test what user sees and does,Test renders and interactions,Test internal state or methods,expect(screen.getByText('Hello')),expect(component.state.name),Medium,https://testing-library.com/docs/react-testing-library/intro/
42,Testing,Use testing-library queries,Use accessible queries,getByRole getByLabelText,getByTestId for everything,getByRole('button'),getByTestId('submit-btn'),Medium,https://testing-library.com/docs/queries/about#priority
43,Accessibility,Use semantic HTML,Proper HTML elements for their purpose,button for clicks nav for navigation,div with onClick for buttons,<button onClick={...}>,<div onClick={...}>,High,https://react.dev/reference/react-dom/components#all-html-components
44,Accessibility,Manage focus properly,Handle focus for modals dialogs,Focus trap in modals return focus on close,No focus management,useEffect to focus input,Modal without focus trap,High,
45,Accessibility,Announce dynamic content,Use ARIA live regions for updates,aria-live for dynamic updates,Silent updates to screen readers,"<div aria-live=""polite"">{msg}</div>",<div>{msg}</div>,Medium,
46,Accessibility,Label form controls,Associate labels with inputs,htmlFor matching input id,Placeholder as only label,"<label htmlFor=""email"">Email</label>","<input placeholder=""Email""/>",High,
47,TypeScript,Type component props,Define interfaces for all props,interface Props with all prop types,any or missing types,interface Props { name: string },function Component(props: any),High,
48,TypeScript,Type state properly,Provide types for useState,useState<Type>() for complex state,Inferred any types,useState<User | null>(null),useState(null),Medium,
49,TypeScript,Type event handlers,Use React event types,React.ChangeEvent<HTMLInputElement>,Generic Event type,onChange: React.ChangeEvent<HTMLInputElement>,onChange: Event,Medium,
50,TypeScript,Use generics for reusable components,Generic components for flexible typing,Generic props for list components,Union types for flexibility,<List<T> items={T[]}>,<List items={any[]}>,Medium,
51,Patterns,Container/Presentational split,Separate data logic from UI,Container fetches presentational renders,Mixed data and UI in one,<UserContainer><UserView/></UserContainer>,<User /> with fetch and render,Low,
52,Patterns,Render props for flexibility,Share code via render prop pattern,Render prop for customizable rendering,Duplicate logic across components,<DataFetcher render={data => ...}/>,Copy paste fetch logic,Low,https://react.dev/reference/react/cloneElement#passing-data-with-a-render-prop
53,Patterns,Compound components,Related components sharing state,Tab + TabPanel sharing context,Prop drilling between related,<Tabs><Tab/><TabPanel/></Tabs>,<Tabs tabs={[]} panels={[...]}/>,Low,
1 No Category Guideline Description Do Don't Code Good Code Bad Severity Docs URL
2 1 State Use useState for local state Simple component state should use useState hook useState for form inputs toggles counters Class components this.state const [count, setCount] = useState(0) this.state = { count: 0 } Medium https://react.dev/reference/react/useState
3 2 State Lift state up when needed Share state between siblings by lifting to parent Lift shared state to common ancestor Prop drilling through many levels Parent holds state passes down Deep prop chains Medium https://react.dev/learn/sharing-state-between-components
4 3 State Use useReducer for complex state Complex state logic benefits from reducer pattern useReducer for state with multiple sub-values Multiple useState for related values useReducer with action types 5+ useState calls that update together Medium https://react.dev/reference/react/useReducer
5 4 State Avoid unnecessary state Derive values from existing state when possible Compute derived values in render Store derivable values in state const total = items.reduce(...) const [total, setTotal] = useState(0) High https://react.dev/learn/choosing-the-state-structure
6 5 State Initialize state lazily Use function form for expensive initial state useState(() => computeExpensive()) useState(computeExpensive()) useState(() => JSON.parse(data)) useState(JSON.parse(data)) Medium https://react.dev/reference/react/useState#avoiding-recreating-the-initial-state
7 6 Effects Clean up effects Return cleanup function for subscriptions timers Return cleanup function in useEffect No cleanup for subscriptions useEffect(() => { sub(); return unsub; }) useEffect(() => { subscribe(); }) High https://react.dev/reference/react/useEffect#connecting-to-an-external-system
8 7 Effects Specify dependencies correctly Include all values used inside effect in deps array All referenced values in dependency array Empty deps with external references [value] when using value in effect [] when using props/state in effect High https://react.dev/reference/react/useEffect#specifying-reactive-dependencies
9 8 Effects Avoid unnecessary effects Don't use effects for transforming data or events Transform data during render handle events directly useEffect for derived state or event handling const filtered = items.filter(...) useEffect(() => setFiltered(items.filter(...))) High https://react.dev/learn/you-might-not-need-an-effect
10 9 Effects Use refs for non-reactive values Store values that don't trigger re-renders in refs useRef for interval IDs DOM elements useState for values that don't need render const intervalRef = useRef(null) const [intervalId, setIntervalId] = useState() Medium https://react.dev/reference/react/useRef
11 10 Rendering Use keys properly Stable unique keys for list items Use stable IDs as keys Array index as key for dynamic lists key={item.id} key={index} High https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key
12 11 Rendering Memoize expensive calculations Use useMemo for costly computations useMemo for expensive filtering/sorting Recalculate every render useMemo(() => expensive(), [deps]) const result = expensiveCalc() Medium https://react.dev/reference/react/useMemo
13 12 Rendering Memoize callbacks passed to children Use useCallback for functions passed as props useCallback for handlers passed to memoized children New function reference every render useCallback(() => {}, [deps]) const handler = () => {} Medium https://react.dev/reference/react/useCallback
14 13 Rendering Use React.memo wisely Wrap components that render often with same props memo for pure components with stable props memo everything or nothing memo(ExpensiveList) memo(SimpleButton) Low https://react.dev/reference/react/memo
15 14 Rendering Avoid inline object/array creation in JSX Create objects outside render or memoize Define style objects outside component Inline objects in props <div style={styles.container}> <div style={{ margin: 10 }}> Medium
16 15 Components Keep components small and focused Single responsibility for each component One concern per component Large multi-purpose components <UserAvatar /><UserName /> <UserCard /> with 500 lines Medium
17 16 Components Use composition over inheritance Compose components using children and props Use children prop for flexibility Inheritance hierarchies <Card>{content}</Card> class SpecialCard extends Card Medium https://react.dev/learn/thinking-in-react
18 17 Components Colocate related code Keep related components and hooks together Related files in same directory Flat structure with many files components/User/UserCard.tsx components/UserCard.tsx + hooks/useUser.ts Low
19 18 Components Use fragments to avoid extra DOM Fragment or <> for multiple elements without wrapper <> for grouping without DOM node Extra div wrappers <>{items.map(...)}</> <div>{items.map(...)}</div> Low https://react.dev/reference/react/Fragment
20 19 Props Destructure props Destructure props for cleaner component code Destructure in function signature props.name props.value throughout function User({ name, age }) function User(props) Low
21 20 Props Provide default props values Use default parameters or defaultProps Default values in destructuring Undefined checks throughout function Button({ size = 'md' }) if (size === undefined) size = 'md' Low
22 21 Props Avoid prop drilling Use context or composition for deeply nested data Context for global data composition for UI Passing props through 5+ levels <UserContext.Provider> <A user={u}><B user={u}><C user={u}> Medium https://react.dev/learn/passing-data-deeply-with-context
23 22 Props Validate props with TypeScript Use TypeScript interfaces for prop types interface Props { name: string } PropTypes or no validation interface ButtonProps { onClick: () => void } Button.propTypes = {} Medium
24 23 Events Use synthetic events correctly React normalizes events across browsers e.preventDefault() e.stopPropagation() Access native event unnecessarily onClick={(e) => e.preventDefault()} onClick={(e) => e.nativeEvent.preventDefault()} Low https://react.dev/reference/react-dom/components/common#react-event-object
25 24 Events Avoid binding in render Use arrow functions in class or hooks Arrow functions in functional components bind in render or constructor const handleClick = () => {} this.handleClick.bind(this) Medium
26 25 Events Pass event handlers not call results Pass function reference not invocation onClick={handleClick} onClick={handleClick()} causing immediate call onClick={handleClick} onClick={handleClick()} High
27 26 Forms Controlled components for forms Use state to control form inputs value + onChange for inputs Uncontrolled inputs with refs <input value={val} onChange={setVal}> <input ref={inputRef}> Medium https://react.dev/reference/react-dom/components/input#controlling-an-input-with-a-state-variable
28 27 Forms Handle form submission properly Prevent default and handle in submit handler onSubmit with preventDefault onClick on submit button only <form onSubmit={handleSubmit}> <button onClick={handleSubmit}> Medium
29 28 Forms Debounce rapid input changes Debounce search/filter inputs useDeferredValue or debounce for search Filter on every keystroke useDeferredValue(searchTerm) useEffect filtering on every change Medium https://react.dev/reference/react/useDeferredValue
30 29 Hooks Follow rules of hooks Only call hooks at top level and in React functions Hooks at component top level Hooks in conditions loops or callbacks const [x, setX] = useState() if (cond) { const [x, setX] = useState() } High https://react.dev/reference/rules/rules-of-hooks
31 30 Hooks Custom hooks for reusable logic Extract shared stateful logic to custom hooks useCustomHook for reusable patterns Duplicate hook logic across components const { data } = useFetch(url) Duplicate useEffect/useState in components Medium https://react.dev/learn/reusing-logic-with-custom-hooks
32 31 Hooks Name custom hooks with use prefix Custom hooks must start with use useFetch useForm useAuth fetchData or getData for hook function useFetch(url) function fetchData(url) High
33 32 Context Use context for global data Context for theme auth locale Context for app-wide state Context for frequently changing data <ThemeContext.Provider> Context for form field values Medium https://react.dev/learn/passing-data-deeply-with-context
34 33 Context Split contexts by concern Separate contexts for different domains ThemeContext + AuthContext One giant AppContext <ThemeProvider><AuthProvider> <AppProvider value={{theme user...}}> Medium
35 34 Context Memoize context values Prevent unnecessary re-renders with useMemo useMemo for context value object New object reference every render value={useMemo(() => ({...}), [])} value={{ user, theme }} High
36 35 Performance Use React DevTools Profiler Profile to identify performance bottlenecks Profile before optimizing Optimize without measuring React DevTools Profiler Guessing at bottlenecks Medium https://react.dev/learn/react-developer-tools
37 36 Performance Lazy load components Use React.lazy for code splitting lazy() for routes and heavy components Import everything upfront const Page = lazy(() => import('./Page')) import Page from './Page' Medium https://react.dev/reference/react/lazy
38 37 Performance Virtualize long lists Use windowing for lists over 100 items react-window or react-virtual Render thousands of DOM nodes <VirtualizedList items={items}/> {items.map(i => <Item />)} High
39 38 Performance Batch state updates React 18 auto-batches but be aware Let React batch related updates Manual batching with flushSync setA(1); setB(2); // batched flushSync(() => setA(1)) Low https://react.dev/learn/queueing-a-series-of-state-updates
40 39 ErrorHandling Use error boundaries Catch JavaScript errors in component tree ErrorBoundary wrapping sections Let errors crash entire app <ErrorBoundary><App/></ErrorBoundary> No error handling High https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary
41 40 ErrorHandling Handle async errors Catch errors in async operations try/catch in async handlers Unhandled promise rejections try { await fetch() } catch(e) {} await fetch() // no catch High
42 41 Testing Test behavior not implementation Test what user sees and does Test renders and interactions Test internal state or methods expect(screen.getByText('Hello')) expect(component.state.name) Medium https://testing-library.com/docs/react-testing-library/intro/
43 42 Testing Use testing-library queries Use accessible queries getByRole getByLabelText getByTestId for everything getByRole('button') getByTestId('submit-btn') Medium https://testing-library.com/docs/queries/about#priority
44 43 Accessibility Use semantic HTML Proper HTML elements for their purpose button for clicks nav for navigation div with onClick for buttons <button onClick={...}> <div onClick={...}> High https://react.dev/reference/react-dom/components#all-html-components
45 44 Accessibility Manage focus properly Handle focus for modals dialogs Focus trap in modals return focus on close No focus management useEffect to focus input Modal without focus trap High
46 45 Accessibility Announce dynamic content Use ARIA live regions for updates aria-live for dynamic updates Silent updates to screen readers <div aria-live="polite">{msg}</div> <div>{msg}</div> Medium
47 46 Accessibility Label form controls Associate labels with inputs htmlFor matching input id Placeholder as only label <label htmlFor="email">Email</label> <input placeholder="Email"/> High
48 47 TypeScript Type component props Define interfaces for all props interface Props with all prop types any or missing types interface Props { name: string } function Component(props: any) High
49 48 TypeScript Type state properly Provide types for useState useState<Type>() for complex state Inferred any types useState<User | null>(null) useState(null) Medium
50 49 TypeScript Type event handlers Use React event types React.ChangeEvent<HTMLInputElement> Generic Event type onChange: React.ChangeEvent<HTMLInputElement> onChange: Event Medium
51 50 TypeScript Use generics for reusable components Generic components for flexible typing Generic props for list components Union types for flexibility <List<T> items={T[]}> <List items={any[]}> Medium
52 51 Patterns Container/Presentational split Separate data logic from UI Container fetches presentational renders Mixed data and UI in one <UserContainer><UserView/></UserContainer> <User /> with fetch and render Low
53 52 Patterns Render props for flexibility Share code via render prop pattern Render prop for customizable rendering Duplicate logic across components <DataFetcher render={data => ...}/> Copy paste fetch logic Low https://react.dev/reference/react/cloneElement#passing-data-with-a-render-prop
54 53 Patterns Compound components Related components sharing state Tab + TabPanel sharing context Prop drilling between related <Tabs><Tab/><TabPanel/></Tabs> <Tabs tabs={[]} panels={[...]}/> Low

View File

@@ -0,0 +1,61 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,Setup,Use CLI for installation,Install components via shadcn CLI for proper setup,npx shadcn@latest add component-name,Manual copy-paste from docs,npx shadcn@latest add button,Copy component code manually,High,https://ui.shadcn.com/docs/cli
2,Setup,Initialize project properly,Run init command to set up components.json and globals.css,npx shadcn@latest init before adding components,Skip init and add components directly,npx shadcn@latest init,npx shadcn@latest add button (without init),High,https://ui.shadcn.com/docs/installation
3,Setup,Configure path aliases,Set up proper import aliases in tsconfig and components.json,Use @/components/ui path aliases,Relative imports like ../../components,import { Button } from "@/components/ui/button",import { Button } from "../../components/ui/button",Medium,https://ui.shadcn.com/docs/installation
4,Theming,Use CSS variables for colors,Define colors as CSS variables in globals.css for theming,CSS variables in :root and .dark,Hardcoded color values in components,bg-primary text-primary-foreground,bg-blue-500 text-white,High,https://ui.shadcn.com/docs/theming
5,Theming,Follow naming convention,Use semantic color names with foreground pattern,primary/primary-foreground secondary/secondary-foreground,Generic color names,--primary --primary-foreground,--blue --light-blue,Medium,https://ui.shadcn.com/docs/theming
6,Theming,Support dark mode,Include .dark class styles for all custom CSS,Define both :root and .dark color schemes,Only light mode colors,.dark { --background: 240 10% 3.9%; },No .dark class styles,High,https://ui.shadcn.com/docs/dark-mode
7,Components,Use component variants,Leverage cva variants for consistent styling,Use variant prop for different styles,Inline conditional classes,<Button variant="destructive">,<Button className={isError ? "bg-red-500" : "bg-blue-500"}>,Medium,https://ui.shadcn.com/docs/components/button
8,Components,Compose with className,Add custom classes via className prop for overrides,Extend with className for one-off customizations,Modify component source directly,<Button className="w-full">,Edit button.tsx to add w-full,Medium,https://ui.shadcn.com/docs/components/button
9,Components,Use size variants consistently,Apply size prop for consistent sizing across components,size="sm" size="lg" for sizing,Mix size classes inconsistently,<Button size="lg">,<Button className="text-lg px-8 py-4">,Medium,https://ui.shadcn.com/docs/components/button
10,Components,Prefer compound components,Use provided sub-components for complex UI,Card + CardHeader + CardContent pattern,Single component with many props,<Card><CardHeader><CardTitle>,<Card title="x" content="y" footer="z">,Medium,https://ui.shadcn.com/docs/components/card
11,Dialog,Use Dialog for modal content,Dialog component for overlay modal windows,Dialog for confirmations forms details,Alert for modal content,<Dialog><DialogContent>,<Alert> styled as modal,High,https://ui.shadcn.com/docs/components/dialog
12,Dialog,Handle dialog state properly,Use open and onOpenChange for controlled dialogs,Controlled state with useState,Uncontrolled with default open only,"<Dialog open={open} onOpenChange={setOpen}>","<Dialog defaultOpen={true}>",Medium,https://ui.shadcn.com/docs/components/dialog
13,Dialog,Include proper dialog structure,Use DialogHeader DialogTitle DialogDescription,Complete semantic structure,Missing title or description,<DialogHeader><DialogTitle><DialogDescription>,<DialogContent><p>Content</p></DialogContent>,High,https://ui.shadcn.com/docs/components/dialog
14,Sheet,Use Sheet for side panels,Sheet component for slide-out panels and drawers,Sheet for navigation filters settings,Dialog for side content,<Sheet side="right">,<Dialog> with slide animation,Medium,https://ui.shadcn.com/docs/components/sheet
15,Sheet,Specify sheet side,Set side prop for sheet slide direction,Explicit side="left" or side="right",Default side without consideration,<Sheet><SheetContent side="left">,<Sheet><SheetContent>,Low,https://ui.shadcn.com/docs/components/sheet
16,Form,Use Form with react-hook-form,Integrate Form component with react-hook-form for validation,useForm + Form + FormField pattern,Custom form handling without Form,<Form {...form}><FormField control={form.control}>,<form onSubmit={handleSubmit}>,High,https://ui.shadcn.com/docs/components/form
17,Form,Use FormField for inputs,Wrap inputs in FormField for proper labeling and errors,FormField + FormItem + FormLabel + FormControl,Input without FormField wrapper,<FormField><FormItem><FormLabel><FormControl><Input>,<Input onChange={...}>,High,https://ui.shadcn.com/docs/components/form
18,Form,Display form messages,Use FormMessage for validation error display,FormMessage after FormControl,Custom error text without FormMessage,<FormControl><Input/></FormControl><FormMessage/>,<Input/>{error && <span>{error}</span>},Medium,https://ui.shadcn.com/docs/components/form
19,Form,Use Zod for validation,Define form schema with Zod for type-safe validation,zodResolver with form schema,Manual validation logic,zodResolver(formSchema),validate: (values) => { if (!values.email) },Medium,https://ui.shadcn.com/docs/components/form
20,Select,Use Select for dropdowns,Select component for option selection,Select for choosing from list,Native select element,<Select><SelectTrigger><SelectContent>,<select><option>,Medium,https://ui.shadcn.com/docs/components/select
21,Select,Structure Select properly,Include Trigger Value Content and Items,Complete Select structure,Missing SelectValue or SelectContent,<SelectTrigger><SelectValue/></SelectTrigger><SelectContent><SelectItem>,<Select><option>,High,https://ui.shadcn.com/docs/components/select
22,Command,Use Command for search,Command component for searchable lists and palettes,Command for command palette search,Input with custom dropdown,<Command><CommandInput><CommandList>,<Input><div className="dropdown">,Medium,https://ui.shadcn.com/docs/components/command
23,Command,Group command items,Use CommandGroup for categorized items,CommandGroup with heading for sections,Flat list without grouping,<CommandGroup heading="Suggestions"><CommandItem>,<CommandItem> without groups,Low,https://ui.shadcn.com/docs/components/command
24,Table,Use Table for data display,Table component for structured data,Table for tabular data display,Div grid for table-like layouts,<Table><TableHeader><TableBody><TableRow>,<div className="grid">,Medium,https://ui.shadcn.com/docs/components/table
25,Table,Include proper table structure,Use TableHeader TableBody TableRow TableCell,Semantic table structure,Missing thead or tbody,<TableHeader><TableRow><TableHead>,<Table><TableRow> without header,High,https://ui.shadcn.com/docs/components/table
26,DataTable,Use DataTable for complex tables,Combine Table with TanStack Table for features,DataTable pattern for sorting filtering pagination,Custom table implementation,useReactTable + Table components,Custom sort filter pagination logic,Medium,https://ui.shadcn.com/docs/components/data-table
27,Tabs,Use Tabs for content switching,Tabs component for tabbed interfaces,Tabs for related content sections,Custom tab implementation,<Tabs><TabsList><TabsTrigger><TabsContent>,<div onClick={() => setTab(...)},Medium,https://ui.shadcn.com/docs/components/tabs
28,Tabs,Set default tab value,Specify defaultValue for initial tab,defaultValue on Tabs component,No default leaving first tab,<Tabs defaultValue="account">,<Tabs> without defaultValue,Low,https://ui.shadcn.com/docs/components/tabs
29,Accordion,Use Accordion for collapsible,Accordion for expandable content sections,Accordion for FAQ settings panels,Custom collapse implementation,<Accordion><AccordionItem><AccordionTrigger>,<div onClick={() => setOpen(!open)}>,Medium,https://ui.shadcn.com/docs/components/accordion
30,Accordion,Choose accordion type,Use type="single" or type="multiple" appropriately,type="single" for one open type="multiple" for many,Default type without consideration,<Accordion type="single" collapsible>,<Accordion> without type,Low,https://ui.shadcn.com/docs/components/accordion
31,Toast,Use Sonner for toasts,Sonner integration for toast notifications,toast() from sonner for notifications,Custom toast implementation,toast("Event created"),setShowToast(true),Medium,https://ui.shadcn.com/docs/components/sonner
32,Toast,Add Toaster to layout,Include Toaster component in root layout,<Toaster /> in app layout,Toaster in individual pages,app/layout.tsx: <Toaster />,page.tsx: <Toaster />,High,https://ui.shadcn.com/docs/components/sonner
33,Toast,Use toast variants,Apply toast.success toast.error for context,Semantic toast methods,Generic toast for all messages,toast.success("Saved!") toast.error("Failed"),toast("Saved!") toast("Failed"),Medium,https://ui.shadcn.com/docs/components/sonner
34,Popover,Use Popover for floating content,Popover for dropdown menus and floating panels,Popover for contextual actions,Absolute positioned divs,<Popover><PopoverTrigger><PopoverContent>,<div className="relative"><div className="absolute">,Medium,https://ui.shadcn.com/docs/components/popover
35,Popover,Handle popover alignment,Use align and side props for positioning,Explicit alignment configuration,Default alignment for all,<PopoverContent align="start" side="bottom">,<PopoverContent>,Low,https://ui.shadcn.com/docs/components/popover
36,DropdownMenu,Use DropdownMenu for actions,DropdownMenu for action lists and context menus,DropdownMenu for user menu actions,Popover for action lists,<DropdownMenu><DropdownMenuTrigger><DropdownMenuContent>,<Popover> for menu actions,Medium,https://ui.shadcn.com/docs/components/dropdown-menu
37,DropdownMenu,Group menu items,Use DropdownMenuGroup and DropdownMenuSeparator,Organized menu with separators,Flat list of items,<DropdownMenuGroup><DropdownMenuItem><DropdownMenuSeparator>,<DropdownMenuItem> without organization,Low,https://ui.shadcn.com/docs/components/dropdown-menu
38,Tooltip,Use Tooltip for hints,Tooltip for icon buttons and truncated text,Tooltip for additional context,Title attribute for tooltips,<Tooltip><TooltipTrigger><TooltipContent>,<button title="Delete">,Medium,https://ui.shadcn.com/docs/components/tooltip
39,Tooltip,Add TooltipProvider,Wrap app or section in TooltipProvider,TooltipProvider at app level,TooltipProvider per tooltip,<TooltipProvider><App/></TooltipProvider>,<Tooltip><TooltipProvider>,High,https://ui.shadcn.com/docs/components/tooltip
40,Skeleton,Use Skeleton for loading,Skeleton component for loading placeholders,Skeleton matching content layout,Spinner for content loading,<Skeleton className="h-4 w-[200px]"/>,<Spinner/> for card loading,Medium,https://ui.shadcn.com/docs/components/skeleton
41,Skeleton,Match skeleton dimensions,Size skeleton to match loaded content,Skeleton same size as expected content,Generic skeleton size,<Skeleton className="h-12 w-12 rounded-full"/>,<Skeleton/> without sizing,Medium,https://ui.shadcn.com/docs/components/skeleton
42,AlertDialog,Use AlertDialog for confirms,AlertDialog for destructive action confirmation,AlertDialog for delete confirmations,Dialog for confirmations,<AlertDialog><AlertDialogTrigger><AlertDialogContent>,<Dialog> for delete confirmation,High,https://ui.shadcn.com/docs/components/alert-dialog
43,AlertDialog,Include action buttons,Use AlertDialogAction and AlertDialogCancel,Standard confirm/cancel pattern,Custom buttons in AlertDialog,<AlertDialogCancel>Cancel</AlertDialogCancel><AlertDialogAction>,<Button>Cancel</Button><Button>Confirm</Button>,Medium,https://ui.shadcn.com/docs/components/alert-dialog
44,Sidebar,Use Sidebar for navigation,Sidebar component for app navigation,Sidebar for main app navigation,Custom sidebar implementation,<SidebarProvider><Sidebar><SidebarContent>,<div className="w-64 fixed">,Medium,https://ui.shadcn.com/docs/components/sidebar
45,Sidebar,Wrap in SidebarProvider,Use SidebarProvider for sidebar state management,SidebarProvider at layout level,Sidebar without provider,<SidebarProvider><Sidebar></SidebarProvider>,<Sidebar> without provider,High,https://ui.shadcn.com/docs/components/sidebar
46,Sidebar,Use SidebarTrigger,Include SidebarTrigger for mobile toggle,SidebarTrigger for responsive toggle,Custom toggle button,<SidebarTrigger/>,<Button onClick={() => toggleSidebar()}>,Medium,https://ui.shadcn.com/docs/components/sidebar
47,Chart,Use Chart for data viz,Chart component with Recharts integration,Chart component for dashboards,Direct Recharts without wrapper,<ChartContainer config={chartConfig}>,<ResponsiveContainer><BarChart>,Medium,https://ui.shadcn.com/docs/components/chart
48,Chart,Define chart config,Create chartConfig for consistent theming,chartConfig with color definitions,Inline colors in charts,"{ desktop: { label: ""Desktop"", color: ""#2563eb"" } }",<Bar fill="#2563eb"/>,Medium,https://ui.shadcn.com/docs/components/chart
49,Chart,Use ChartTooltip,Apply ChartTooltip for interactive charts,ChartTooltip with ChartTooltipContent,Recharts Tooltip directly,<ChartTooltip content={<ChartTooltipContent/>}/>,<Tooltip/> from recharts,Low,https://ui.shadcn.com/docs/components/chart
50,Blocks,Use blocks for scaffolding,Start from shadcn blocks for common layouts,npx shadcn@latest add dashboard-01,Build dashboard from scratch,npx shadcn@latest add login-01,Custom login page from scratch,Medium,https://ui.shadcn.com/blocks
51,Blocks,Customize block components,Modify copied block code to fit needs,Edit block files after installation,Use blocks without modification,Customize dashboard-01 layout,Use dashboard-01 as-is,Low,https://ui.shadcn.com/blocks
52,A11y,Use semantic components,Shadcn components have built-in ARIA,Rely on component accessibility,Override ARIA attributes,<Button> has button role,<div role="button">,High,https://ui.shadcn.com/docs/components/button
53,A11y,Maintain focus management,Dialog Sheet handle focus automatically,Let components manage focus,Custom focus handling,<Dialog> traps focus,document.querySelector().focus(),High,https://ui.shadcn.com/docs/components/dialog
54,A11y,Provide labels,Use FormLabel and aria-label appropriately,FormLabel for form inputs,Placeholder as only label,<FormLabel>Email</FormLabel><Input/>,<Input placeholder="Email"/>,High,https://ui.shadcn.com/docs/components/form
55,Performance,Import components individually,Import only needed components,Named imports from component files,Import all from index,import { Button } from "@/components/ui/button",import { Button Card Dialog } from "@/components/ui",Medium,
56,Performance,Lazy load dialogs,Dynamic import for heavy dialog content,React.lazy for dialog content,Import all dialogs upfront,const HeavyContent = lazy(() => import('./Heavy')),import HeavyContent from './Heavy',Medium,
57,Customization,Extend variants with cva,Add new variants using class-variance-authority,Extend buttonVariants for new styles,Inline classes for variants,"variants: { size: { xl: ""h-14 px-8"" } }",className="h-14 px-8",Medium,https://ui.shadcn.com/docs/components/button
58,Customization,Create custom components,Build new components following shadcn patterns,Use cn() and cva for custom components,Different patterns for custom,const Custom = ({ className }) => <div className={cn("base" className)}>,const Custom = ({ style }) => <div style={style}>,Medium,
59,Patterns,Use asChild for composition,asChild prop for component composition,Slot pattern with asChild,Wrapper divs for composition,<Button asChild><Link href="/">,<Button><Link href="/"></Link></Button>,Medium,https://ui.shadcn.com/docs/components/button
60,Patterns,Combine with React Hook Form,Form + useForm for complete forms,RHF Controller with shadcn inputs,Custom form state management,<FormField control={form.control} name="email">,<Input value={email} onChange={(e) => setEmail(e.target.value)},High,https://ui.shadcn.com/docs/components/form
Can't render this file because it contains an unexpected character in line 4 and column 188.

View File

@@ -0,0 +1,54 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,Reactivity,Use $: for reactive statements,Automatic dependency tracking,$: for derived values,Manual recalculation,$: doubled = count * 2,let doubled; count && (doubled = count * 2),Medium,https://svelte.dev/docs/svelte-components#script-3-$-marks-a-statement-as-reactive
2,Reactivity,Trigger reactivity with assignment,Svelte tracks assignments not mutations,Reassign arrays/objects to trigger update,Mutate without reassignment,"items = [...items, newItem]",items.push(newItem),High,https://svelte.dev/docs/svelte-components#script-2-assignments-are-reactive
3,Reactivity,Use $state in Svelte 5,Runes for explicit reactivity,let count = $state(0),Implicit reactivity in Svelte 5,let count = $state(0),let count = 0 (Svelte 5),Medium,https://svelte.dev/blog/runes
4,Reactivity,Use $derived for computed values,$derived replaces $: in Svelte 5,let doubled = $derived(count * 2),$: in Svelte 5,let doubled = $derived(count * 2),$: doubled = count * 2 (Svelte 5),Medium,
5,Reactivity,Use $effect for side effects,$effect replaces $: side effects,Use $effect for subscriptions,$: for side effects in Svelte 5,$effect(() => console.log(count)),$: console.log(count) (Svelte 5),Medium,
6,Props,Export let for props,Declare props with export let,export let propName,Props without export,export let count = 0,let count = 0,High,https://svelte.dev/docs/svelte-components#script-1-export-creates-a-component-prop
7,Props,Use $props in Svelte 5,$props rune for prop access,let { name } = $props(),export let in Svelte 5,"let { name, age = 0 } = $props()",export let name; export let age = 0,Medium,
8,Props,Provide default values,Default props with assignment,export let count = 0,Required props without defaults,export let count = 0,export let count,Low,
9,Props,Use spread props,Pass through unknown props,{...$$restProps} on elements,Manual prop forwarding,<button {...$$restProps}>,<button class={$$props.class}>,Low,https://svelte.dev/docs/basic-markup#attributes-and-props
10,Bindings,Use bind: for two-way binding,Simplified input handling,bind:value for inputs,on:input with manual update,<input bind:value={name}>,<input value={name} on:input={e => name = e.target.value}>,Low,https://svelte.dev/docs/element-directives#bind-property
11,Bindings,Bind to DOM elements,Reference DOM nodes,bind:this for element reference,querySelector in onMount,<div bind:this={el}>,onMount(() => el = document.querySelector()),Medium,
12,Bindings,Use bind:group for radios/checkboxes,Simplified group handling,bind:group for radio/checkbox groups,Manual checked handling,"<input type=""radio"" bind:group={selected}>","<input type=""radio"" checked={selected === value}>",Low,
13,Events,Use on: for event handlers,Event directive syntax,on:click={handler},addEventListener in onMount,<button on:click={handleClick}>,onMount(() => btn.addEventListener()),Medium,https://svelte.dev/docs/element-directives#on-eventname
14,Events,Forward events with on:event,Pass events to parent,on:click without handler,createEventDispatcher for DOM events,<button on:click>,"dispatch('click', event)",Low,
15,Events,Use createEventDispatcher,Custom component events,dispatch for custom events,on:event for custom events,"dispatch('save', { data })",on:save without dispatch,Medium,https://svelte.dev/docs/svelte#createeventdispatcher
16,Lifecycle,Use onMount for initialization,Run code after component mounts,onMount for setup and data fetching,Code in script body for side effects,onMount(() => fetchData()),fetchData() in script body,High,https://svelte.dev/docs/svelte#onmount
17,Lifecycle,Return cleanup from onMount,Automatic cleanup on destroy,Return function from onMount,Separate onDestroy for paired cleanup,onMount(() => { sub(); return unsub }),onMount(sub); onDestroy(unsub),Medium,
18,Lifecycle,Use onDestroy sparingly,Only when onMount cleanup not possible,onDestroy for non-mount cleanup,onDestroy for mount-related cleanup,onDestroy for store unsubscribe,onDestroy(() => clearInterval(id)),Low,
19,Lifecycle,Avoid beforeUpdate/afterUpdate,Usually not needed,Reactive statements instead,beforeUpdate for derived state,$: if (x) doSomething(),beforeUpdate(() => doSomething()),Low,
20,Stores,Use writable for mutable state,Basic reactive store,writable for shared mutable state,Local variables for shared state,const count = writable(0),let count = 0 in module,Medium,https://svelte.dev/docs/svelte-store#writable
21,Stores,Use readable for read-only state,External data sources,readable for derived/external data,writable for read-only data,"readable(0, set => interval(set))",writable(0) for timer,Low,https://svelte.dev/docs/svelte-store#readable
22,Stores,Use derived for computed stores,Combine or transform stores,derived for computed values,Manual subscription for derived,"derived(count, $c => $c * 2)",count.subscribe(c => doubled = c * 2),Medium,https://svelte.dev/docs/svelte-store#derived
23,Stores,Use $ prefix for auto-subscription,Automatic subscribe/unsubscribe,$storeName in components,Manual subscription,{$count},count.subscribe(c => value = c),High,
24,Stores,Clean up custom subscriptions,Unsubscribe when component destroys,Return unsubscribe from onMount,Leave subscriptions open,onMount(() => store.subscribe(fn)),store.subscribe(fn) in script,High,
25,Slots,Use slots for composition,Content projection,<slot> for flexible content,Props for all content,<slot>Default</slot>,"<Component content=""text""/>",Medium,https://svelte.dev/docs/special-elements#slot
26,Slots,Name slots for multiple areas,Multiple content areas,"<slot name=""header"">",Single slot for complex layouts,"<slot name=""header""><slot name=""footer"">",<slot> with complex conditionals,Low,
27,Slots,Check slot content with $$slots,Conditional slot rendering,$$slots.name for conditional rendering,Always render slot wrapper,"{#if $$slots.footer}<slot name=""footer""/>{/if}","<div><slot name=""footer""/></div>",Low,
28,Styling,Use scoped styles by default,Styles scoped to component,<style> for component styles,Global styles for component,:global() only when needed,<style> all global,Medium,https://svelte.dev/docs/svelte-components#style
29,Styling,Use :global() sparingly,Escape scoping when needed,:global for third-party styling,Global for all styles,:global(.external-lib),<style> without scoping,Medium,
30,Styling,Use CSS variables for theming,Dynamic styling,CSS custom properties,Inline styles for themes,"style=""--color: {color}""","style=""color: {color}""",Low,
31,Transitions,Use built-in transitions,Svelte transition directives,transition:fade for simple effects,Manual CSS transitions,<div transition:fade>,<div class:fade={visible}>,Low,https://svelte.dev/docs/element-directives#transition-fn
32,Transitions,Use in: and out: separately,Different enter/exit animations,in:fly out:fade for asymmetric,Same transition for both,<div in:fly out:fade>,<div transition:fly>,Low,
33,Transitions,Add local modifier,Prevent ancestor trigger,transition:fade|local,Global transitions for lists,<div transition:slide|local>,<div transition:slide>,Medium,
34,Actions,Use actions for DOM behavior,Reusable DOM logic,use:action for DOM enhancements,onMount for each usage,<div use:clickOutside>,onMount(() => setupClickOutside(el)),Medium,https://svelte.dev/docs/element-directives#use-action
35,Actions,Return update and destroy,Lifecycle methods for actions,"Return { update, destroy }",Only initial setup,"return { update(params) {}, destroy() {} }",return destroy only,Medium,
36,Actions,Pass parameters to actions,Configure action behavior,use:action={params},Hardcoded action behavior,<div use:tooltip={options}>,<div use:tooltip>,Low,
37,Logic,Use {#if} for conditionals,Template conditionals,{#if} {:else if} {:else},Ternary in expressions,{#if cond}...{:else}...{/if},{cond ? a : b} for complex,Low,https://svelte.dev/docs/logic-blocks#if
38,Logic,Use {#each} for lists,List rendering,{#each} with key,Map in expression,{#each items as item (item.id)},{items.map(i => `<div>${i}</div>`)},Medium,
39,Logic,Always use keys in {#each},Proper list reconciliation,(item.id) for unique key,Index as key or no key,{#each items as item (item.id)},"{#each items as item, i (i)}",High,
40,Logic,Use {#await} for promises,Handle async states,{#await} for loading/error states,Manual promise handling,{#await promise}...{:then}...{:catch},{#if loading}...{#if error},Medium,https://svelte.dev/docs/logic-blocks#await
41,SvelteKit,Use +page.svelte for routes,File-based routing,+page.svelte for route components,Custom routing setup,routes/about/+page.svelte,routes/About.svelte,Medium,https://kit.svelte.dev/docs/routing
42,SvelteKit,Use +page.js for data loading,Load data before render,load function in +page.js,onMount for data fetching,export function load() {},onMount(() => fetchData()),High,https://kit.svelte.dev/docs/load
43,SvelteKit,Use +page.server.js for server-only,Server-side data loading,+page.server.js for sensitive data,+page.js for API keys,+page.server.js with DB access,+page.js with DB access,High,
44,SvelteKit,Use form actions,Server-side form handling,+page.server.js actions,API routes for forms,export const actions = { default },fetch('/api/submit'),Medium,https://kit.svelte.dev/docs/form-actions
45,SvelteKit,Use $app/stores for app state,$page $navigating $updated,$page for current page data,Manual URL parsing,import { page } from '$app/stores',window.location.pathname,Medium,https://kit.svelte.dev/docs/modules#$app-stores
46,Performance,Use {#key} for forced re-render,Reset component state,{#key id} for fresh instance,Manual destroy/create,{#key item.id}<Component/>{/key},on:change={() => component = null},Low,https://svelte.dev/docs/logic-blocks#key
47,Performance,Avoid unnecessary reactivity,Not everything needs $:,$: only for side effects,$: for simple assignments,$: if (x) console.log(x),$: y = x (when y = x works),Low,
48,Performance,Use immutable compiler option,Skip equality checks,immutable: true for large lists,Default for all components,<svelte:options immutable/>,Default without immutable,Low,
49,TypeScript,"Use lang=""ts"" in script",TypeScript support,"<script lang=""ts"">",JavaScript for typed projects,"<script lang=""ts"">",<script> with JSDoc,Medium,https://svelte.dev/docs/typescript
50,TypeScript,Type props with interface,Explicit prop types,interface $$Props for types,Untyped props,interface $$Props { name: string },export let name,Medium,
51,TypeScript,Type events with createEventDispatcher,Type-safe events,createEventDispatcher<Events>(),Untyped dispatch,createEventDispatcher<{ save: Data }>(),createEventDispatcher(),Medium,
52,Accessibility,Use semantic elements,Proper HTML in templates,button nav main appropriately,div for everything,<button on:click>,<div on:click>,High,
53,Accessibility,Add aria to dynamic content,Accessible state changes,aria-live for updates,Silent dynamic updates,"<div aria-live=""polite"">{message}</div>",<div>{message}</div>,Medium,
1 No Category Guideline Description Do Don't Code Good Code Bad Severity Docs URL
2 1 Reactivity Use $: for reactive statements Automatic dependency tracking $: for derived values Manual recalculation $: doubled = count * 2 let doubled; count && (doubled = count * 2) Medium https://svelte.dev/docs/svelte-components#script-3-$-marks-a-statement-as-reactive
3 2 Reactivity Trigger reactivity with assignment Svelte tracks assignments not mutations Reassign arrays/objects to trigger update Mutate without reassignment items = [...items, newItem] items.push(newItem) High https://svelte.dev/docs/svelte-components#script-2-assignments-are-reactive
4 3 Reactivity Use $state in Svelte 5 Runes for explicit reactivity let count = $state(0) Implicit reactivity in Svelte 5 let count = $state(0) let count = 0 (Svelte 5) Medium https://svelte.dev/blog/runes
5 4 Reactivity Use $derived for computed values $derived replaces $: in Svelte 5 let doubled = $derived(count * 2) $: in Svelte 5 let doubled = $derived(count * 2) $: doubled = count * 2 (Svelte 5) Medium
6 5 Reactivity Use $effect for side effects $effect replaces $: side effects Use $effect for subscriptions $: for side effects in Svelte 5 $effect(() => console.log(count)) $: console.log(count) (Svelte 5) Medium
7 6 Props Export let for props Declare props with export let export let propName Props without export export let count = 0 let count = 0 High https://svelte.dev/docs/svelte-components#script-1-export-creates-a-component-prop
8 7 Props Use $props in Svelte 5 $props rune for prop access let { name } = $props() export let in Svelte 5 let { name, age = 0 } = $props() export let name; export let age = 0 Medium
9 8 Props Provide default values Default props with assignment export let count = 0 Required props without defaults export let count = 0 export let count Low
10 9 Props Use spread props Pass through unknown props {...$$restProps} on elements Manual prop forwarding <button {...$$restProps}> <button class={$$props.class}> Low https://svelte.dev/docs/basic-markup#attributes-and-props
11 10 Bindings Use bind: for two-way binding Simplified input handling bind:value for inputs on:input with manual update <input bind:value={name}> <input value={name} on:input={e => name = e.target.value}> Low https://svelte.dev/docs/element-directives#bind-property
12 11 Bindings Bind to DOM elements Reference DOM nodes bind:this for element reference querySelector in onMount <div bind:this={el}> onMount(() => el = document.querySelector()) Medium
13 12 Bindings Use bind:group for radios/checkboxes Simplified group handling bind:group for radio/checkbox groups Manual checked handling <input type="radio" bind:group={selected}> <input type="radio" checked={selected === value}> Low
14 13 Events Use on: for event handlers Event directive syntax on:click={handler} addEventListener in onMount <button on:click={handleClick}> onMount(() => btn.addEventListener()) Medium https://svelte.dev/docs/element-directives#on-eventname
15 14 Events Forward events with on:event Pass events to parent on:click without handler createEventDispatcher for DOM events <button on:click> dispatch('click', event) Low
16 15 Events Use createEventDispatcher Custom component events dispatch for custom events on:event for custom events dispatch('save', { data }) on:save without dispatch Medium https://svelte.dev/docs/svelte#createeventdispatcher
17 16 Lifecycle Use onMount for initialization Run code after component mounts onMount for setup and data fetching Code in script body for side effects onMount(() => fetchData()) fetchData() in script body High https://svelte.dev/docs/svelte#onmount
18 17 Lifecycle Return cleanup from onMount Automatic cleanup on destroy Return function from onMount Separate onDestroy for paired cleanup onMount(() => { sub(); return unsub }) onMount(sub); onDestroy(unsub) Medium
19 18 Lifecycle Use onDestroy sparingly Only when onMount cleanup not possible onDestroy for non-mount cleanup onDestroy for mount-related cleanup onDestroy for store unsubscribe onDestroy(() => clearInterval(id)) Low
20 19 Lifecycle Avoid beforeUpdate/afterUpdate Usually not needed Reactive statements instead beforeUpdate for derived state $: if (x) doSomething() beforeUpdate(() => doSomething()) Low
21 20 Stores Use writable for mutable state Basic reactive store writable for shared mutable state Local variables for shared state const count = writable(0) let count = 0 in module Medium https://svelte.dev/docs/svelte-store#writable
22 21 Stores Use readable for read-only state External data sources readable for derived/external data writable for read-only data readable(0, set => interval(set)) writable(0) for timer Low https://svelte.dev/docs/svelte-store#readable
23 22 Stores Use derived for computed stores Combine or transform stores derived for computed values Manual subscription for derived derived(count, $c => $c * 2) count.subscribe(c => doubled = c * 2) Medium https://svelte.dev/docs/svelte-store#derived
24 23 Stores Use $ prefix for auto-subscription Automatic subscribe/unsubscribe $storeName in components Manual subscription {$count} count.subscribe(c => value = c) High
25 24 Stores Clean up custom subscriptions Unsubscribe when component destroys Return unsubscribe from onMount Leave subscriptions open onMount(() => store.subscribe(fn)) store.subscribe(fn) in script High
26 25 Slots Use slots for composition Content projection <slot> for flexible content Props for all content <slot>Default</slot> <Component content="text"/> Medium https://svelte.dev/docs/special-elements#slot
27 26 Slots Name slots for multiple areas Multiple content areas <slot name="header"> Single slot for complex layouts <slot name="header"><slot name="footer"> <slot> with complex conditionals Low
28 27 Slots Check slot content with $$slots Conditional slot rendering $$slots.name for conditional rendering Always render slot wrapper {#if $$slots.footer}<slot name="footer"/>{/if} <div><slot name="footer"/></div> Low
29 28 Styling Use scoped styles by default Styles scoped to component <style> for component styles Global styles for component :global() only when needed <style> all global Medium https://svelte.dev/docs/svelte-components#style
30 29 Styling Use :global() sparingly Escape scoping when needed :global for third-party styling Global for all styles :global(.external-lib) <style> without scoping Medium
31 30 Styling Use CSS variables for theming Dynamic styling CSS custom properties Inline styles for themes style="--color: {color}" style="color: {color}" Low
32 31 Transitions Use built-in transitions Svelte transition directives transition:fade for simple effects Manual CSS transitions <div transition:fade> <div class:fade={visible}> Low https://svelte.dev/docs/element-directives#transition-fn
33 32 Transitions Use in: and out: separately Different enter/exit animations in:fly out:fade for asymmetric Same transition for both <div in:fly out:fade> <div transition:fly> Low
34 33 Transitions Add local modifier Prevent ancestor trigger transition:fade|local Global transitions for lists <div transition:slide|local> <div transition:slide> Medium
35 34 Actions Use actions for DOM behavior Reusable DOM logic use:action for DOM enhancements onMount for each usage <div use:clickOutside> onMount(() => setupClickOutside(el)) Medium https://svelte.dev/docs/element-directives#use-action
36 35 Actions Return update and destroy Lifecycle methods for actions Return { update, destroy } Only initial setup return { update(params) {}, destroy() {} } return destroy only Medium
37 36 Actions Pass parameters to actions Configure action behavior use:action={params} Hardcoded action behavior <div use:tooltip={options}> <div use:tooltip> Low
38 37 Logic Use {#if} for conditionals Template conditionals {#if} {:else if} {:else} Ternary in expressions {#if cond}...{:else}...{/if} {cond ? a : b} for complex Low https://svelte.dev/docs/logic-blocks#if
39 38 Logic Use {#each} for lists List rendering {#each} with key Map in expression {#each items as item (item.id)} {items.map(i => `<div>${i}</div>`)} Medium
40 39 Logic Always use keys in {#each} Proper list reconciliation (item.id) for unique key Index as key or no key {#each items as item (item.id)} {#each items as item, i (i)} High
41 40 Logic Use {#await} for promises Handle async states {#await} for loading/error states Manual promise handling {#await promise}...{:then}...{:catch} {#if loading}...{#if error} Medium https://svelte.dev/docs/logic-blocks#await
42 41 SvelteKit Use +page.svelte for routes File-based routing +page.svelte for route components Custom routing setup routes/about/+page.svelte routes/About.svelte Medium https://kit.svelte.dev/docs/routing
43 42 SvelteKit Use +page.js for data loading Load data before render load function in +page.js onMount for data fetching export function load() {} onMount(() => fetchData()) High https://kit.svelte.dev/docs/load
44 43 SvelteKit Use +page.server.js for server-only Server-side data loading +page.server.js for sensitive data +page.js for API keys +page.server.js with DB access +page.js with DB access High
45 44 SvelteKit Use form actions Server-side form handling +page.server.js actions API routes for forms export const actions = { default } fetch('/api/submit') Medium https://kit.svelte.dev/docs/form-actions
46 45 SvelteKit Use $app/stores for app state $page $navigating $updated $page for current page data Manual URL parsing import { page } from '$app/stores' window.location.pathname Medium https://kit.svelte.dev/docs/modules#$app-stores
47 46 Performance Use {#key} for forced re-render Reset component state {#key id} for fresh instance Manual destroy/create {#key item.id}<Component/>{/key} on:change={() => component = null} Low https://svelte.dev/docs/logic-blocks#key
48 47 Performance Avoid unnecessary reactivity Not everything needs $: $: only for side effects $: for simple assignments $: if (x) console.log(x) $: y = x (when y = x works) Low
49 48 Performance Use immutable compiler option Skip equality checks immutable: true for large lists Default for all components <svelte:options immutable/> Default without immutable Low
50 49 TypeScript Use lang="ts" in script TypeScript support <script lang="ts"> JavaScript for typed projects <script lang="ts"> <script> with JSDoc Medium https://svelte.dev/docs/typescript
51 50 TypeScript Type props with interface Explicit prop types interface $$Props for types Untyped props interface $$Props { name: string } export let name Medium
52 51 TypeScript Type events with createEventDispatcher Type-safe events createEventDispatcher<Events>() Untyped dispatch createEventDispatcher<{ save: Data }>() createEventDispatcher() Medium
53 52 Accessibility Use semantic elements Proper HTML in templates button nav main appropriately div for everything <button on:click> <div on:click> High
54 53 Accessibility Add aria to dynamic content Accessible state changes aria-live for updates Silent dynamic updates <div aria-live="polite">{message}</div> <div>{message}</div> Medium

View File

@@ -0,0 +1,51 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,Views,Use struct for views,SwiftUI views are value types,struct MyView: View,class MyView: View,struct ContentView: View { var body: some View },class ContentView: View,High,https://developer.apple.com/documentation/swiftui/view
2,Views,Keep views small and focused,Single responsibility for each view,Extract subviews for complex layouts,Large monolithic views,Extract HeaderView FooterView,500+ line View struct,Medium,
3,Views,Use body computed property,body returns the view hierarchy,var body: some View { },func body() -> some View,"var body: some View { Text(""Hello"") }",func body() -> Text,High,
4,Views,Prefer composition over inheritance,Compose views using ViewBuilder,Combine smaller views,Inheritance hierarchies,VStack { Header() Content() },class SpecialView extends BaseView,Medium,
5,State,Use @State for local state,Simple value types owned by view,@State for view-local primitives,@State for shared data,@State private var count = 0,@State var sharedData: Model,High,https://developer.apple.com/documentation/swiftui/state
6,State,Use @Binding for two-way data,Pass mutable state to child views,@Binding for child input,@State in child for parent data,@Binding var isOn: Bool,$isOn to pass binding,Medium,https://developer.apple.com/documentation/swiftui/binding
7,State,Use @StateObject for reference types,ObservableObject owned by view,@StateObject for view-created objects,@ObservedObject for owned objects,@StateObject private var vm = ViewModel(),@ObservedObject var vm = ViewModel(),High,https://developer.apple.com/documentation/swiftui/stateobject
8,State,Use @ObservedObject for injected objects,Reference types passed from parent,@ObservedObject for injected dependencies,@StateObject for injected objects,@ObservedObject var vm: ViewModel,@StateObject var vm: ViewModel (injected),High,https://developer.apple.com/documentation/swiftui/observedobject
9,State,Use @EnvironmentObject for shared state,App-wide state injection,@EnvironmentObject for global state,Prop drilling through views,@EnvironmentObject var settings: Settings,Pass settings through 5 views,Medium,https://developer.apple.com/documentation/swiftui/environmentobject
10,State,Use @Published in ObservableObject,Automatically publish property changes,@Published for observed properties,Manual objectWillChange calls,@Published var items: [Item] = [],var items: [Item] { didSet { objectWillChange.send() } },Medium,
11,Observable,Use @Observable macro (iOS 17+),Modern observation without Combine,@Observable class for view models,ObservableObject for new projects,@Observable class ViewModel { },class ViewModel: ObservableObject,Medium,https://developer.apple.com/documentation/observation
12,Observable,Use @Bindable for @Observable,Create bindings from @Observable,@Bindable var vm for bindings,@Binding with @Observable,@Bindable var viewModel,$viewModel.name with @Observable,Medium,
13,Layout,Use VStack HStack ZStack,Standard stack-based layouts,Stacks for linear arrangements,GeometryReader for simple layouts,VStack { Text() Image() },GeometryReader for vertical list,Medium,https://developer.apple.com/documentation/swiftui/vstack
14,Layout,Use LazyVStack LazyHStack for lists,Lazy loading for performance,Lazy stacks for long lists,Regular stacks for 100+ items,LazyVStack { ForEach(items) },VStack { ForEach(largeArray) },High,https://developer.apple.com/documentation/swiftui/lazyvstack
15,Layout,Use GeometryReader sparingly,Only when needed for sizing,GeometryReader for responsive layouts,GeometryReader everywhere,GeometryReader for aspect ratio,GeometryReader wrapping everything,Medium,
16,Layout,Use spacing and padding consistently,Consistent spacing throughout app,Design system spacing values,Magic numbers for spacing,.padding(16) or .padding(),".padding(13), .padding(17)",Low,
17,Layout,Use frame modifiers correctly,Set explicit sizes when needed,.frame(maxWidth: .infinity),Fixed sizes for responsive content,.frame(maxWidth: .infinity),.frame(width: 375),Medium,
18,Modifiers,Order modifiers correctly,Modifier order affects rendering,Background before padding for full coverage,Wrong modifier order,.padding().background(Color.red),.background(Color.red).padding(),High,
19,Modifiers,Create custom ViewModifiers,Reusable modifier combinations,ViewModifier for repeated styling,Duplicate modifier chains,struct CardStyle: ViewModifier,.shadow().cornerRadius() everywhere,Medium,https://developer.apple.com/documentation/swiftui/viewmodifier
20,Modifiers,Use conditional modifiers carefully,Avoid changing view identity,if-else with same view type,Conditional that changes view identity,Text(title).foregroundColor(isActive ? .blue : .gray),if isActive { Text().bold() } else { Text() },Medium,
21,Navigation,Use NavigationStack (iOS 16+),Modern navigation with type-safe paths,NavigationStack with navigationDestination,NavigationView for new projects,NavigationStack { },NavigationView { } (deprecated),Medium,https://developer.apple.com/documentation/swiftui/navigationstack
22,Navigation,Use navigationDestination,Type-safe navigation destinations,.navigationDestination(for:),NavigationLink(destination:),.navigationDestination(for: Item.self),NavigationLink(destination: DetailView()),Medium,
23,Navigation,Use @Environment for dismiss,Programmatic navigation dismissal,@Environment(\.dismiss) var dismiss,presentationMode (deprecated),@Environment(\.dismiss) var dismiss,@Environment(\.presentationMode),Low,
24,Lists,Use List for scrollable content,Built-in scrolling and styling,List for standard scrollable content,ScrollView + VStack for simple lists,List { ForEach(items) { } },ScrollView { VStack { ForEach } },Low,https://developer.apple.com/documentation/swiftui/list
25,Lists,Provide stable identifiers,Use Identifiable or explicit id,Identifiable protocol or id parameter,Index as identifier,ForEach(items) where Item: Identifiable,"ForEach(items.indices, id: \.self)",High,
26,Lists,Use onDelete and onMove,Standard list editing,onDelete for swipe to delete,Custom delete implementation,.onDelete(perform: delete),.onTapGesture for delete,Low,
27,Forms,Use Form for settings,Grouped input controls,Form for settings screens,Manual grouping for forms,Form { Section { Toggle() } },VStack { Toggle() },Low,https://developer.apple.com/documentation/swiftui/form
28,Forms,Use @FocusState for keyboard,Manage keyboard focus,@FocusState for text field focus,Manual first responder handling,@FocusState private var isFocused: Bool,UIKit first responder,Medium,https://developer.apple.com/documentation/swiftui/focusstate
29,Forms,Validate input properly,Show validation feedback,Real-time validation feedback,Submit without validation,TextField with validation state,TextField without error handling,Medium,
30,Async,Use .task for async work,Automatic cancellation on view disappear,.task for view lifecycle async,onAppear with Task,.task { await loadData() },onAppear { Task { await loadData() } },Medium,https://developer.apple.com/documentation/swiftui/view/task(priority:_:)
31,Async,Handle loading states,Show progress during async operations,ProgressView during loading,Empty view during load,if isLoading { ProgressView() },No loading indicator,Medium,
32,Async,Use @MainActor for UI updates,Ensure UI updates on main thread,@MainActor on view models,Manual DispatchQueue.main,@MainActor class ViewModel,DispatchQueue.main.async,Medium,
33,Animation,Use withAnimation,Animate state changes,withAnimation for state transitions,No animation for state changes,withAnimation { isExpanded.toggle() },isExpanded.toggle(),Low,https://developer.apple.com/documentation/swiftui/withanimation(_:_:)
34,Animation,Use .animation modifier,Apply animations to views,.animation(.spring()) on view,Manual animation timing,.animation(.easeInOut),CABasicAnimation equivalent,Low,
35,Animation,Respect reduced motion,Check accessibility settings,Check accessibilityReduceMotion,Ignore motion preferences,@Environment(\.accessibilityReduceMotion),Always animate regardless,High,
36,Preview,Use #Preview macro (Xcode 15+),Modern preview syntax,#Preview for view previews,PreviewProvider protocol,#Preview { ContentView() },struct ContentView_Previews: PreviewProvider,Low,
37,Preview,Create multiple previews,Test different states and devices,Multiple previews for states,Single preview only,"#Preview(""Light"") { } #Preview(""Dark"") { }",Single preview configuration,Low,
38,Preview,Use preview data,Dedicated preview mock data,Static preview data,Production data in previews,Item.preview for preview,Fetch real data in preview,Low,
39,Performance,Avoid expensive body computations,Body should be fast to compute,Precompute in view model,Heavy computation in body,vm.computedValue in body,Complex calculation in body,High,
40,Performance,Use Equatable views,Skip unnecessary view updates,Equatable for complex views,Default equality for all views,struct MyView: View Equatable,No Equatable conformance,Medium,
41,Performance,Profile with Instruments,Measure before optimizing,Use SwiftUI Instruments,Guess at performance issues,Profile with Instruments,Optimize without measuring,Medium,
42,Accessibility,Add accessibility labels,Describe UI elements,.accessibilityLabel for context,Missing labels,".accessibilityLabel(""Close button"")",Button without label,High,https://developer.apple.com/documentation/swiftui/view/accessibilitylabel(_:)-1d7jv
43,Accessibility,Support Dynamic Type,Respect text size preferences,Scalable fonts and layouts,Fixed font sizes,.font(.body) with Dynamic Type,.font(.system(size: 16)),High,
44,Accessibility,Use semantic views,Proper accessibility traits,Correct accessibilityTraits,Wrong semantic meaning,Button for actions Image for display,Image that acts like button,Medium,
45,Testing,Use ViewInspector for testing,Third-party view testing,ViewInspector for unit tests,UI tests only,ViewInspector assertions,Only XCUITest,Medium,
46,Testing,Test view models,Unit test business logic,XCTest for view model,Skip view model testing,Test ViewModel methods,No unit tests,Medium,
47,Testing,Use preview as visual test,Previews catch visual regressions,Multiple preview configurations,No visual verification,Preview different states,Single preview only,Low,
48,Architecture,Use MVVM pattern,Separate view and logic,ViewModel for business logic,Logic in View,ObservableObject ViewModel,@State for complex logic,Medium,
49,Architecture,Keep views dumb,Views display view model state,View reads from ViewModel,Business logic in View,view.items from vm.items,Complex filtering in View,Medium,
50,Architecture,Use dependency injection,Inject dependencies for testing,Initialize with dependencies,Hard-coded dependencies,init(service: ServiceProtocol),let service = RealService(),Medium,
1 No Category Guideline Description Do Don't Code Good Code Bad Severity Docs URL
2 1 Views Use struct for views SwiftUI views are value types struct MyView: View class MyView: View struct ContentView: View { var body: some View } class ContentView: View High https://developer.apple.com/documentation/swiftui/view
3 2 Views Keep views small and focused Single responsibility for each view Extract subviews for complex layouts Large monolithic views Extract HeaderView FooterView 500+ line View struct Medium
4 3 Views Use body computed property body returns the view hierarchy var body: some View { } func body() -> some View var body: some View { Text("Hello") } func body() -> Text High
5 4 Views Prefer composition over inheritance Compose views using ViewBuilder Combine smaller views Inheritance hierarchies VStack { Header() Content() } class SpecialView extends BaseView Medium
6 5 State Use @State for local state Simple value types owned by view @State for view-local primitives @State for shared data @State private var count = 0 @State var sharedData: Model High https://developer.apple.com/documentation/swiftui/state
7 6 State Use @Binding for two-way data Pass mutable state to child views @Binding for child input @State in child for parent data @Binding var isOn: Bool $isOn to pass binding Medium https://developer.apple.com/documentation/swiftui/binding
8 7 State Use @StateObject for reference types ObservableObject owned by view @StateObject for view-created objects @ObservedObject for owned objects @StateObject private var vm = ViewModel() @ObservedObject var vm = ViewModel() High https://developer.apple.com/documentation/swiftui/stateobject
9 8 State Use @ObservedObject for injected objects Reference types passed from parent @ObservedObject for injected dependencies @StateObject for injected objects @ObservedObject var vm: ViewModel @StateObject var vm: ViewModel (injected) High https://developer.apple.com/documentation/swiftui/observedobject
10 9 State Use @EnvironmentObject for shared state App-wide state injection @EnvironmentObject for global state Prop drilling through views @EnvironmentObject var settings: Settings Pass settings through 5 views Medium https://developer.apple.com/documentation/swiftui/environmentobject
11 10 State Use @Published in ObservableObject Automatically publish property changes @Published for observed properties Manual objectWillChange calls @Published var items: [Item] = [] var items: [Item] { didSet { objectWillChange.send() } } Medium
12 11 Observable Use @Observable macro (iOS 17+) Modern observation without Combine @Observable class for view models ObservableObject for new projects @Observable class ViewModel { } class ViewModel: ObservableObject Medium https://developer.apple.com/documentation/observation
13 12 Observable Use @Bindable for @Observable Create bindings from @Observable @Bindable var vm for bindings @Binding with @Observable @Bindable var viewModel $viewModel.name with @Observable Medium
14 13 Layout Use VStack HStack ZStack Standard stack-based layouts Stacks for linear arrangements GeometryReader for simple layouts VStack { Text() Image() } GeometryReader for vertical list Medium https://developer.apple.com/documentation/swiftui/vstack
15 14 Layout Use LazyVStack LazyHStack for lists Lazy loading for performance Lazy stacks for long lists Regular stacks for 100+ items LazyVStack { ForEach(items) } VStack { ForEach(largeArray) } High https://developer.apple.com/documentation/swiftui/lazyvstack
16 15 Layout Use GeometryReader sparingly Only when needed for sizing GeometryReader for responsive layouts GeometryReader everywhere GeometryReader for aspect ratio GeometryReader wrapping everything Medium
17 16 Layout Use spacing and padding consistently Consistent spacing throughout app Design system spacing values Magic numbers for spacing .padding(16) or .padding() .padding(13), .padding(17) Low
18 17 Layout Use frame modifiers correctly Set explicit sizes when needed .frame(maxWidth: .infinity) Fixed sizes for responsive content .frame(maxWidth: .infinity) .frame(width: 375) Medium
19 18 Modifiers Order modifiers correctly Modifier order affects rendering Background before padding for full coverage Wrong modifier order .padding().background(Color.red) .background(Color.red).padding() High
20 19 Modifiers Create custom ViewModifiers Reusable modifier combinations ViewModifier for repeated styling Duplicate modifier chains struct CardStyle: ViewModifier .shadow().cornerRadius() everywhere Medium https://developer.apple.com/documentation/swiftui/viewmodifier
21 20 Modifiers Use conditional modifiers carefully Avoid changing view identity if-else with same view type Conditional that changes view identity Text(title).foregroundColor(isActive ? .blue : .gray) if isActive { Text().bold() } else { Text() } Medium
22 21 Navigation Use NavigationStack (iOS 16+) Modern navigation with type-safe paths NavigationStack with navigationDestination NavigationView for new projects NavigationStack { } NavigationView { } (deprecated) Medium https://developer.apple.com/documentation/swiftui/navigationstack
23 22 Navigation Use navigationDestination Type-safe navigation destinations .navigationDestination(for:) NavigationLink(destination:) .navigationDestination(for: Item.self) NavigationLink(destination: DetailView()) Medium
24 23 Navigation Use @Environment for dismiss Programmatic navigation dismissal @Environment(\.dismiss) var dismiss presentationMode (deprecated) @Environment(\.dismiss) var dismiss @Environment(\.presentationMode) Low
25 24 Lists Use List for scrollable content Built-in scrolling and styling List for standard scrollable content ScrollView + VStack for simple lists List { ForEach(items) { } } ScrollView { VStack { ForEach } } Low https://developer.apple.com/documentation/swiftui/list
26 25 Lists Provide stable identifiers Use Identifiable or explicit id Identifiable protocol or id parameter Index as identifier ForEach(items) where Item: Identifiable ForEach(items.indices, id: \.self) High
27 26 Lists Use onDelete and onMove Standard list editing onDelete for swipe to delete Custom delete implementation .onDelete(perform: delete) .onTapGesture for delete Low
28 27 Forms Use Form for settings Grouped input controls Form for settings screens Manual grouping for forms Form { Section { Toggle() } } VStack { Toggle() } Low https://developer.apple.com/documentation/swiftui/form
29 28 Forms Use @FocusState for keyboard Manage keyboard focus @FocusState for text field focus Manual first responder handling @FocusState private var isFocused: Bool UIKit first responder Medium https://developer.apple.com/documentation/swiftui/focusstate
30 29 Forms Validate input properly Show validation feedback Real-time validation feedback Submit without validation TextField with validation state TextField without error handling Medium
31 30 Async Use .task for async work Automatic cancellation on view disappear .task for view lifecycle async onAppear with Task .task { await loadData() } onAppear { Task { await loadData() } } Medium https://developer.apple.com/documentation/swiftui/view/task(priority:_:)
32 31 Async Handle loading states Show progress during async operations ProgressView during loading Empty view during load if isLoading { ProgressView() } No loading indicator Medium
33 32 Async Use @MainActor for UI updates Ensure UI updates on main thread @MainActor on view models Manual DispatchQueue.main @MainActor class ViewModel DispatchQueue.main.async Medium
34 33 Animation Use withAnimation Animate state changes withAnimation for state transitions No animation for state changes withAnimation { isExpanded.toggle() } isExpanded.toggle() Low https://developer.apple.com/documentation/swiftui/withanimation(_:_:)
35 34 Animation Use .animation modifier Apply animations to views .animation(.spring()) on view Manual animation timing .animation(.easeInOut) CABasicAnimation equivalent Low
36 35 Animation Respect reduced motion Check accessibility settings Check accessibilityReduceMotion Ignore motion preferences @Environment(\.accessibilityReduceMotion) Always animate regardless High
37 36 Preview Use #Preview macro (Xcode 15+) Modern preview syntax #Preview for view previews PreviewProvider protocol #Preview { ContentView() } struct ContentView_Previews: PreviewProvider Low
38 37 Preview Create multiple previews Test different states and devices Multiple previews for states Single preview only #Preview("Light") { } #Preview("Dark") { } Single preview configuration Low
39 38 Preview Use preview data Dedicated preview mock data Static preview data Production data in previews Item.preview for preview Fetch real data in preview Low
40 39 Performance Avoid expensive body computations Body should be fast to compute Precompute in view model Heavy computation in body vm.computedValue in body Complex calculation in body High
41 40 Performance Use Equatable views Skip unnecessary view updates Equatable for complex views Default equality for all views struct MyView: View Equatable No Equatable conformance Medium
42 41 Performance Profile with Instruments Measure before optimizing Use SwiftUI Instruments Guess at performance issues Profile with Instruments Optimize without measuring Medium
43 42 Accessibility Add accessibility labels Describe UI elements .accessibilityLabel for context Missing labels .accessibilityLabel("Close button") Button without label High https://developer.apple.com/documentation/swiftui/view/accessibilitylabel(_:)-1d7jv
44 43 Accessibility Support Dynamic Type Respect text size preferences Scalable fonts and layouts Fixed font sizes .font(.body) with Dynamic Type .font(.system(size: 16)) High
45 44 Accessibility Use semantic views Proper accessibility traits Correct accessibilityTraits Wrong semantic meaning Button for actions Image for display Image that acts like button Medium
46 45 Testing Use ViewInspector for testing Third-party view testing ViewInspector for unit tests UI tests only ViewInspector assertions Only XCUITest Medium
47 46 Testing Test view models Unit test business logic XCTest for view model Skip view model testing Test ViewModel methods No unit tests Medium
48 47 Testing Use preview as visual test Previews catch visual regressions Multiple preview configurations No visual verification Preview different states Single preview only Low
49 48 Architecture Use MVVM pattern Separate view and logic ViewModel for business logic Logic in View ObservableObject ViewModel @State for complex logic Medium
50 49 Architecture Keep views dumb Views display view model state View reads from ViewModel Business logic in View view.items from vm.items Complex filtering in View Medium
51 50 Architecture Use dependency injection Inject dependencies for testing Initialize with dependencies Hard-coded dependencies init(service: ServiceProtocol) let service = RealService() Medium

View File

@@ -0,0 +1,50 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,Composition,Use Composition API for new projects,Composition API offers better TypeScript support and logic reuse,<script setup> for components,Options API for new projects,<script setup>,export default { data() },Medium,https://vuejs.org/guide/extras/composition-api-faq.html
2,Composition,Use script setup syntax,Cleaner syntax with automatic exports,<script setup> with defineProps,setup() function manually,<script setup>,<script> setup() { return {} },Low,https://vuejs.org/api/sfc-script-setup.html
3,Reactivity,Use ref for primitives,ref() for primitive values that need reactivity,ref() for strings numbers booleans,reactive() for primitives,const count = ref(0),const count = reactive(0),Medium,https://vuejs.org/guide/essentials/reactivity-fundamentals.html
4,Reactivity,Use reactive for objects,reactive() for complex objects and arrays,reactive() for objects with multiple properties,ref() for complex objects,const state = reactive({ user: null }),const state = ref({ user: null }),Medium,
5,Reactivity,Access ref values with .value,Remember .value in script unwrap in template,Use .value in script,Forget .value in script,count.value++,count++ (in script),High,
6,Reactivity,Use computed for derived state,Computed properties cache and update automatically,computed() for derived values,Methods for derived values,const doubled = computed(() => count.value * 2),const doubled = () => count.value * 2,Medium,https://vuejs.org/guide/essentials/computed.html
7,Reactivity,Use shallowRef for large objects,Avoid deep reactivity for performance,shallowRef for large data structures,ref for large nested objects,const bigData = shallowRef(largeObject),const bigData = ref(largeObject),Medium,https://vuejs.org/api/reactivity-advanced.html#shallowref
8,Watchers,Use watchEffect for simple cases,Auto-tracks dependencies,watchEffect for simple reactive effects,watch with explicit deps when not needed,watchEffect(() => console.log(count.value)),"watch(count, (val) => console.log(val))",Low,https://vuejs.org/guide/essentials/watchers.html
9,Watchers,Use watch for specific sources,Explicit control over what to watch,watch with specific refs,watchEffect for complex conditional logic,"watch(userId, fetchUser)",watchEffect with conditionals,Medium,
10,Watchers,Clean up side effects,Return cleanup function in watchers,Return cleanup in watchEffect,Leave subscriptions open,watchEffect((onCleanup) => { onCleanup(unsub) }),watchEffect without cleanup,High,
11,Props,Define props with defineProps,Type-safe prop definitions,defineProps with TypeScript,Props without types,defineProps<{ msg: string }>(),defineProps(['msg']),Medium,https://vuejs.org/guide/typescript/composition-api.html#typing-component-props
12,Props,Use withDefaults for default values,Provide defaults for optional props,withDefaults with defineProps,Defaults in destructuring,"withDefaults(defineProps<Props>(), { count: 0 })",const { count = 0 } = defineProps(),Medium,
13,Props,Avoid mutating props,Props should be read-only,Emit events to parent for changes,Direct prop mutation,"emit('update:modelValue', newVal)",props.modelValue = newVal,High,
14,Emits,Define emits with defineEmits,Type-safe event emissions,defineEmits with types,Emit without definition,defineEmits<{ change: [id: number] }>(),"emit('change', id) without define",Medium,https://vuejs.org/guide/typescript/composition-api.html#typing-component-emits
15,Emits,Use v-model for two-way binding,Simplified parent-child data flow,v-model with modelValue prop,:value + @input manually,"<Child v-model=""value""/>","<Child :value=""value"" @input=""value = $event""/>",Low,https://vuejs.org/guide/components/v-model.html
16,Lifecycle,Use onMounted for DOM access,DOM is ready in onMounted,onMounted for DOM operations,Access DOM in setup directly,onMounted(() => el.value.focus()),el.value.focus() in setup,High,https://vuejs.org/api/composition-api-lifecycle.html
17,Lifecycle,Clean up in onUnmounted,Remove listeners and subscriptions,onUnmounted for cleanup,Leave listeners attached,onUnmounted(() => window.removeEventListener()),No cleanup on unmount,High,
18,Lifecycle,Avoid onBeforeMount for data,Use onMounted or setup for data fetching,Fetch in onMounted or setup,Fetch in onBeforeMount,onMounted(async () => await fetchData()),onBeforeMount(async () => await fetchData()),Low,
19,Components,Use single-file components,Keep template script style together,.vue files for components,Separate template/script files,Component.vue with all parts,Component.js + Component.html,Low,
20,Components,Use PascalCase for components,Consistent component naming,PascalCase in imports and templates,kebab-case in script,<MyComponent/>,<my-component/>,Low,https://vuejs.org/style-guide/rules-strongly-recommended.html
21,Components,Prefer composition over mixins,Composables replace mixins,Composables for shared logic,Mixins for code reuse,const { data } = useApi(),mixins: [apiMixin],Medium,
22,Composables,Name composables with use prefix,Convention for composable functions,useFetch useAuth useForm,getData or fetchApi,export function useFetch(),export function fetchData(),Medium,https://vuejs.org/guide/reusability/composables.html
23,Composables,Return refs from composables,Maintain reactivity when destructuring,Return ref values,Return reactive objects that lose reactivity,return { data: ref(null) },return reactive({ data: null }),Medium,
24,Composables,Accept ref or value params,Use toValue for flexible inputs,toValue() or unref() for params,Only accept ref or only value,const val = toValue(maybeRef),const val = maybeRef.value,Low,https://vuejs.org/api/reactivity-utilities.html#tovalue
25,Templates,Use v-bind shorthand,Cleaner template syntax,:prop instead of v-bind:prop,Full v-bind syntax,"<div :class=""cls"">","<div v-bind:class=""cls"">",Low,
26,Templates,Use v-on shorthand,Cleaner event binding,@event instead of v-on:event,Full v-on syntax,"<button @click=""handler"">","<button v-on:click=""handler"">",Low,
27,Templates,Avoid v-if with v-for,v-if has higher priority causes issues,Wrap in template or computed filter,v-if on same element as v-for,<template v-for><div v-if>,<div v-for v-if>,High,https://vuejs.org/style-guide/rules-essential.html#avoid-v-if-with-v-for
28,Templates,Use key with v-for,Proper list rendering and updates,Unique key for each item,Index as key for dynamic lists,"v-for=""item in items"" :key=""item.id""","v-for=""(item, i) in items"" :key=""i""",High,
29,State,Use Pinia for global state,Official state management for Vue 3,Pinia stores for shared state,Vuex for new projects,const store = useCounterStore(),Vuex with mutations,Medium,https://pinia.vuejs.org/
30,State,Define stores with defineStore,Composition API style stores,Setup stores with defineStore,Options stores for complex state,"defineStore('counter', () => {})","defineStore('counter', { state })",Low,
31,State,Use storeToRefs for destructuring,Maintain reactivity when destructuring,storeToRefs(store),Direct destructuring,const { count } = storeToRefs(store),const { count } = store,High,https://pinia.vuejs.org/core-concepts/#destructuring-from-a-store
32,Routing,Use useRouter and useRoute,Composition API router access,useRouter() useRoute() in setup,this.$router this.$route,const router = useRouter(),this.$router.push(),Medium,https://router.vuejs.org/guide/advanced/composition-api.html
33,Routing,Lazy load route components,Code splitting for routes,() => import() for components,Static imports for all routes,component: () => import('./Page.vue'),component: Page,Medium,https://router.vuejs.org/guide/advanced/lazy-loading.html
34,Routing,Use navigation guards,Protect routes and handle redirects,beforeEach for auth checks,Check auth in each component,router.beforeEach((to) => {}),Check auth in onMounted,Medium,
35,Performance,Use v-once for static content,Skip re-renders for static elements,v-once on never-changing content,v-once on dynamic content,<div v-once>{{ staticText }}</div>,<div v-once>{{ dynamicText }}</div>,Low,https://vuejs.org/api/built-in-directives.html#v-once
36,Performance,Use v-memo for expensive lists,Memoize list items,v-memo with dependency array,Re-render entire list always,"<div v-for v-memo=""[item.id]"">",<div v-for> without memo,Medium,https://vuejs.org/api/built-in-directives.html#v-memo
37,Performance,Use shallowReactive for flat objects,Avoid deep reactivity overhead,shallowReactive for flat state,reactive for simple objects,shallowReactive({ count: 0 }),reactive({ count: 0 }),Low,
38,Performance,Use defineAsyncComponent,Lazy load heavy components,defineAsyncComponent for modals dialogs,Import all components eagerly,defineAsyncComponent(() => import()),import HeavyComponent from,Medium,https://vuejs.org/guide/components/async.html
39,TypeScript,Use generic components,Type-safe reusable components,Generic with defineComponent,Any types in components,"<script setup lang=""ts"" generic=""T"">",<script setup> without types,Medium,https://vuejs.org/guide/typescript/composition-api.html
40,TypeScript,Type template refs,Proper typing for DOM refs,ref<HTMLInputElement>(null),ref(null) without type,const input = ref<HTMLInputElement>(null),const input = ref(null),Medium,
41,TypeScript,Use PropType for complex props,Type complex prop types,PropType<User> for object props,Object without type,type: Object as PropType<User>,type: Object,Medium,
42,Testing,Use Vue Test Utils,Official testing library,mount shallowMount for components,Manual DOM testing,import { mount } from '@vue/test-utils',document.createElement,Medium,https://test-utils.vuejs.org/
43,Testing,Test component behavior,Focus on inputs and outputs,Test props emit and rendered output,Test internal implementation,expect(wrapper.text()).toContain(),expect(wrapper.vm.internalState),Medium,
44,Forms,Use v-model modifiers,Built-in input handling,.lazy .number .trim modifiers,Manual input parsing,"<input v-model.number=""age"">","<input v-model=""age""> then parse",Low,https://vuejs.org/guide/essentials/forms.html#modifiers
45,Forms,Use VeeValidate or FormKit,Form validation libraries,VeeValidate for complex forms,Manual validation logic,useField useForm from vee-validate,Custom validation in each input,Medium,
46,Accessibility,Use semantic elements,Proper HTML elements in templates,button nav main for purpose,div for everything,<button @click>,<div @click>,High,
47,Accessibility,Bind aria attributes dynamically,Keep ARIA in sync with state,":aria-expanded=""isOpen""",Static ARIA values,":aria-expanded=""menuOpen""","aria-expanded=""true""",Medium,
48,SSR,Use Nuxt for SSR,Full-featured SSR framework,Nuxt 3 for SSR apps,Manual SSR setup,npx nuxi init my-app,Custom SSR configuration,Medium,https://nuxt.com/
49,SSR,Handle hydration mismatches,Client/server content must match,ClientOnly for browser-only content,Different content server/client,<ClientOnly><BrowserWidget/></ClientOnly>,<div>{{ Date.now() }}</div>,High,
1 No Category Guideline Description Do Don't Code Good Code Bad Severity Docs URL
2 1 Composition Use Composition API for new projects Composition API offers better TypeScript support and logic reuse <script setup> for components Options API for new projects <script setup> export default { data() } Medium https://vuejs.org/guide/extras/composition-api-faq.html
3 2 Composition Use script setup syntax Cleaner syntax with automatic exports <script setup> with defineProps setup() function manually <script setup> <script> setup() { return {} } Low https://vuejs.org/api/sfc-script-setup.html
4 3 Reactivity Use ref for primitives ref() for primitive values that need reactivity ref() for strings numbers booleans reactive() for primitives const count = ref(0) const count = reactive(0) Medium https://vuejs.org/guide/essentials/reactivity-fundamentals.html
5 4 Reactivity Use reactive for objects reactive() for complex objects and arrays reactive() for objects with multiple properties ref() for complex objects const state = reactive({ user: null }) const state = ref({ user: null }) Medium
6 5 Reactivity Access ref values with .value Remember .value in script unwrap in template Use .value in script Forget .value in script count.value++ count++ (in script) High
7 6 Reactivity Use computed for derived state Computed properties cache and update automatically computed() for derived values Methods for derived values const doubled = computed(() => count.value * 2) const doubled = () => count.value * 2 Medium https://vuejs.org/guide/essentials/computed.html
8 7 Reactivity Use shallowRef for large objects Avoid deep reactivity for performance shallowRef for large data structures ref for large nested objects const bigData = shallowRef(largeObject) const bigData = ref(largeObject) Medium https://vuejs.org/api/reactivity-advanced.html#shallowref
9 8 Watchers Use watchEffect for simple cases Auto-tracks dependencies watchEffect for simple reactive effects watch with explicit deps when not needed watchEffect(() => console.log(count.value)) watch(count, (val) => console.log(val)) Low https://vuejs.org/guide/essentials/watchers.html
10 9 Watchers Use watch for specific sources Explicit control over what to watch watch with specific refs watchEffect for complex conditional logic watch(userId, fetchUser) watchEffect with conditionals Medium
11 10 Watchers Clean up side effects Return cleanup function in watchers Return cleanup in watchEffect Leave subscriptions open watchEffect((onCleanup) => { onCleanup(unsub) }) watchEffect without cleanup High
12 11 Props Define props with defineProps Type-safe prop definitions defineProps with TypeScript Props without types defineProps<{ msg: string }>() defineProps(['msg']) Medium https://vuejs.org/guide/typescript/composition-api.html#typing-component-props
13 12 Props Use withDefaults for default values Provide defaults for optional props withDefaults with defineProps Defaults in destructuring withDefaults(defineProps<Props>(), { count: 0 }) const { count = 0 } = defineProps() Medium
14 13 Props Avoid mutating props Props should be read-only Emit events to parent for changes Direct prop mutation emit('update:modelValue', newVal) props.modelValue = newVal High
15 14 Emits Define emits with defineEmits Type-safe event emissions defineEmits with types Emit without definition defineEmits<{ change: [id: number] }>() emit('change', id) without define Medium https://vuejs.org/guide/typescript/composition-api.html#typing-component-emits
16 15 Emits Use v-model for two-way binding Simplified parent-child data flow v-model with modelValue prop :value + @input manually <Child v-model="value"/> <Child :value="value" @input="value = $event"/> Low https://vuejs.org/guide/components/v-model.html
17 16 Lifecycle Use onMounted for DOM access DOM is ready in onMounted onMounted for DOM operations Access DOM in setup directly onMounted(() => el.value.focus()) el.value.focus() in setup High https://vuejs.org/api/composition-api-lifecycle.html
18 17 Lifecycle Clean up in onUnmounted Remove listeners and subscriptions onUnmounted for cleanup Leave listeners attached onUnmounted(() => window.removeEventListener()) No cleanup on unmount High
19 18 Lifecycle Avoid onBeforeMount for data Use onMounted or setup for data fetching Fetch in onMounted or setup Fetch in onBeforeMount onMounted(async () => await fetchData()) onBeforeMount(async () => await fetchData()) Low
20 19 Components Use single-file components Keep template script style together .vue files for components Separate template/script files Component.vue with all parts Component.js + Component.html Low
21 20 Components Use PascalCase for components Consistent component naming PascalCase in imports and templates kebab-case in script <MyComponent/> <my-component/> Low https://vuejs.org/style-guide/rules-strongly-recommended.html
22 21 Components Prefer composition over mixins Composables replace mixins Composables for shared logic Mixins for code reuse const { data } = useApi() mixins: [apiMixin] Medium
23 22 Composables Name composables with use prefix Convention for composable functions useFetch useAuth useForm getData or fetchApi export function useFetch() export function fetchData() Medium https://vuejs.org/guide/reusability/composables.html
24 23 Composables Return refs from composables Maintain reactivity when destructuring Return ref values Return reactive objects that lose reactivity return { data: ref(null) } return reactive({ data: null }) Medium
25 24 Composables Accept ref or value params Use toValue for flexible inputs toValue() or unref() for params Only accept ref or only value const val = toValue(maybeRef) const val = maybeRef.value Low https://vuejs.org/api/reactivity-utilities.html#tovalue
26 25 Templates Use v-bind shorthand Cleaner template syntax :prop instead of v-bind:prop Full v-bind syntax <div :class="cls"> <div v-bind:class="cls"> Low
27 26 Templates Use v-on shorthand Cleaner event binding @event instead of v-on:event Full v-on syntax <button @click="handler"> <button v-on:click="handler"> Low
28 27 Templates Avoid v-if with v-for v-if has higher priority causes issues Wrap in template or computed filter v-if on same element as v-for <template v-for><div v-if> <div v-for v-if> High https://vuejs.org/style-guide/rules-essential.html#avoid-v-if-with-v-for
29 28 Templates Use key with v-for Proper list rendering and updates Unique key for each item Index as key for dynamic lists v-for="item in items" :key="item.id" v-for="(item, i) in items" :key="i" High
30 29 State Use Pinia for global state Official state management for Vue 3 Pinia stores for shared state Vuex for new projects const store = useCounterStore() Vuex with mutations Medium https://pinia.vuejs.org/
31 30 State Define stores with defineStore Composition API style stores Setup stores with defineStore Options stores for complex state defineStore('counter', () => {}) defineStore('counter', { state }) Low
32 31 State Use storeToRefs for destructuring Maintain reactivity when destructuring storeToRefs(store) Direct destructuring const { count } = storeToRefs(store) const { count } = store High https://pinia.vuejs.org/core-concepts/#destructuring-from-a-store
33 32 Routing Use useRouter and useRoute Composition API router access useRouter() useRoute() in setup this.$router this.$route const router = useRouter() this.$router.push() Medium https://router.vuejs.org/guide/advanced/composition-api.html
34 33 Routing Lazy load route components Code splitting for routes () => import() for components Static imports for all routes component: () => import('./Page.vue') component: Page Medium https://router.vuejs.org/guide/advanced/lazy-loading.html
35 34 Routing Use navigation guards Protect routes and handle redirects beforeEach for auth checks Check auth in each component router.beforeEach((to) => {}) Check auth in onMounted Medium
36 35 Performance Use v-once for static content Skip re-renders for static elements v-once on never-changing content v-once on dynamic content <div v-once>{{ staticText }}</div> <div v-once>{{ dynamicText }}</div> Low https://vuejs.org/api/built-in-directives.html#v-once
37 36 Performance Use v-memo for expensive lists Memoize list items v-memo with dependency array Re-render entire list always <div v-for v-memo="[item.id]"> <div v-for> without memo Medium https://vuejs.org/api/built-in-directives.html#v-memo
38 37 Performance Use shallowReactive for flat objects Avoid deep reactivity overhead shallowReactive for flat state reactive for simple objects shallowReactive({ count: 0 }) reactive({ count: 0 }) Low
39 38 Performance Use defineAsyncComponent Lazy load heavy components defineAsyncComponent for modals dialogs Import all components eagerly defineAsyncComponent(() => import()) import HeavyComponent from Medium https://vuejs.org/guide/components/async.html
40 39 TypeScript Use generic components Type-safe reusable components Generic with defineComponent Any types in components <script setup lang="ts" generic="T"> <script setup> without types Medium https://vuejs.org/guide/typescript/composition-api.html
41 40 TypeScript Type template refs Proper typing for DOM refs ref<HTMLInputElement>(null) ref(null) without type const input = ref<HTMLInputElement>(null) const input = ref(null) Medium
42 41 TypeScript Use PropType for complex props Type complex prop types PropType<User> for object props Object without type type: Object as PropType<User> type: Object Medium
43 42 Testing Use Vue Test Utils Official testing library mount shallowMount for components Manual DOM testing import { mount } from '@vue/test-utils' document.createElement Medium https://test-utils.vuejs.org/
44 43 Testing Test component behavior Focus on inputs and outputs Test props emit and rendered output Test internal implementation expect(wrapper.text()).toContain() expect(wrapper.vm.internalState) Medium
45 44 Forms Use v-model modifiers Built-in input handling .lazy .number .trim modifiers Manual input parsing <input v-model.number="age"> <input v-model="age"> then parse Low https://vuejs.org/guide/essentials/forms.html#modifiers
46 45 Forms Use VeeValidate or FormKit Form validation libraries VeeValidate for complex forms Manual validation logic useField useForm from vee-validate Custom validation in each input Medium
47 46 Accessibility Use semantic elements Proper HTML elements in templates button nav main for purpose div for everything <button @click> <div @click> High
48 47 Accessibility Bind aria attributes dynamically Keep ARIA in sync with state :aria-expanded="isOpen" Static ARIA values :aria-expanded="menuOpen" aria-expanded="true" Medium
49 48 SSR Use Nuxt for SSR Full-featured SSR framework Nuxt 3 for SSR apps Manual SSR setup npx nuxi init my-app Custom SSR configuration Medium https://nuxt.com/
50 49 SSR Handle hydration mismatches Client/server content must match ClientOnly for browser-only content Different content server/client <ClientOnly><BrowserWidget/></ClientOnly> <div>{{ Date.now() }}</div> High