All skills
sergiodxa avatar

/frontend-react-best-practices

@734526d

React performance optimization guidelines. Use when writing, reviewing, or refactoring React components to ensure optimal rendering and bundle patterns. Triggers on tasks involving React components, hooks, memoization, or bundle optimization.

Use this Skill: https://skilld.dev/gh/sergiodxa/agent-skills/frontend-react-best-practices

This session only. Nothing lands on disk.

rulescomposition-typescript-namespaces.md

≈1.2k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Use TypeScript Namespaces for Component Types

Combine a component and its related types using TypeScript namespaces for cleaner imports.

Why

  • Single import gives you component + all its types
  • Avoids naming conflicts (ButtonProps vs Button.Props)
  • Groups related types together (Button.Props, Button.Variant, Button.Size)
  • Cleaner API for consumers of the component

Important: Types Only

Namespaces should only contain type definitions, never runtime code.

// Good: namespace contains only types
export namespace Button {
  export type Props = { ... };
  export type Variant = "solid" | "ghost";
}

// Bad: namespace contains runtime code
export namespace Button {
  export const defaultVariant = "solid"; // Don't do this
  export function getClassName() { ... } // Don't do this
}

Pattern

// components/button.tsx

export namespace Button {
  export type Variant = "solid" | "ghost" | "outline";
  export type Size = "sm" | "md" | "lg";

  export interface Props {
    variant?: Variant;
    size?: Size;
    children: React.ReactNode;
    onClick?: () => void;
    disabled?: boolean;
  }
}

export function Button({
  variant = "solid",
  size = "md",
  children,
  onClick,
  disabled,
}: Button.Props) {
  return (
    <button
      className={getButtonClasses(variant, size)}
      onClick={onClick}
      disabled={disabled}
    >
      {children}
    </button>
  );
}

Usage

Consumers import once and get everything:

import { Button } from "~/components/button";

// Use the component
<Button variant="ghost" size="lg">
  Click me
</Button>;

// Use the types
function CustomButton(props: Button.Props) {
  return <Button {...props} />;
}

// Use specific type
function getVariantColor(variant: Button.Variant): string {
  switch (variant) {
    case "solid":
      return "blue";
    case "ghost":
      return "transparent";
    case "outline":
      return "white";
  }
}

Without Namespaces (Comparison)

// Without namespace - multiple exports, potential naming conflicts
import {
  Button,
  ButtonProps,
  ButtonVariant,
  ButtonSize,
} from "~/components/button";

// Or with renaming
import { Button, type Props as ButtonProps } from "~/components/button";

Extending Types

When creating a component that extends another:

// components/icon-button.tsx
import { Button } from "./button";

export namespace IconButton {
  export interface Props extends Omit<Button.Props, "children"> {
    icon: React.ReactNode;
    label: string; // For accessibility
  }
}

export function IconButton({ icon, label, ...buttonProps }: IconButton.Props) {
  return (
    <Button {...buttonProps} aria-label={label}>
      {icon}
    </Button>
  );
}

Complex Component Example

// components/select.tsx

export namespace Select {
  export interface Option<T = string> {
    value: T;
    label: string;
    disabled?: boolean;
  }

  export interface Props<T = string> {
    options: Option<T>[];
    value: T;
    onChange: (value: T) => void;
    placeholder?: string;
    disabled?: boolean;
  }

  export type Size = "sm" | "md" | "lg";
}

export function Select<T extends string>({
  options,
  value,
  onChange,
  placeholder,
  disabled,
}: Select.Props<T>) {
  // Implementation
}

Usage:

import { Select } from "~/components/select";

type Status = "active" | "inactive" | "pending";

let options: Select.Option<Status>[] = [
  { value: "active", label: "Active" },
  { value: "inactive", label: "Inactive" },
  { value: "pending", label: "Pending" },
];

<Select<Status> options={options} value={status} onChange={setStatus} />;

When to Use

Scenario Recommendation
Simple component with Props only Optional - either pattern works
Component with multiple related types Use namespace
Type might conflict with other types Use namespace
Building a component library Use namespace
Internal utility component Optional

Rules

  1. Types only - Never put runtime code (values, functions) in namespaces
  2. Export both namespace and function with the same name
  3. Use Button.Props instead of ButtonProps naming convention
  4. Group all component-related types in the namespace
  5. Prefer interface for Props, type for unions/aliases

Source: SKILL.md on GitHub

1 warning16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    This skill is a collection of React performance and composition guidelines. It contains no executable code, scripts, or malicious patterns and is entirely informational.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer7mo

    37/37 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 734526d. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Dormantupdated 8 months ago

README badge

README badge for sergiodxa/agent-skills/frontend-react-best-practices