codemaxxing 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -467,6 +467,960 @@ export const REGISTRY = [
467
467
  - Don't hardcode config — use environment variables or config maps
468
468
  - Don't ignore failed CI — fix or revert immediately
469
469
  - Don't alert on everything — alert fatigue leads to ignored alerts
470
+ `,
471
+ },
472
+ {
473
+ name: "nextjs-app",
474
+ description: "Next.js App Router, Server/Client Components, server actions, caching, streaming",
475
+ version: "1.0.0",
476
+ author: "codemaxxing",
477
+ tags: ["nextjs", "react", "app-router", "server-components", "streaming"],
478
+ prompt: `# Next.js App Router Expert
479
+
480
+ ## Server Components vs Client Components
481
+ - Default to Server Components — they run on the server, ship zero JS to the client
482
+ - Add "use client" only when you need: useState, useEffect, event handlers, browser APIs
483
+ - Keep "use client" boundaries as low in the tree as possible — wrap only the interactive leaf
484
+ - Server Components can import Client Components, but NOT the reverse
485
+ - Pass server data to Client Components as serializable props — no functions, no classes
486
+ - Use composition: Server Component fetches data, passes it to a Client Component for interactivity
487
+
488
+ ## Route Handlers & Server Actions
489
+ - Use server actions ("use server") for mutations — forms, data writes, revalidation
490
+ - Prefer server actions over API route handlers for app-internal mutations
491
+ - Use route.ts (GET/POST/PUT/DELETE) for webhooks, external API consumers, and streaming responses
492
+ - Always validate input in server actions with Zod or similar — they're public endpoints
493
+ - Call revalidatePath() or revalidateTag() after mutations to bust the cache
494
+ - Use useActionState (React 19) for form state + pending UI, not manual useState
495
+
496
+ ## Routing & Layouts
497
+ - Use layout.tsx for shared UI that persists across navigations (navbars, sidebars)
498
+ - Use template.tsx instead of layout.tsx when you need fresh state on every navigation
499
+ - Implement loading.tsx per route segment for instant loading UI via Suspense
500
+ - Implement error.tsx per route segment — wraps in an ErrorBoundary automatically
501
+ - Use not-found.tsx for custom 404 pages, call notFound() to trigger programmatically
502
+ - Route groups (parentheses) for organizing without affecting URL: (marketing)/about/page.tsx
503
+ - Parallel routes (@modal) and intercepting routes ((..)photo) for modals and feeds
504
+
505
+ ## Data Fetching & Caching
506
+ - Fetch in Server Components directly — no useEffect, no client-side fetching for initial data
507
+ - Use the extended fetch options: \`fetch(url, { next: { revalidate: 3600, tags: ["posts"] } })\`
508
+ - unstable_cache or "use cache" directive for caching non-fetch operations (DB queries)
509
+ - Understand the cache layers: Request Memoization → Data Cache → Full Route Cache
510
+ - Use \`export const dynamic = "force-dynamic"\` to opt out of static rendering per route
511
+ - generateStaticParams for static generation of dynamic routes at build time
512
+
513
+ ## Streaming & Suspense
514
+ - Wrap slow data fetches in <Suspense> with a fallback to stream the page progressively
515
+ - Use loading.tsx for route-level Suspense — it wraps page.tsx automatically
516
+ - Multiple <Suspense> boundaries let fast content appear while slow content loads
517
+ - Streaming works out of the box — no special config needed with App Router
518
+
519
+ ## Metadata & SEO
520
+ - Export metadata object or generateMetadata function from page.tsx and layout.tsx
521
+ - Use generateMetadata for dynamic metadata (fetching title from DB)
522
+ - Metadata merges from layout → page, with page taking precedence
523
+ - Add opengraph-image.tsx and twitter-image.tsx for dynamic OG images
524
+ - Use sitemap.ts and robots.ts for programmatic SEO files
525
+
526
+ ## Middleware
527
+ - Use middleware.ts at the project root for auth checks, redirects, A/B testing, geo-routing
528
+ - Middleware runs on the Edge — keep it lightweight, no heavy computation or DB queries
529
+ - Use NextResponse.next() to continue, NextResponse.redirect() to redirect, NextResponse.rewrite() to rewrite
530
+ - Match routes with the config.matcher array — don't run middleware on static assets
531
+
532
+ ## Anti-Patterns
533
+ - Don't "use client" on layout.tsx — it defeats the purpose of Server Component layouts
534
+ - Don't fetch data on the client when you can fetch in a Server Component
535
+ - Don't use useEffect for data fetching in the App Router — use Server Components or server actions
536
+ - Don't mix Pages Router patterns (getServerSideProps) with App Router
537
+ - Don't put all components in a single "use client" boundary — isolate interactivity
538
+ - Don't forget to handle the loading and error states per route segment
539
+ `,
540
+ },
541
+ {
542
+ name: "tailwind-ui",
543
+ description: "Tailwind CSS, Shadcn UI, Radix primitives, responsive design, dark mode",
544
+ version: "1.0.0",
545
+ author: "codemaxxing",
546
+ tags: ["tailwind", "shadcn", "radix", "css", "ui", "design-system"],
547
+ prompt: `# Tailwind CSS & Shadcn UI Expert
548
+
549
+ ## Utility-First Patterns
550
+ - Build UI with utility classes directly — avoid creating CSS files unless truly necessary
551
+ - Group related utilities logically: layout → spacing → sizing → typography → colors → effects
552
+ - Use arbitrary values sparingly: \`w-[327px]\` is a sign you need a design token or a different approach
553
+ - Prefer Tailwind's spacing scale (p-4, m-6) over arbitrary values for consistency
554
+ - Use @apply only in base layer for truly repeated patterns (btn, input) — not for components
555
+ - Prefer component extraction (React/Svelte/Vue components) over @apply for reuse
556
+
557
+ ## Responsive Design
558
+ - Mobile-first: write base styles for mobile, override with sm:, md:, lg:, xl:, 2xl:
559
+ - Breakpoints: sm(640) md(768) lg(1024) xl(1280) 2xl(1536) — learn them
560
+ - Use container mx-auto for centered max-width layouts
561
+ - Responsive grids: \`grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6\`
562
+ - Hide/show elements responsively: \`hidden md:block\` or \`md:hidden\`
563
+ - Use responsive typography: \`text-sm md:text-base lg:text-lg\`
564
+
565
+ ## Dark Mode
566
+ - Use the "class" dark mode strategy for user-controlled toggling
567
+ - Apply dark variants: \`bg-white dark:bg-slate-900 text-slate-900 dark:text-slate-100\`
568
+ - Use CSS custom properties with Tailwind for theme-aware colors
569
+ - Define semantic color names in tailwind.config: primary, secondary, muted, accent
570
+ - Use Shadcn's built-in dark mode — it uses CSS variables under the hood
571
+ - Test both modes — don't forget hover/focus states in dark mode
572
+
573
+ ## Shadcn UI & Radix Primitives
574
+ - Install Shadcn components individually: \`npx shadcn@latest add button dialog\`
575
+ - Components live in your codebase (src/components/ui/) — customize them directly
576
+ - Use the cn() helper (clsx + tailwind-merge) for conditional + overridable classes
577
+ - cn() pattern: \`cn("base classes", conditional && "conditional-class", className)\`
578
+ - Radix provides unstyled accessible primitives — Shadcn adds Tailwind styles on top
579
+ - Always pass className through to the root element of custom components for composability
580
+
581
+ ## Component Composition
582
+ - Build complex components by composing Shadcn primitives: Dialog + Form + Button
583
+ - Use Radix's compound component pattern: \`<Select><SelectTrigger><SelectContent>...</SelectContent></SelectTrigger></Select>\`
584
+ - Use cva (class-variance-authority) for multi-variant components: size, color, state
585
+ - Pattern: \`const buttonVariants = cva("base", { variants: { size: { sm: "h-8", lg: "h-12" } } })\`
586
+ - Extend Shadcn components by wrapping them, not by modifying the generated code (easier upgrades)
587
+ - Use Slot from Radix (asChild prop) to merge props onto child elements
588
+
589
+ ## Accessibility
590
+ - Shadcn/Radix components handle ARIA attributes, keyboard navigation, and focus management
591
+ - Don't remove or override ARIA roles/attributes added by Radix primitives
592
+ - Use sr-only class for screen-reader-only text
593
+ - Ensure sufficient color contrast — Tailwind's default palette mostly passes WCAG AA
594
+ - Test with keyboard navigation: Tab, Enter, Escape, Arrow keys should all work
595
+
596
+ ## Anti-Patterns
597
+ - Don't fight Tailwind by writing custom CSS for things utilities already handle
598
+ - Don't create deeply nested className strings — extract components instead
599
+ - Don't use inline styles alongside Tailwind — pick one approach
600
+ - Don't ignore the cn() helper — raw string concatenation breaks with conflicting utilities
601
+ - Don't copy-paste Shadcn components without understanding the underlying Radix primitives
602
+ - Don't use arbitrary values for spacing when a Tailwind scale value is close enough
603
+ - Don't forget to import Tailwind's base/components/utilities layers in your CSS entry point
604
+ `,
605
+ },
606
+ {
607
+ name: "svelte-kit",
608
+ description: "Svelte 5 runes, SvelteKit routing, load functions, form actions, SSR/SSG",
609
+ version: "1.0.0",
610
+ author: "codemaxxing",
611
+ tags: ["svelte", "sveltekit", "runes", "ssr", "frontend"],
612
+ prompt: `# Svelte 5 & SvelteKit Expert
613
+
614
+ ## Svelte 5 Runes
615
+ - Use $state() for reactive state: \`let count = $state(0)\` — replaces the old \`let count = 0\` reactivity
616
+ - Use $derived() for computed values: \`let doubled = $derived(count * 2)\` — replaces $: reactive labels
617
+ - Use $derived.by() for multi-line derivations: \`let total = $derived.by(() => { /* compute */ return val })\`
618
+ - Use $effect() for side effects: replaces onMount + $: reactive statements that cause side effects
619
+ - $effect runs after DOM update — use $effect.pre() if you need to run before DOM update
620
+ - Use $props() to declare component props: \`let { name, age = 25 }: Props = $props()\`
621
+ - Use $bindable() for two-way bindable props: \`let { value = $bindable() }: Props = $props()\`
622
+ - $inspect() for debugging reactive values — like console.log but re-runs when values change
623
+
624
+ ## Component Patterns
625
+ - Svelte components are .svelte files with <script>, markup, and <style> sections
626
+ - Use {#snippet name(params)} for reusable markup blocks within a component (replaces slots)
627
+ - Use {@render snippetName(args)} to render snippets
628
+ - Children content is received as a children snippet: \`let { children }: Props = $props()\` then {@render children?.()}
629
+ - Use \`<svelte:component this={Component}\` for dynamic components
630
+ - Scoped styles by default — styles in <style> only affect the current component
631
+ - Use :global() sparingly for styles that must escape component scope
632
+
633
+ ## SvelteKit Routing
634
+ - File-based routing: src/routes/about/+page.svelte → /about
635
+ - Dynamic params: src/routes/users/[id]/+page.svelte → /users/123
636
+ - Layout nesting: +layout.svelte wraps all child routes automatically
637
+ - Use +page.ts for universal load (runs server + client), +page.server.ts for server-only load
638
+ - Use +error.svelte for error pages, +layout.server.ts for layout-level data loading
639
+ - Group routes without URL impact: (group)/route/+page.svelte
640
+ - Rest params: [...slug]/+page.svelte catches all remaining path segments
641
+
642
+ ## Load Functions
643
+ - Load functions in +page.ts export a load function that returns data as props
644
+ - Access params, url, fetch (SvelteKit's enhanced fetch with credentials), and parent data
645
+ - Use depends() to declare custom invalidation keys: \`depends('app:posts')\`
646
+ - Call invalidate('app:posts') or invalidateAll() to re-run load functions
647
+ - Server load functions (+page.server.ts) can access DB, env vars, and secrets directly
648
+ - Data flows: +layout.server.ts → +layout.ts → +page.server.ts → +page.ts → component
649
+
650
+ ## Form Actions
651
+ - Define actions in +page.server.ts: \`export const actions = { default: async ({ request }) => { ... } }\`
652
+ - Use <form method="POST"> — SvelteKit handles it without JS (progressive enhancement)
653
+ - Named actions: \`<form method="POST" action="?/create">\` maps to \`actions: { create: async () => {} }\`
654
+ - Use enhance action for progressive enhancement: \`<form method="POST" use:enhance>\`
655
+ - Return validation errors with fail(): \`return fail(400, { email, error: "Invalid email" })\`
656
+ - Access returned data in the page via $page.form or the form prop from load
657
+
658
+ ## SSR, SSG & Prerendering
659
+ - SSR is on by default — pages render on the server, then hydrate on the client
660
+ - Prerender static pages: \`export const prerender = true\` in +page.ts or +layout.ts
661
+ - Use adapter-static for full SSG (all pages prerendered)
662
+ - Disable SSR for SPA pages: \`export const ssr = false\` — use only when necessary
663
+ - Use adapter-node for Node server, adapter-vercel/adapter-netlify for serverless
664
+
665
+ ## Anti-Patterns
666
+ - Don't use $: reactive labels in Svelte 5 — migrate to $state, $derived, $effect
667
+ - Don't mutate $state values indirectly without assignment — Svelte 5 uses proxies but keep mutations explicit
668
+ - Don't use $effect for derived values — use $derived instead
669
+ - Don't put secrets or DB calls in +page.ts (universal) — use +page.server.ts for server-only code
670
+ - Don't forget use:enhance on forms — without it, you lose SvelteKit's progressive enhancement
671
+ - Don't create stores for local component state — $state() rune handles it
672
+ `,
673
+ },
674
+ {
675
+ name: "react-native",
676
+ description: "Expo, React Navigation, platform-specific code, performance, EAS builds",
677
+ version: "1.0.0",
678
+ author: "codemaxxing",
679
+ tags: ["react-native", "expo", "mobile", "ios", "android", "navigation"],
680
+ prompt: `# React Native & Expo Expert
681
+
682
+ ## Expo Workflow
683
+ - Start with Expo for new projects — it handles native config, builds, and OTA updates
684
+ - Use Expo Router for file-based routing (built on React Navigation)
685
+ - Use expo-dev-client for custom native modules during development
686
+ - Use EAS Build for cloud builds: \`eas build --platform ios\` — no local Xcode/Android Studio needed
687
+ - Use EAS Submit to automate App Store and Play Store submissions
688
+ - Use EAS Update for OTA JavaScript updates — skip the app store review cycle
689
+ - Config plugins (app.config.ts) let you modify native projects without ejecting
690
+ - Use expo-constants, expo-device, expo-file-system for cross-platform native APIs
691
+
692
+ ## Navigation (React Navigation / Expo Router)
693
+ - Use Expo Router: app/_layout.tsx defines the navigator, app/index.tsx is the home screen
694
+ - Stack navigator for hierarchical flows (push/pop), Tab navigator for main app sections
695
+ - Use typed routes: \`router.push("/users/[id]", { id: "123" })\`
696
+ - Deep linking works automatically with Expo Router — configure in app.config
697
+ - Use navigation state to persist and restore navigation across app restarts
698
+ - Modals: use presentation: "modal" in stack screen options
699
+ - Avoid deeply nested navigators — flatten where possible for performance
700
+
701
+ ## Layout & Styling
702
+ - Always wrap content in SafeAreaView (expo-safe-area-context) to avoid notches/status bars
703
+ - Use StyleSheet.create() for styles — it validates and optimizes at creation time
704
+ - Flexbox is the default layout system — flexDirection defaults to "column" (not "row" like web)
705
+ - Use Dimensions or useWindowDimensions() for responsive layouts
706
+ - Platform-specific code: Platform.select({ ios: value, android: value }) or .ios.tsx / .android.tsx files
707
+ - Use react-native-reanimated for 60fps animations on the native thread
708
+ - Avoid inline styles in render — they create new objects on every render
709
+
710
+ ## State Management
711
+ - Use Zustand for global state — lightweight, works great with React Native
712
+ - Use MMKV (react-native-mmkv) for persistent storage — 30x faster than AsyncStorage
713
+ - Use TanStack Query for server state — caching, refetching, offline support
714
+ - For offline-first: combine TanStack Query + MMKV persister + network-aware sync
715
+ - Keep navigation state separate from app state — React Navigation manages its own state
716
+
717
+ ## Performance
718
+ - Use FlatList (not ScrollView) for lists — it virtualizes, rendering only visible items
719
+ - FlatList: set keyExtractor, getItemLayout (fixed height), maxToRenderPerBatch, windowSize
720
+ - Use React.memo for list items to prevent re-renders when data hasn't changed
721
+ - Use useCallback for event handlers passed to list items
722
+ - Avoid passing new objects/arrays as props in render — memoize or define outside
723
+ - Use Hermes engine (default in Expo) — it improves startup time and memory usage
724
+ - Profile with React DevTools and Flipper — never optimize without measuring first
725
+
726
+ ## Native Modules & Platform Code
727
+ - Check expo packages first before reaching for community native modules
728
+ - Use expo-modules-api to write custom native modules in Swift/Kotlin
729
+ - Bridge native UI with requireNativeComponent or Expo's native view pattern
730
+ - Handle platform differences explicitly — don't assume iOS behavior works on Android
731
+ - Test on real devices — simulators miss performance issues, permissions, and hardware quirks
732
+
733
+ ## Anti-Patterns
734
+ - Don't use ScrollView for long lists — use FlatList or FlashList
735
+ - Don't use web-specific APIs (window, document, localStorage) — they don't exist
736
+ - Don't ignore the keyboard — use KeyboardAvoidingView or react-native-keyboard-aware-scroll-view
737
+ - Don't hardcode dimensions — use relative sizing (flex) and useWindowDimensions
738
+ - Don't skip testing on Android — platform differences are real and frequent
739
+ - Don't use Animated API for complex animations — use react-native-reanimated instead
740
+ `,
741
+ },
742
+ {
743
+ name: "swift-ios",
744
+ description: "SwiftUI, async/await, Combine, SwiftData, MVVM, App Store guidelines",
745
+ version: "1.0.0",
746
+ author: "codemaxxing",
747
+ tags: ["swift", "ios", "swiftui", "apple", "mobile", "xcode"],
748
+ prompt: `# Swift iOS Development Expert
749
+
750
+ ## SwiftUI Views
751
+ - Build UIs declaratively with structs conforming to View — return a body computed property
752
+ - Use VStack, HStack, ZStack for layout composition — avoid GeometryReader unless truly needed
753
+ - Prefer LazyVStack/LazyHStack inside ScrollView for long lists — they load items on demand
754
+ - Use List for built-in swipe actions, selection, and pull-to-refresh
755
+ - Modifiers order matters: \`.padding().background().cornerRadius()\` differs from reordering
756
+ - Extract subviews into separate structs to keep body readable (under ~30 lines)
757
+ - Use @ViewBuilder for functions that return opaque view types conditionally
758
+
759
+ ## Property Wrappers
760
+ - @State for local view state — value types owned by the view
761
+ - @Binding for two-way connection to a parent's @State
762
+ - @StateObject for creating ObservableObject instances (create once, view owns it)
763
+ - @ObservedObject for ObservableObject passed in from parent (view doesn't own it)
764
+ - @EnvironmentObject for dependency injection of ObservableObject through the view hierarchy
765
+ - @Environment(\\.colorScheme) for reading system environment values
766
+ - @AppStorage for UserDefaults-backed persistent state
767
+ - In iOS 17+: use @Observable macro instead of ObservableObject for simpler observation
768
+
769
+ ## MVVM Architecture
770
+ - View: SwiftUI views — declarative UI, no business logic
771
+ - ViewModel: @Observable class that holds state and business logic, exposes computed properties
772
+ - Model: plain structs/classes for data — Codable for serialization
773
+ - ViewModels should not import SwiftUI — keep them testable with plain Swift
774
+ - Use protocols for dependencies (networking, storage) to enable testability
775
+ - One ViewModel per screen/feature — avoid god ViewModels
776
+
777
+ ## Async/Await & Concurrency
778
+ - Use async/await for network calls, file I/O, and any asynchronous work
779
+ - Use Task { } in SwiftUI to launch async work from synchronous contexts (onAppear, buttons)
780
+ - Use TaskGroup for concurrent parallel operations with structured cancellation
781
+ - Actor types protect mutable state from data races — use for shared resources
782
+ - @MainActor ensures code runs on the main thread — use for UI-updating classes
783
+ - Use AsyncSequence and for-await loops for streaming data (WebSockets, file reading)
784
+ - Handle cancellation: check Task.isCancelled or use withTaskCancellationHandler
785
+
786
+ ## Data Persistence
787
+ - SwiftData (iOS 17+): use @Model macro on classes, @Query in views for reactive fetches
788
+ - SwiftData replaces Core Data for most use cases — simpler API, better SwiftUI integration
789
+ - Use ModelContainer for configuration, ModelContext for CRUD operations
790
+ - For key-value storage: UserDefaults (@AppStorage) for small data, Keychain for secrets
791
+ - For complex legacy needs: Core Data with NSPersistentContainer and @FetchRequest
792
+
793
+ ## App Store Guidelines
794
+ - Follow Human Interface Guidelines — use standard navigation patterns and system controls
795
+ - Request permissions just-in-time with clear usage descriptions in Info.plist
796
+ - Implement in-app purchases with StoreKit 2 — server-side validation for subscriptions
797
+ - Support Dynamic Type for text accessibility — use system fonts and relative sizing
798
+ - Add VoiceOver labels to all interactive elements: \`.accessibilityLabel("Close button")\`
799
+ - Test on multiple device sizes and orientations — use preview providers
800
+
801
+ ## Anti-Patterns
802
+ - Don't use force unwraps (!) in production code — use guard let, if let, or ?? defaults
803
+ - Don't put networking or heavy logic in View bodies — use ViewModels
804
+ - Don't use GeometryReader for simple layouts — it causes unnecessary complexity
805
+ - Don't ignore memory management — watch for retain cycles with [weak self] in closures
806
+ - Don't use Timer for background work — use Task with proper lifecycle management
807
+ - Don't hardcode strings — use String Catalogs or NSLocalizedString for localization
808
+ `,
809
+ },
810
+ {
811
+ name: "flutter",
812
+ description: "Dart patterns, widget tree, state management (Riverpod/Bloc), Material Design 3",
813
+ version: "1.0.0",
814
+ author: "codemaxxing",
815
+ tags: ["flutter", "dart", "mobile", "widgets", "riverpod", "material"],
816
+ prompt: `# Flutter & Dart Expert
817
+
818
+ ## Dart Patterns
819
+ - Use null safety: \`String?\` for nullable, \`!\` only when you're certain (prefer null checks)
820
+ - Prefer final for variables that won't be reassigned: \`final name = "Flutter";\`
821
+ - Use named parameters with required keyword: \`void greet({required String name})\`
822
+ - Use extension methods to add functionality to existing types without subclassing
823
+ - Use sealed classes (Dart 3) for exhaustive pattern matching on state variants
824
+ - Cascade notation (..) for chaining operations on the same object
825
+ - Use records for lightweight data grouping: \`(String, int) getNameAndAge()\`
826
+ - Pattern matching with switch expressions: \`final label = switch(status) { Status.ok => "Good" };\`
827
+
828
+ ## Widget Tree & Composition
829
+ - Everything is a widget — compose small, focused widgets into complex UIs
830
+ - StatelessWidget for UI that depends only on constructor parameters (immutable)
831
+ - StatefulWidget when the widget needs to manage mutable state with setState()
832
+ - Keep build() methods lean — extract sub-widget methods into separate widget classes
833
+ - Use const constructors wherever possible — they enable widget tree optimizations
834
+ - Prefer composition over inheritance — wrap widgets rather than extending them
835
+ - Use the Builder pattern for context-dependent widgets: \`Builder(builder: (context) => ...)\`
836
+
837
+ ## State Management
838
+ - setState() for local widget state — fine for simple, isolated state
839
+ - Riverpod (recommended): Provider, StateNotifier, AsyncNotifier for scalable state
840
+ - Riverpod patterns: define providers at top level, use ref.watch() in widgets, ref.read() for actions
841
+ - Use AsyncValue (Riverpod) for loading/error/data states from async operations
842
+ - Bloc pattern: Events → Bloc → States — good for complex business logic with clear event flows
843
+ - Use ChangeNotifier + Provider for simpler apps, but Riverpod scales better
844
+ - Avoid global mutable state — use providers/blocs to scope state to features
845
+
846
+ ## Navigation & Routing
847
+ - Use GoRouter for declarative, URL-based routing with deep link support
848
+ - Define routes in a central configuration: \`GoRouter(routes: [GoRoute(path: "/", builder: ...)])\`
849
+ - Use shell routes for persistent navigation (bottom tabs, drawers)
850
+ - Pass parameters via path or query params — avoid passing complex objects through navigation
851
+ - Use guards (redirect) for authentication-protected routes
852
+
853
+ ## Platform Channels & Integration
854
+ - Use MethodChannel for calling native platform code (Swift/Kotlin) from Dart
855
+ - Use EventChannel for streaming data from native to Dart (sensors, Bluetooth)
856
+ - Use Pigeon for type-safe platform channel communication — generates boilerplate
857
+ - Check platform with \`Platform.isIOS\` / \`Platform.isAndroid\` for platform-specific behavior
858
+ - Use federated plugins to share platform-specific implementations across packages
859
+
860
+ ## Material Design 3 & Theming
861
+ - Use Material 3: \`MaterialApp(theme: ThemeData(useMaterial3: true, colorSchemeSeed: Colors.blue))\`
862
+ - Use ColorScheme for systematic color usage: primary, secondary, surface, error variants
863
+ - Use Theme.of(context) to access theme data — never hardcode colors or text styles
864
+ - Use TextTheme for consistent typography: \`Theme.of(context).textTheme.headlineMedium\`
865
+ - Support dark mode: provide both light and dark ThemeData to MaterialApp
866
+ - Use adaptive widgets (e.g., Switch.adaptive) for platform-appropriate appearance
867
+
868
+ ## Performance
869
+ - Use const widgets to avoid unnecessary rebuilds — the framework skips const subtrees
870
+ - Use ListView.builder for long lists — it creates items lazily as they scroll into view
871
+ - Profile with Flutter DevTools: widget rebuild counts, frame rendering times, memory
872
+ - Use RepaintBoundary to isolate frequently updating parts of the widget tree
873
+ - Avoid building widgets in initState — use didChangeDependencies for context-dependent setup
874
+ - Use Isolates for CPU-heavy work — they run in separate threads without blocking UI
875
+
876
+ ## Anti-Patterns
877
+ - Don't put all logic in widgets — separate business logic into repositories/services
878
+ - Don't use setState for state shared across widgets — use a state management solution
879
+ - Don't create deep widget nesting (10+ levels) — extract into named widget classes
880
+ - Don't ignore keys in lists — use ValueKey or ObjectKey for items that move/reorder
881
+ - Don't use BuildContext across async gaps — capture what you need before the await
882
+ - Don't hardcode sizes — use MediaQuery, LayoutBuilder, or Flex for responsive layouts
883
+ `,
884
+ },
885
+ {
886
+ name: "rust-systems",
887
+ description: "Ownership, borrowing, error handling, async Tokio, Actix/Axum, unsafe guidelines",
888
+ version: "1.0.0",
889
+ author: "codemaxxing",
890
+ tags: ["rust", "systems", "tokio", "axum", "ownership", "concurrency"],
891
+ prompt: `# Rust Systems Programming Expert
892
+
893
+ ## Ownership & Borrowing
894
+ - Each value has exactly one owner — when the owner goes out of scope, the value is dropped
895
+ - Use references (&T) for read-only borrowing, (&mut T) for mutable borrowing
896
+ - Rule: unlimited &T OR exactly one &mut T — never both simultaneously
897
+ - Clone explicitly when you need a separate owned copy — don't fight the borrow checker blindly
898
+ - Use Cow<str> (Clone on Write) when you sometimes need to own, sometimes just borrow
899
+ - Prefer &str over String in function parameters — accepts both String and &str
900
+ - Use .as_ref(), .as_str(), .into() for ergonomic type conversions
901
+
902
+ ## Error Handling
903
+ - Use Result<T, E> for recoverable errors — never panic in library code
904
+ - Use the ? operator to propagate errors up the call chain concisely
905
+ - Define custom error enums with thiserror: \`#[error("not found: {id}")] NotFound { id: u64 }\`
906
+ - Use anyhow::Result for application code where you don't need typed errors
907
+ - Reserve panic!() and .unwrap() for truly unrecoverable situations or tests
908
+ - Use .expect("reason") over .unwrap() — document WHY you believe it won't fail
909
+ - Map errors at boundaries: \`.map_err(|e| MyError::Database(e))?\`
910
+
911
+ ## Lifetimes
912
+ - Lifetimes prevent dangling references — the compiler ensures references outlive their use
913
+ - Elision rules handle most cases — only annotate when the compiler asks you to
914
+ - Named lifetimes: \`fn first<'a>(items: &'a [T]) -> &'a T\` — output lives as long as input
915
+ - 'static means the reference lives for the entire program — owned data or compile-time constants
916
+ - Lifetime bounds on structs: \`struct Parser<'a> { input: &'a str }\` — struct can't outlive the reference
917
+ - When fighting lifetimes: consider if you should own the data instead of borrowing
918
+
919
+ ## Async with Tokio
920
+ - Use #[tokio::main] for the async runtime entry point
921
+ - Use tokio::spawn for concurrent tasks — returns a JoinHandle for awaiting results
922
+ - Use tokio::select! to race multiple futures — first one to complete wins
923
+ - Use tokio::sync::Mutex for async-safe locking (not std::sync::Mutex in async code)
924
+ - Use channels (mpsc, broadcast, oneshot) for communication between tasks
925
+ - Use tokio::time::timeout to prevent indefinite waits on futures
926
+ - Use Stream (futures/tokio-stream) for async iterators — process items as they arrive
927
+
928
+ ## Web with Axum
929
+ - Define handlers as async functions: \`async fn get_user(Path(id): Path<u64>) -> impl IntoResponse\`
930
+ - Use extractors for parsing: Path, Query, Json, State, Headers — composable and type-safe
931
+ - Shared state with State(Arc<AppState>) — wrap in Arc for thread-safe sharing
932
+ - Use tower middleware for logging, CORS, auth, rate limiting — composable layers
933
+ - Error handling: implement IntoResponse for your error type to control HTTP responses
934
+ - Use Router::new().route("/users", get(list).post(create)) for clean route definitions
935
+ - Use axum::serve with graceful_shutdown for production deployments
936
+
937
+ ## Cargo & Project Structure
938
+ - Use Cargo workspaces for multi-crate projects: shared deps, unified builds
939
+ - Feature flags for conditional compilation: \`#[cfg(feature = "postgres")]\`
940
+ - Use clippy: \`cargo clippy -- -W clippy::all\` — it catches common mistakes and idioms
941
+ - Organize: lib.rs for library logic, main.rs for binary entry, mod.rs for module roots
942
+ - Use integration tests in tests/ directory — they test your public API as an external consumer
943
+ - Profile with cargo bench (criterion) and cargo flamegraph for performance optimization
944
+
945
+ ## Unsafe Guidelines
946
+ - Avoid unsafe unless absolutely necessary — most Rust code should be 100% safe
947
+ - Valid reasons for unsafe: FFI, raw pointer manipulation, implementing unsafe traits
948
+ - Document every unsafe block with a SAFETY comment explaining why it's sound
949
+ - Minimize the scope of unsafe blocks — keep the unsafe surface area as small as possible
950
+ - Use safe abstractions around unsafe internals — expose a safe API to callers
951
+ - Prefer well-audited crates (libc, nix, windows-rs) over raw FFI bindings
952
+
953
+ ## Anti-Patterns
954
+ - Don't clone everything to avoid the borrow checker — understand ownership first
955
+ - Don't use Rc/RefCell as a default — they add runtime overhead, use references instead
956
+ - Don't ignore compiler warnings — Rust warnings almost always indicate real issues
957
+ - Don't use String when &str suffices — unnecessary allocation
958
+ - Don't block the async runtime with synchronous I/O — use tokio::task::spawn_blocking
959
+ - Don't write unsafe for convenience — only for correctness when safe Rust can't express it
960
+ `,
961
+ },
962
+ {
963
+ name: "go-backend",
964
+ description: "Go standard library, error handling, goroutines, interfaces, table-driven tests",
965
+ version: "1.0.0",
966
+ author: "codemaxxing",
967
+ tags: ["go", "golang", "backend", "concurrency", "testing"],
968
+ prompt: `# Go Backend Expert
969
+
970
+ ## Standard Library First
971
+ - Use net/http for HTTP servers — it's production-ready and widely understood
972
+ - Use http.ServeMux (Go 1.22+) with method-aware routing: \`mux.HandleFunc("GET /users/{id}", handler)\`
973
+ - Use encoding/json for JSON: \`json.NewDecoder(r.Body).Decode(&v)\` for requests, json.NewEncoder for responses
974
+ - Use database/sql with a driver (pgx, go-sql-driver) — it handles connection pooling
975
+ - Use log/slog (Go 1.21+) for structured logging: \`slog.Info("user created", "id", user.ID)\`
976
+ - Use html/template for server-rendered HTML — auto-escapes to prevent XSS
977
+ - Use embed for bundling static assets and templates into the binary
978
+ - Reach for third-party libraries only when the stdlib genuinely falls short
979
+
980
+ ## Error Handling
981
+ - Errors are values — return them, don't panic: \`func Open(name string) (*File, error)\`
982
+ - Always check errors: \`if err != nil { return fmt.Errorf("opening config: %w", err) }\`
983
+ - Wrap errors with %w for context: \`fmt.Errorf("creating user %s: %w", name, err)\`
984
+ - Use errors.Is() to check for specific errors: \`if errors.Is(err, sql.ErrNoRows)\`
985
+ - Use errors.As() to extract typed errors: \`var pathErr *os.PathError; errors.As(err, &pathErr)\`
986
+ - Define sentinel errors: \`var ErrNotFound = errors.New("not found")\`
987
+ - Don't use panic for expected failures — reserve panic for truly unrecoverable programmer errors
988
+
989
+ ## Goroutines & Channels
990
+ - Use goroutines for concurrent work — they're lightweight (2KB stack) and managed by the runtime
991
+ - Always ensure goroutines can terminate — use context.Context for cancellation
992
+ - Use sync.WaitGroup to wait for a group of goroutines to finish
993
+ - Use channels for communication between goroutines: \`ch := make(chan Result, bufSize)\`
994
+ - Buffered channels for producer/consumer, unbuffered for synchronization
995
+ - Use select for multiplexing: waiting on multiple channels or timeouts
996
+ - Use errgroup (golang.org/x/sync) for groups of goroutines that return errors
997
+ - Avoid goroutine leaks: always close channels, cancel contexts, and handle done signals
998
+
999
+ ## Interfaces
1000
+ - Interfaces are small: \`type Reader interface { Read(p []byte) (n int, err error) }\`
1001
+ - Accept interfaces, return structs — keep interfaces at the consumer, not the producer
1002
+ - Don't create interfaces until you need them — premature abstraction is costly in Go
1003
+ - Implicit implementation: types satisfy interfaces without explicit declaration
1004
+ - Use io.Reader, io.Writer, fmt.Stringer — standard interfaces enable composition
1005
+ - Empty interface (any) should be rare — use generics (Go 1.18+) for type-safe polymorphism
1006
+
1007
+ ## Project Structure
1008
+ - Keep it simple: cmd/ for entry points, internal/ for private packages, pkg/ only if truly reusable
1009
+ - Use internal/ to prevent external packages from importing your implementation details
1010
+ - One package per directory — package name matches the directory name
1011
+ - Avoid circular dependencies — they're compile errors in Go
1012
+ - Use Go modules: go.mod at the root, run go mod tidy to clean up dependencies
1013
+ - Follow standard naming: lowercase packages, MixedCaps for exported, camelCase for unexported
1014
+
1015
+ ## Table-Driven Tests
1016
+ - Use table-driven tests for exhaustive input/output coverage:
1017
+ - Pattern: define []struct{ name, input, want }, loop with t.Run(tc.name, func(t *testing.T) { ... })
1018
+ - Use t.Parallel() for independent tests — speeds up test suites
1019
+ - Use testify/assert for readable assertions, or stick with stdlib for zero dependencies
1020
+ - Use t.Helper() in test helper functions to fix file/line reporting
1021
+ - Use t.Cleanup() for teardown — it runs after the test and all its subtests
1022
+ - Use testcontainers-go for integration tests with real databases and services
1023
+
1024
+ ## Anti-Patterns
1025
+ - Don't ignore errors with \`_ = someFunc()\` — handle or explicitly document why it's safe
1026
+ - Don't use init() functions — they make testing hard and hide initialization order
1027
+ - Don't use global mutable state — pass dependencies explicitly via struct fields or function params
1028
+ - Don't overuse channels — a mutex is simpler when you just need to protect shared data
1029
+ - Don't create interfaces for single implementations — that's Java, not Go
1030
+ - Don't return interfaces — return concrete types and let consumers define their own interfaces
1031
+ `,
1032
+ },
1033
+ {
1034
+ name: "node-backend",
1035
+ description: "Express/Fastify, middleware, input validation, JWT auth, error handling, graceful shutdown",
1036
+ version: "1.0.0",
1037
+ author: "codemaxxing",
1038
+ tags: ["node", "express", "fastify", "backend", "api", "middleware"],
1039
+ prompt: `# Node.js Backend Expert
1040
+
1041
+ ## Framework Choice
1042
+ - Express for simplicity and ecosystem maturity — huge middleware library, well-documented
1043
+ - Fastify for performance — 2-3x faster than Express, built-in schema validation, TypeScript-first
1044
+ - Use Fastify's plugin system for encapsulated, reusable modules
1045
+ - Both support async handlers — always use async/await, never callbacks
1046
+ - For new projects: Fastify is recommended for its speed, schema validation, and TypeScript support
1047
+
1048
+ ## Middleware Patterns
1049
+ - Middleware executes in order — put auth before route handlers, error handlers last
1050
+ - Express: \`app.use(middleware)\` for global, \`router.use(middleware)\` for scoped
1051
+ - Fastify: use hooks (onRequest, preHandler, onSend) or plugins for middleware-like behavior
1052
+ - Common middleware stack: cors → helmet → rate-limiter → body-parser → auth → routes → error-handler
1053
+ - Keep middleware focused: one concern per middleware (logging, auth, validation)
1054
+ - Use express-async-errors or wrap handlers to catch async errors automatically
1055
+
1056
+ ## Input Validation
1057
+ - Validate ALL incoming data at the boundary — never trust req.body, req.params, req.query
1058
+ - Use Zod for runtime validation + TypeScript type inference: \`const UserSchema = z.object({...})\`
1059
+ - Validate in middleware: parse input before it reaches the handler, reject invalid requests early
1060
+ - Pattern: \`const data = UserSchema.parse(req.body)\` — throws ZodError on invalid input
1061
+ - Fastify: use JSON Schema in route definitions for automatic validation + serialization
1062
+ - Validate path params and query strings too — not just the body
1063
+ - Return structured validation errors: \`{ errors: [{ field: "email", message: "Invalid email" }] }\`
1064
+
1065
+ ## Authentication
1066
+ - Use bcrypt (cost factor 12+) for password hashing — never store plaintext passwords
1067
+ - JWTs for stateless auth: short-lived access tokens (15min), longer refresh tokens (7 days)
1068
+ - Store refresh tokens in httpOnly cookies — never in localStorage (XSS vulnerability)
1069
+ - Verify JWTs with jose or jsonwebtoken: check signature, expiry, issuer, audience
1070
+ - Middleware pattern: decode JWT → find user → attach to req.user → call next()
1071
+ - Use passport.js only if you need multiple OAuth providers — otherwise it's overhead
1072
+ - Implement token rotation: issue new refresh token on each use, revoke old one
1073
+
1074
+ ## Error Handling
1075
+ - Use a centralized error handler middleware — the last app.use() with (err, req, res, next)
1076
+ - Define custom error classes: AppError extends Error with statusCode and isOperational
1077
+ - Distinguish operational errors (bad input, not found) from programmer errors (null reference)
1078
+ - Never send stack traces to clients in production — log them, return a generic message
1079
+ - Use process.on('unhandledRejection') and process.on('uncaughtException') as safety nets
1080
+ - Return consistent error format: \`{ error: { code: "NOT_FOUND", message: "User not found" } }\`
1081
+
1082
+ ## Rate Limiting & Security
1083
+ - Use express-rate-limit or @fastify/rate-limit — essential for public APIs
1084
+ - Apply stricter limits to auth endpoints (login, register, password reset)
1085
+ - Use helmet for security headers: CSP, HSTS, X-Frame-Options, X-Content-Type-Options
1086
+ - Use cors with explicit origin allowlist — never use \`origin: "*"\` in production
1087
+ - Implement request ID (uuid) for tracing requests across services and logs
1088
+
1089
+ ## Structured Logging & Graceful Shutdown
1090
+ - Use pino (Fastify default) or winston — never console.log in production
1091
+ - Log as JSON with consistent fields: timestamp, level, requestId, message, metadata
1092
+ - Log at boundaries: incoming request, outgoing response, external API calls, errors
1093
+ - Graceful shutdown: handle SIGTERM/SIGINT → stop accepting requests → finish in-flight → close DB/Redis → exit
1094
+ - Pattern: \`process.on("SIGTERM", async () => { await server.close(); await db.end(); process.exit(0); })\`
1095
+ - Set a shutdown timeout (10-30s) — force exit if graceful shutdown hangs
1096
+
1097
+ ## Anti-Patterns
1098
+ - Don't use callback-based APIs — use promisify() or native promise alternatives
1099
+ - Don't block the event loop with synchronous operations (fs.readFileSync, crypto.pbkdf2Sync)
1100
+ - Don't catch errors silently: \`catch (e) {}\` — always log or handle meaningfully
1101
+ - Don't use \`res.send()\` after \`next()\` — it causes "headers already sent" errors
1102
+ - Don't store sessions in memory — use Redis or a database for production session storage
1103
+ - Don't skip input validation because "the frontend validates" — the frontend is untrusted
1104
+ `,
1105
+ },
1106
+ {
1107
+ name: "sql-master",
1108
+ description: "Query optimization, indexing, schema design, migrations, CTEs, window functions",
1109
+ version: "1.0.0",
1110
+ author: "codemaxxing",
1111
+ tags: ["sql", "postgres", "mysql", "database", "indexing", "performance"],
1112
+ prompt: `# SQL Mastery Expert
1113
+
1114
+ ## Schema Design
1115
+ - Use appropriate data types: INTEGER for IDs, TEXT/VARCHAR for strings, TIMESTAMPTZ for dates
1116
+ - Always use TIMESTAMPTZ (not TIMESTAMP) for dates — store in UTC, convert in the app
1117
+ - Add NOT NULL constraints by default — make columns nullable only when NULL has business meaning
1118
+ - Use UUID (gen_random_uuid) for public-facing IDs, BIGSERIAL for internal primary keys
1119
+ - Define foreign keys with appropriate ON DELETE behavior: CASCADE, SET NULL, or RESTRICT
1120
+ - Add created_at and updated_at columns to every table — use triggers for updated_at
1121
+ - Use CHECK constraints for data validation: \`CHECK (price >= 0)\`, \`CHECK (status IN ('active','inactive'))\`
1122
+ - Normalize to 3NF by default — denormalize intentionally for read-heavy queries with measured need
1123
+
1124
+ ## Indexing Strategies
1125
+ - Index columns used in WHERE, JOIN, ORDER BY, and GROUP BY clauses
1126
+ - B-tree indexes (default) work for equality and range queries: =, <, >, BETWEEN, LIKE 'prefix%'
1127
+ - Composite indexes: put equality columns first, range columns last: \`(status, created_at)\`
1128
+ - Covering indexes include all columns a query needs — avoids heap lookups (INDEX ... INCLUDE)
1129
+ - Partial indexes for filtered queries: \`CREATE INDEX ON orders (user_id) WHERE status = 'pending'\`
1130
+ - GIN indexes for JSONB, full-text search, and array columns
1131
+ - Don't over-index — each index slows writes and consumes storage. Index what you query.
1132
+ - Use CONCURRENTLY for production index creation: \`CREATE INDEX CONCURRENTLY ...\`
1133
+
1134
+ ## Query Optimization
1135
+ - Use EXPLAIN ANALYZE to see actual execution plans — not just EXPLAIN (which estimates)
1136
+ - Look for: Seq Scan (missing index?), Nested Loop (N+1?), Sort (missing index?), high row estimates vs actuals
1137
+ - Avoid SELECT * — select only the columns you need
1138
+ - Use JOINs instead of subqueries where possible — the optimizer handles JOINs better
1139
+ - Avoid functions on indexed columns in WHERE: \`WHERE created_at > '2024-01-01'\` not \`WHERE YEAR(created_at) = 2024\`
1140
+ - Use EXISTS instead of IN for correlated subqueries — it short-circuits on first match
1141
+ - LIMIT early in subqueries to reduce the working set for outer queries
1142
+ - Use connection pooling (PgBouncer, built-in pool) — don't open a connection per request
1143
+
1144
+ ## Common Table Expressions (CTEs)
1145
+ - Use CTEs for readability: \`WITH active_users AS (SELECT ...) SELECT ... FROM active_users\`
1146
+ - CTEs are optimization fences in some databases — the optimizer may not push predicates into them
1147
+ - Recursive CTEs for hierarchical data: org charts, category trees, threaded comments
1148
+ - Pattern: \`WITH RECURSIVE tree AS (base UNION ALL SELECT ... FROM tree JOIN ... ) SELECT * FROM tree\`
1149
+ - Use CTEs to break complex queries into named, readable steps — each CTE is a logical unit
1150
+
1151
+ ## Window Functions
1152
+ - ROW_NUMBER() for pagination, deduplication, and picking the latest record per group
1153
+ - RANK() and DENSE_RANK() for ranking with ties (RANK skips, DENSE_RANK doesn't)
1154
+ - LAG/LEAD for comparing rows to previous/next rows: \`LAG(amount) OVER (ORDER BY date)\`
1155
+ - SUM/AVG/COUNT as window functions for running totals: \`SUM(amount) OVER (ORDER BY date)\`
1156
+ - Use PARTITION BY to compute within groups: \`ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC)\`
1157
+ - FILTER clause for conditional aggregation: \`COUNT(*) FILTER (WHERE status = 'active')\`
1158
+
1159
+ ## Migrations
1160
+ - Use a migration tool: Flyway, Liquibase, golang-migrate, Prisma Migrate, or Knex
1161
+ - Every schema change is a numbered, version-controlled migration — never modify production DDL manually
1162
+ - Make migrations backward-compatible: add columns with defaults, avoid renaming in one step
1163
+ - Large table changes: add column → backfill → add constraint, not ALTER + NOT NULL in one migration
1164
+ - Always test migrations on a copy of production data before applying to production
1165
+ - Include both up and down migrations — even if you rarely use rollbacks
1166
+
1167
+ ## Avoiding N+1 Queries
1168
+ - N+1: fetching a list then querying related data per item — O(N) queries instead of O(1)
1169
+ - Fix with JOINs: \`SELECT users.*, orders.* FROM users JOIN orders ON ...\`
1170
+ - Fix with IN: \`SELECT * FROM orders WHERE user_id IN (1,2,3,...)\` — batch the lookups
1171
+ - ORMs: use eager loading (include, joinedload, preload) to fetch relations in one query
1172
+ - Monitor query counts in development — log the number of queries per request
1173
+
1174
+ ## Anti-Patterns
1175
+ - Don't use SELECT * in production queries — specify columns explicitly
1176
+ - Don't store CSV or JSON when you need relational data — normalize it
1177
+ - Don't skip foreign keys for "flexibility" — they enforce data integrity
1178
+ - Don't use OFFSET for deep pagination — use cursor-based (WHERE id > last_id) instead
1179
+ - Don't run schema changes without a migration tool — you'll lose track of database state
1180
+ - Don't optimize queries without EXPLAIN ANALYZE — measure before changing
1181
+ `,
1182
+ },
1183
+ {
1184
+ name: "supabase",
1185
+ description: "Auth, Row Level Security, edge functions, real-time, Postgres functions, storage",
1186
+ version: "1.0.0",
1187
+ author: "codemaxxing",
1188
+ tags: ["supabase", "postgres", "auth", "realtime", "edge-functions", "baas"],
1189
+ prompt: `# Supabase Expert
1190
+
1191
+ ## Auth Setup
1192
+ - Use Supabase Auth for email/password, magic link, OAuth (Google, GitHub, etc.)
1193
+ - Client: \`const { data, error } = await supabase.auth.signUp({ email, password })\`
1194
+ - Always check for errors after auth operations — don't assume success
1195
+ - Use onAuthStateChange listener to react to sign-in/sign-out events globally
1196
+ - Store user metadata in a separate profiles table linked by auth.uid() — don't overload auth.users
1197
+ - Use auth.getUser() (server-side verified) over auth.getSession() (client JWT only) for security
1198
+ - Configure email templates and redirect URLs in the Supabase dashboard
1199
+ - Set up proper redirect handling for OAuth: signInWithOAuth({ options: { redirectTo } })
1200
+
1201
+ ## Row Level Security (RLS)
1202
+ - ALWAYS enable RLS on every table: \`ALTER TABLE posts ENABLE ROW LEVEL SECURITY\`
1203
+ - Without RLS policies, NO rows are accessible — it's deny-by-default
1204
+ - Use auth.uid() in policies to scope access to the authenticated user
1205
+ - SELECT policy: \`CREATE POLICY "users read own" ON posts FOR SELECT USING (user_id = auth.uid())\`
1206
+ - INSERT policy: \`CREATE POLICY "users insert own" ON posts FOR INSERT WITH CHECK (user_id = auth.uid())\`
1207
+ - Use auth.jwt() -> 'user_role' for role-based access in policies
1208
+ - Test RLS policies thoroughly — use Supabase SQL editor with \`SET request.jwt.claims = ...\`
1209
+ - For public data, create a policy with \`USING (true)\` — but be intentional about it
1210
+
1211
+ ## Database & Postgres Functions
1212
+ - Use the Supabase client for CRUD: \`supabase.from("posts").select("*, author:profiles(name)")\`
1213
+ - Foreign key relations are automatic in .select() — use the relation name for joins
1214
+ - Use Postgres functions for complex operations: \`supabase.rpc("function_name", { param: value })\`
1215
+ - Write functions in SQL or PL/pgSQL: \`CREATE FUNCTION get_stats(...) RETURNS TABLE (...) AS $$ ... $$\`
1216
+ - Use SECURITY DEFINER functions to bypass RLS when needed (admin operations) — with caution
1217
+ - Set search_path in SECURITY DEFINER functions to prevent search path injection
1218
+ - Use database triggers for automated side effects: updated_at timestamps, audit logs, notifications
1219
+
1220
+ ## Edge Functions
1221
+ - Write edge functions in Deno/TypeScript — they run on Supabase's edge infrastructure
1222
+ - Use for: webhooks, third-party API calls, custom auth flows, scheduled jobs
1223
+ - Create a Supabase client inside edge functions with the service_role key for admin access
1224
+ - Validate incoming requests: check auth headers, parse and validate request bodies
1225
+ - Use Deno's built-in fetch for external API calls — edge functions have internet access
1226
+ - Deploy with \`supabase functions deploy function-name\`
1227
+ - Set secrets with \`supabase secrets set API_KEY=value\` — access via Deno.env.get()
1228
+
1229
+ ## Real-Time Subscriptions
1230
+ - Subscribe to database changes: \`supabase.channel("posts").on("postgres_changes", { event: "INSERT", schema: "public", table: "posts" }, callback).subscribe()\`
1231
+ - Filter subscriptions: \`filter: "user_id=eq.abc123"\` — don't subscribe to all rows
1232
+ - Use Broadcast for ephemeral messages (typing indicators, cursor positions)
1233
+ - Use Presence for tracking online users and their state
1234
+ - Unsubscribe when components unmount: \`supabase.removeChannel(channel)\`
1235
+ - RLS policies apply to real-time — users only receive changes they're authorized to see
1236
+
1237
+ ## Storage
1238
+ - Use Supabase Storage for file uploads: images, documents, videos
1239
+ - Create buckets with appropriate policies: public (avatars) vs private (documents)
1240
+ - Upload: \`supabase.storage.from("avatars").upload(path, file, { contentType })\`
1241
+ - Use signed URLs for time-limited access to private files: \`createSignedUrl(path, expiresIn)\`
1242
+ - Use image transformations for thumbnails: \`getPublicUrl(path, { transform: { width: 200 } })\`
1243
+ - Set file size limits and allowed MIME types per bucket in storage policies
1244
+
1245
+ ## Typed Client Generation
1246
+ - Generate TypeScript types from your database: \`supabase gen types typescript --project-id xxx > types/supabase.ts\`
1247
+ - Use generated types with the client: \`createClient<Database>(url, key)\`
1248
+ - Types provide autocomplete for table names, column names, and filter operations
1249
+ - Regenerate types after every migration — keep types in sync with the schema
1250
+ - Use Database['public']['Tables']['posts']['Row'] for row types in your app code
1251
+
1252
+ ## Anti-Patterns
1253
+ - Don't skip RLS — an unprotected table is a data breach waiting to happen
1254
+ - Don't use the service_role key on the client side — it bypasses all RLS
1255
+ - Don't query without filters on large tables — always scope your queries
1256
+ - Don't use real-time for everything — polling is simpler for low-frequency updates
1257
+ - Don't store business logic only in the client — use Postgres functions or edge functions
1258
+ - Don't hardcode Supabase URLs and keys — use environment variables
1259
+ `,
1260
+ },
1261
+ {
1262
+ name: "unity-csharp",
1263
+ description: "MonoBehaviour lifecycle, ScriptableObjects, ECS, object pooling, performance profiling",
1264
+ version: "1.0.0",
1265
+ author: "codemaxxing",
1266
+ tags: ["unity", "csharp", "gamedev", "ecs", "performance", "game-engine"],
1267
+ prompt: `# Unity & C# Game Development Expert
1268
+
1269
+ ## MonoBehaviour Lifecycle
1270
+ - Awake() → OnEnable() → Start() → FixedUpdate() → Update() → LateUpdate() → OnDisable() → OnDestroy()
1271
+ - Use Awake() for self-initialization (cache component references with GetComponent<T>())
1272
+ - Use Start() for initialization that depends on other objects being ready
1273
+ - Use FixedUpdate() for physics — it runs at a fixed timestep (default 50Hz), independent of framerate
1274
+ - Use Update() for input handling and non-physics game logic — runs once per frame
1275
+ - Use LateUpdate() for camera follow and anything that must happen after all Update() calls
1276
+ - Cache component references in Awake: \`private Rigidbody _rb; void Awake() => _rb = GetComponent<Rigidbody>();\`
1277
+ - Never use GetComponent in Update — it's an expensive lookup every frame
1278
+
1279
+ ## ScriptableObjects
1280
+ - Use ScriptableObjects for shared, data-driven assets: enemy stats, item definitions, game config
1281
+ - Create with: \`[CreateAssetMenu(fileName = "NewWeapon", menuName = "Game/Weapon")] public class WeaponData : ScriptableObject\`
1282
+ - ScriptableObjects persist in the project (not the scene) — changes in editor persist, changes at runtime don't (in builds)
1283
+ - Use them to decouple data from behavior — MonoBehaviours reference ScriptableObjects, not each other
1284
+ - Event channels: use ScriptableObject-based events to decouple systems without direct references
1285
+ - Pattern: ScriptableObject holds a list of listeners, Raise() notifies all — no singleton needed
1286
+
1287
+ ## Object Pooling
1288
+ - Instantiate/Destroy is expensive — pool frequently created/destroyed objects (bullets, particles, enemies)
1289
+ - Unity's built-in ObjectPool<T> (UnityEngine.Pool): \`new ObjectPool<GameObject>(createFunc, onGet, onRelease, onDestroy)\`
1290
+ - On Get: activate the object, reset its state (position, velocity, health)
1291
+ - On Release: deactivate the object, return it to the pool — don't Destroy it
1292
+ - Pre-warm pools at scene load to avoid frame hitches during gameplay
1293
+ - Use pool for particle systems, audio sources, and UI elements — not just game objects
1294
+
1295
+ ## Entity Component System (ECS)
1296
+ - Unity DOTS: Entities for data, Systems for logic, Components for pure data (no methods)
1297
+ - IComponentData structs are blittable data — no references, no managed types
1298
+ - SystemBase or ISystem process entities with matching component queries
1299
+ - Use Burst compiler for performance-critical systems — compiles to optimized native code
1300
+ - Jobs system for multi-threaded work: IJobEntity, IJobChunk for parallel processing
1301
+ - Use ECS for massive entity counts (10K+ units) — traditional MonoBehaviours for simpler needs
1302
+
1303
+ ## Physics Best Practices
1304
+ - Move Rigidbodies with forces (AddForce) or velocity — never transform.position for physics objects
1305
+ - Use layers and the collision matrix to control which objects interact
1306
+ - Use Physics.OverlapSphereNonAlloc() to avoid allocations in physics queries
1307
+ - Prefer discrete collision detection; use continuous only for fast-moving small objects
1308
+ - Use FixedUpdate for all physics code — Update runs at variable rate and causes jittery physics
1309
+ - Avoid moving static colliders at runtime — it rebuilds the physics tree (expensive)
1310
+
1311
+ ## Coroutines vs Async/Await
1312
+ - Coroutines (yield return): tied to MonoBehaviour, stop when GameObject is disabled/destroyed
1313
+ - Use yield return new WaitForSeconds(t) for delays, WaitUntil(() => condition) for polling
1314
+ - Async/await (UniTask recommended): proper cancellation, no MonoBehaviour dependency, awaitable
1315
+ - Use CancellationToken with async/await and link to destroyCancellationToken for auto-cleanup
1316
+ - Prefer async/await for complex async flows; coroutines for simple sequences and visual scripting
1317
+
1318
+ ## Asset Management
1319
+ - Use Addressables for loading assets on demand — reduces build size and startup time
1320
+ - Never use Resources.Load in production — it forces all Resources/ assets into the build
1321
+ - Unload unused assets: Addressables.Release() for counted references, Resources.UnloadUnusedAssets() as fallback
1322
+ - Use asset bundles / Addressable groups to organize content for DLC or streaming
1323
+ - Sprite atlases for UI and 2D — reduce draw calls by batching sprites into a single texture
1324
+
1325
+ ## Performance Profiling
1326
+ - Use Unity Profiler (Window > Analysis > Profiler) — identify CPU, GPU, memory, and rendering bottlenecks
1327
+ - Profile on target hardware — editor performance is not representative of builds
1328
+ - Watch for GC allocations in hot paths: use struct over class, avoid LINQ in Update, pre-allocate collections
1329
+ - Reduce draw calls: batching, atlasing, LODs, occlusion culling
1330
+ - Use Frame Debugger to inspect individual draw calls and shader passes
1331
+ - Profile with Deep Profile only when needed — it adds significant overhead
1332
+
1333
+ ## Anti-Patterns
1334
+ - Don't use Find("name") or FindObjectOfType at runtime — cache references or use events
1335
+ - Don't allocate in Update: no new List<T>, no LINQ, no string concatenation in hot loops
1336
+ - Don't use SendMessage — it's slow and stringly typed, use direct references or events
1337
+ - Don't put everything on one GameObject — split responsibilities across child objects
1338
+ - Don't ignore the profiler — gut feelings about performance are usually wrong
1339
+ - Don't use singletons for everything — use dependency injection or ScriptableObject events
1340
+ `,
1341
+ },
1342
+ {
1343
+ name: "git-workflow",
1344
+ description: "Conventional commits, branching strategies, PR best practices, rebase, hooks",
1345
+ version: "1.0.0",
1346
+ author: "codemaxxing",
1347
+ tags: ["git", "workflow", "commits", "branching", "code-review", "hooks"],
1348
+ prompt: `# Git Workflow Expert
1349
+
1350
+ ## Conventional Commits
1351
+ - Format: \`type(scope): description\` — e.g., \`feat(auth): add OAuth2 login flow\`
1352
+ - Types: feat (new feature), fix (bug fix), docs, style, refactor, perf, test, build, ci, chore
1353
+ - Breaking changes: add ! after type or BREAKING CHANGE in footer: \`feat(api)!: rename /users to /accounts\`
1354
+ - Scope is optional but helpful: module, component, or feature area
1355
+ - Description: imperative mood, lowercase, no period — "add login page" not "Added login page."
1356
+ - Body: wrap at 72 chars, explain WHAT and WHY (not HOW — the diff shows how)
1357
+ - Use commitlint + husky to enforce conventional commits in CI and locally
1358
+
1359
+ ## Branching Strategies
1360
+ - Trunk-based: short-lived feature branches (1-2 days), merge to main frequently, feature flags for WIP
1361
+ - GitFlow: main + develop + feature/ + release/ + hotfix/ — suited for versioned releases, more overhead
1362
+ - GitHub Flow: branch from main → PR → review → merge to main — simple, good for continuous deployment
1363
+ - For most teams: trunk-based or GitHub Flow — GitFlow adds complexity that slows teams down
1364
+ - Branch naming: type/description — \`feat/user-auth\`, \`fix/login-redirect\`, \`chore/update-deps\`
1365
+ - Delete branches after merge — don't accumulate stale branches
1366
+
1367
+ ## Pull Request Best Practices
1368
+ - Keep PRs small (under 400 lines changed) — large PRs get rubber-stamped, not reviewed
1369
+ - Write descriptive PR titles and descriptions: what changed, why, how to test
1370
+ - One concern per PR — don't mix a feature with a refactor with a bug fix
1371
+ - Add screenshots/recordings for UI changes
1372
+ - Self-review your PR before requesting review — catch obvious issues yourself
1373
+ - Request reviewers who own the affected code area
1374
+ - Respond to review comments promptly — don't let PRs go stale
1375
+
1376
+ ## Interactive Rebase
1377
+ - Use \`git rebase -i HEAD~N\` to clean up commits before opening a PR
1378
+ - Squash WIP commits into logical units: one commit per meaningful change
1379
+ - Reword commit messages to follow conventions: pick → reword
1380
+ - Fixup: absorb small fixes into the commit they belong to: pick → fixup
1381
+ - Never rebase commits that are already on shared branches (main, develop)
1382
+ - Prefer rebase over merge for feature branches — cleaner linear history
1383
+ - After rebase, force-push to your branch only: \`git push --force-with-lease\` (safer than --force)
1384
+
1385
+ ## Cherry-Pick & Bisect
1386
+ - Cherry-pick to apply specific commits to another branch: \`git cherry-pick <sha>\`
1387
+ - Use cherry-pick for hotfixes: fix on main, cherry-pick to release branch
1388
+ - Use -x flag to record the source commit: \`git cherry-pick -x <sha>\`
1389
+ - Bisect to find the commit that introduced a bug: \`git bisect start\`, \`git bisect bad\`, \`git bisect good <sha>\`
1390
+ - Automate bisect with a test script: \`git bisect run npm test\`
1391
+ - Bisect is O(log n) — it finds the bad commit in ~10 steps for 1000 commits
1392
+
1393
+ ## Git Hooks
1394
+ - Use husky (npm) or pre-commit (Python) to manage hooks across the team
1395
+ - pre-commit: lint staged files (lint-staged), format code, check for secrets
1396
+ - commit-msg: validate commit message format (commitlint)
1397
+ - pre-push: run tests, type-check — catch issues before they hit CI
1398
+ - Don't put slow operations in pre-commit — keep it under 5 seconds
1399
+ - Use lint-staged to only process staged files: \`"*.ts": ["eslint --fix", "prettier --write"]\`
1400
+
1401
+ ## .gitattributes & Configuration
1402
+ - Use .gitattributes for consistent line endings: \`* text=auto\` normalizes to LF
1403
+ - Mark binary files: \`*.png binary\`, \`*.zip binary\` — prevents diff/merge issues
1404
+ - Use .gitattributes for diff drivers: \`*.lockfile binary\` to skip noisy lockfile diffs
1405
+ - Use .gitignore for build artifacts, dependencies, env files, editor config
1406
+ - Global gitignore (~/.gitignore_global) for personal editor files (.vscode, .idea, .DS_Store)
1407
+ - Configure merge strategies per file: \`package-lock.json merge=ours\` to auto-resolve lockfile conflicts
1408
+
1409
+ ## Advanced Techniques
1410
+ - Use git stash for quick context switches: \`git stash push -m "WIP: feature X"\`
1411
+ - Use git worktree for working on multiple branches simultaneously without stashing
1412
+ - Use git reflog to recover lost commits — it tracks every HEAD movement for 90 days
1413
+ - Use git blame -w to ignore whitespace changes when tracking down who wrote a line
1414
+ - Use git log --all --graph --oneline for a visual branch/merge history
1415
+ - Use git diff --stat for a quick summary of changes before committing
1416
+
1417
+ ## Anti-Patterns
1418
+ - Don't commit directly to main — use branches and PRs for all changes
1419
+ - Don't use \`git add .\` blindly — review staged files to avoid committing secrets or artifacts
1420
+ - Don't rewrite shared history — rebase and amend only your own unpushed commits
1421
+ - Don't write commit messages like "fix" or "WIP" or "asdf" — future you will be confused
1422
+ - Don't keep long-lived branches — merge or rebase frequently to avoid painful conflicts
1423
+ - Don't skip code review — even small changes benefit from a second pair of eyes
470
1424
  `,
471
1425
  },
472
1426
  ];