smithery.ai

react-rules

This is a new rule

First seen Mar 21, 2026

Installation

$ npx skills add https://smithery.ai

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery.ai · top by installs.

npx skills add https://smithery.ai

Browse all from smithery.ai

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 10,310 B
  • docs SUMMARY.md 37 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 1 installs

SKILL.md

Cursor Rules for Saitre Language App

Core Principles

  1. Small Files: No component, hook, or service file should exceed 300 lines. If it does, break it down.
  2. Single Responsibility: Each component, hook, and service should do ONE thing well.
  3. Separation of Concerns: Business logic in services/hooks, UI in components, utilities in utils.
  4. Documentation: Always explain "why", not just "what". Use JSDoc for all exported functions and components.

Component Guidelines

Component Size

  • Maximum 300 lines per component file
  • If a component exceeds 200 lines, consider breaking it into smaller sub-components
  • Each sub-component should be 50-150 lines

Component Structure

  • Components should ONLY handle UI rendering and user interactions
  • Extract business logic to custom hooks or services
  • Use composition: break large components into smaller, focused components
  • One component = one responsibility

Component Documentation

Always include JSDoc for components:

/**
 * ComponentName - Brief description of what it does
 * 
 * @component
 * @param {Object} props
 * @param {Type} props.propName - Description and why it's needed
 * 
 * Features:
 * - Feature 1
 * - Feature 2
 * 
 * Usage:
 * ```jsx
 * <ComponentName propName={value} />
 * ```
 */

State Management

useState Guidelines

  • Maximum 5-7 useState hooks per component
  • If you need more, use useReducer for complex state
  • Group related state into objects when appropriate
  • Extract state management to custom hooks if it's complex

Custom Hooks

  • Create custom hooks for reusable state logic
  • Name hooks with use prefix
  • Document hooks with JSDoc explaining purpose and return values

State Updates

  • Never update state based on props directly in render
  • Use useEffect with proper dependencies for prop-to-state sync
  • Prefer controlled components over local state when possible
  • Use useMemo for expensive derived state

File Organization

Component Files

  • One component per file
  • File name matches component name (PascalCase)
  • Place in appropriate directory: components/{feature}/ComponentName.jsx

Service Files

  • One service per domain (e.g., wordsService.js, sentencesService.js)
  • Split if service exceeds 300 lines
  • Separate CRUD operations from business logic
  • Separate query operations from mutation operations

Utility Files

  • Group related utilities together
  • One utility file per domain (e.g., wordHelpers.js, validators.js)
  • Split if file exceeds 300 lines

Code Quality

No Console.log in Production

  • NEVER use console.log, console.warn, or console.info in production code
  • Use a logging utility instead:

``javascript import { logger } from '../utils/logger'; logger.debug('Debug message'); // Only in development logger.error('Error message'); // Always logged ``

  • Remove all console.log statements before committing

Error Handling

  • Services should throw typed errors (ValidationError, NotFoundError, etc.)
  • Hooks should catch errors and return error state
  • Components should display user-friendly error messages
  • Always handle errors - never silently fail

Validation

  • Centralize validation logic in utils/validators.js
  • Use same validators in both components and services
  • Return structured validation results: { valid: boolean, error?: string }

Constants

  • Extract magic numbers and strings to constants
  • Create constant files: constants/debounce.js, constants/batching.js, constants/ui.js
  • Document why each constant has its value

Naming Conventions

Functions

  • Event handlers: handle* (e.g., handleSubmit, handleChange)
  • Toggle functions: toggle or handleToggle (e.g., toggleExpanded)
  • Getter functions: get* (e.g., getWordRoleIds)
  • Transformer functions: transform, normalize, format* (e.g., normalizeWord)
  • Boolean state: is, has, should, show (be consistent within component)

Variables

  • Use descriptive names that explain purpose
  • Avoid abbreviations unless widely understood
  • Boolean variables should be clearly true/false (e.g., isLoading, not loading)

Files

  • Components: PascalCase (e.g., WordForm.jsx)
  • Hooks: camelCase with use prefix (e.g., useWords.js)
  • Services: camelCase (e.g., wordsService.js)
  • Utils: camelCase (e.g., wordHelpers.js)

Documentation Requirements

Function Documentation

Always include JSDoc with:

  • What the function does
  • Why it exists (the problem it solves)
  • Parameters with types and descriptions
  • Return value with type and description
  • Usage examples for complex functions

Example:

/**
 * Aggregates word fields from meanings array for efficient Firestore queries
 * 
 * WHY: Firestore doesn't support querying nested arrays (meanings[].tags).
 * We pre-aggregate roleIds, tags, and search terms into top-level arrays
 * to enable efficient queries like "find words with tag X".
 * 
 * MUST be called on every create/update to keep aggregates in sync.
 * 
 * @param {Object} wordData - Word data with meanings array
 * @param {Array} wordData.meanings - Array of meaning objects
 * @returns {Object} Aggregated fields: { roleIds: [], tags: [], search: [] }
 */

Complex Logic Documentation

  • Explain algorithms and approaches
  • Document edge cases and why they're handled
  • Include performance considerations if relevant

React Best Practices

Component Composition

  • Break UI into component hierarchy (see React's "Thinking in React" guide)
  • Build static version first, then add interactivity
  • Keep components focused on one visual/functional area

Props and State

  • Identify minimal state (what changes over time)
  • State should be owned by the closest common parent
  • Pass data down via props, pass callbacks up for updates
  • Don't store derived data in state - compute it

Performance

  • Use useMemo for expensive calculations
  • Use useCallback for functions passed to child components
  • Memoize list items with React.memo when appropriate
  • Don't fetch more data than needed

Hooks

  • Custom hooks should be reusable and focused
  • One hook = one concern (data fetching, form state, etc.)
  • Don't mix data fetching with mutations in same hook

Code Structure

Import Order

  1. React and React-related imports
  2. Third-party libraries
  3. Internal hooks
  4. Internal services
  5. Internal utils
  6. Internal components
  7. Types/interfaces (if using TypeScript)
  8. Constants
  9. Styles

Function Order in Components

  1. Component definition with props destructuring
  2. Hooks (useState, useEffect, useMemo, etc.)
  3. Event handlers
  4. Render helpers
  5. Early returns (loading, error states)
  6. Main render return

When Creating New Code

Before Writing

  1. Check if similar functionality exists
  2. Identify the single responsibility
  3. Plan component/hook/service structure
  4. Consider file size limits

While Writing

  1. Write JSDoc comments first
  2. Extract constants immediately
  3. Keep functions small (< 50 lines)
  4. Use descriptive variable names
  5. Add "why" comments for complex logic

After Writing

  1. Check file size (< 300 lines)
  2. Verify single responsibility
  3. Remove any console.log statements
  4. Add error handling
  5. Document complex logic

Refactoring Guidelines

When to Refactor

  • File exceeds 300 lines
  • Component has more than 7 useState hooks
  • Function exceeds 50 lines
  • Business logic in component
  • Duplicated code appears

How to Refactor

  1. Identify the single responsibility
  2. Extract to smaller components/hooks/services
  3. Move business logic to appropriate layer
  4. Update documentation
  5. Test the refactored code

Anti-Patterns to Avoid

❌ DON'T

  • Create components over 300 lines
  • Mix business logic with UI components
  • Use console.log in production code
  • Create components with 10+ useState hooks
  • Duplicate validation logic
  • Write functions without JSDoc
  • Use magic numbers/strings without constants
  • Fetch all data when only some is needed
  • Store derived data in state
  • Silently catch errors without user feedback

✅ DO

  • Break large components into smaller ones
  • Extract business logic to hooks/services
  • Use logging utility for debug messages
  • Use useReducer for complex state
  • Centralize validation logic
  • Document all exported functions
  • Extract constants with explanations
  • Fetch only needed data
  • Compute derived data with useMemo
  • Show user-friendly error messages

Examples

Good Component Structure

/**
 * WordCard - Displays a word card with basic info and actions
 * 
 * @component
 * @param {Object} props
 * @param {Object} props.word - Word object to display
 * @param {Function} props.onEdit - Callback when edit button clicked
 * @param {Function} props.onDelete - Callback when delete button clicked
 */
export default function WordCard({ word, onEdit, onDelete }) {
  const normalizedWord = useMemo(() => normalizeWord(word), [word]);
  const roleIds = useMemo(() => getWordRoleIds(normalizedWord), [normalizedWord]);
  
  if (!normalizedWord) return null;
  
  return (
    <div className="word-card">
      {/* UI rendering */}
    </div>
  );
}

Good Hook Structure

/**
 * useWord - Fetches a single word with real-time updates
 * 
 * WHY: Provides consistent word fetching with loading/error states.
 * Uses real-time listener for automatic updates when word changes.
 * 
 * @param {string} wordId - ID of word to fetch
 * @returns {Object} { word, loading, error }
 */
export function useWord(wordId) {
  // Hook implementation
}

Good Service Structure

/**
 * Creates a word in Firestore
 * 
 * WHY: Centralizes word creation logic, ensures aggregates are calculated,
 * and validates data before saving to prevent invalid data.
 * 
 * @param {Object} wordData - Word data to create
 * @returns {Promise<Object>} Created word object
 * @throws {ValidationError} If word data is invalid
 */
export async function createWord(wordData) {
  // Service implementation
}

Remember: When in doubt, break it down. Smaller, focused code is always better than large, complex code.