All skills
davila7 avatar

/frontend-dev-guidelines

@1deb97c

Frontend development guidelines for React/TypeScript applications. Modern patterns including Suspense, lazy loading, useSuspenseQuery, file organization with features directory, MUI v7 styling, TanStack Router, performance optimization, and TypeScript best practices. Use when creating components, pages, features, fetching data, styling, routing, or working with frontend code.

Use this Skill: https://skilld.dev/gh/davila7/claude-code-templates/frontend-dev-guidelines

This session only. Nothing lands on disk.

resourcesfile-organization.md

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

File Organization

Proper file and directory structure for maintainable, scalable frontend code in the the application.


features/ vs components/ Distinction

features/ Directory

Purpose: Domain-specific features with their own logic, API, and components

When to use:

  • Feature has multiple related components
  • Feature has its own API endpoints
  • Feature has domain-specific logic
  • Feature has custom hooks/utilities

Examples:

  • features/posts/ - Project catalog/post management
  • features/blogs/ - Blog builder and rendering
  • features/auth/ - Authentication flows

Structure:

features/
  my-feature/
    api/
      myFeatureApi.ts         # API service layer
    components/
      MyFeatureMain.tsx       # Main component
      SubComponents/          # Related components
    hooks/
      useMyFeature.ts         # Custom hooks
      useSuspenseMyFeature.ts # Suspense hooks
    helpers/
      myFeatureHelpers.ts     # Utility functions
    types/
      index.ts                # TypeScript types
    index.ts                  # Public exports

components/ Directory

Purpose: Truly reusable components used across multiple features

When to use:

  • Component is used in 3+ places
  • Component is generic (no feature-specific logic)
  • Component is a UI primitive or pattern

Examples:

  • components/SuspenseLoader/ - Loading wrapper
  • components/CustomAppBar/ - Application header
  • components/ErrorBoundary/ - Error handling
  • components/LoadingOverlay/ - Loading overlay

Structure:

components/
  SuspenseLoader/
    SuspenseLoader.tsx
    SuspenseLoader.test.tsx
  CustomAppBar/
    CustomAppBar.tsx
    CustomAppBar.test.tsx

Feature Directory Structure (Detailed)

Complete Feature Example

Based on features/posts/ structure:

features/
  posts/
    api/
      postApi.ts              # API service layer (GET, POST, PUT, DELETE)

    components/
      PostTable.tsx           # Main container component
      grids/
        PostDataGrid/
          PostDataGrid.tsx
      drawers/
        ProjectPostDrawer/
          ProjectPostDrawer.tsx
      cells/
        editors/
          TextEditCell.tsx
        renderers/
          DateCell.tsx
      toolbar/
        CustomToolbar.tsx

    hooks/
      usePostQueries.ts       # Regular queries
      useSuspensePost.ts      # Suspense queries
      usePostMutations.ts     # Mutations
      useGridLayout.ts              # Feature-specific hooks

    helpers/
      postHelpers.ts          # Utility functions
      validation.ts                 # Validation logic

    types/
      index.ts                      # TypeScript types/interfaces

    queries/
      postQueries.ts          # Query key factories (optional)

    context/
      PostContext.tsx         # React context (if needed)

    index.ts                        # Public API exports

Subdirectory Guidelines

api/ Directory

Purpose: Centralized API calls for the feature

Files:

  • {feature}Api.ts - Main API service

Pattern:

// features/my-feature/api/myFeatureApi.ts
import apiClient from '@/lib/apiClient';

export const myFeatureApi = {
    getItem: async (id: number) => {
        const { data } = await apiClient.get(`/blog/items/${id}`);
        return data;
    },
    createItem: async (payload) => {
        const { data } = await apiClient.post('/blog/items', payload);
        return data;
    },
};
components/ Directory

Purpose: Feature-specific components

Organization:

  • Flat structure if <5 components
  • Subdirectories by responsibility if >5 components

Examples:

components/
  MyFeatureMain.tsx           # Main component
  MyFeatureHeader.tsx         # Supporting components
  MyFeatureFooter.tsx

  # OR with subdirectories:
  containers/
    MyFeatureContainer.tsx
  presentational/
    MyFeatureDisplay.tsx
  blogs/
    MyFeatureBlog.tsx
hooks/ Directory

Purpose: Custom hooks for the feature

Naming:

  • use prefix (camelCase)
  • Descriptive of what they do

Examples:

hooks/
  useMyFeature.ts               # Main hook
  useSuspenseMyFeature.ts       # Suspense version
  useMyFeatureMutations.ts      # Mutations
  useMyFeatureFilters.ts        # Filters/search
helpers/ Directory

Purpose: Utility functions specific to the feature

Examples:

helpers/
  myFeatureHelpers.ts           # General utilities
  validation.ts                 # Validation logic
  transblogers.ts               # Data transblogations
  constants.ts                  # Constants
types/ Directory

Purpose: TypeScript types and interfaces

Files:

types/
  index.ts                      # Main types, exported
  internal.ts                   # Internal types (not exported)

Import Aliases (Vite Configuration)

Available Aliases

From vite.config.ts lines 180-185:

Alias Resolves To Use For
@/ src/ Absolute imports from src root
~types src/types Shared TypeScript types
~components src/components Reusable components
~features src/features Feature imports

Usage Examples

// ✅ PREFERRED - Use aliases for absolute imports
import { apiClient } from '@/lib/apiClient';
import { SuspenseLoader } from '~components/SuspenseLoader';
import { postApi } from '~features/posts/api/postApi';
import type { User } from '~types/user';

// ❌ AVOID - Relative paths from deep nesting
import { apiClient } from '../../../lib/apiClient';
import { SuspenseLoader } from '../../../components/SuspenseLoader';

When to Use Which Alias

@/ (General):

  • Lib utilities: @/lib/apiClient
  • Hooks: @/hooks/useAuth
  • Config: @/config/theme
  • Shared services: @/services/authService

~types (Type Imports):

import type { Post } from '~types/post';
import type { User, UserRole } from '~types/user';

~components (Reusable Components):

import { SuspenseLoader } from '~components/SuspenseLoader';
import { CustomAppBar } from '~components/CustomAppBar';
import { ErrorBoundary } from '~components/ErrorBoundary';

~features (Feature Imports):

import { postApi } from '~features/posts/api/postApi';
import { useAuth } from '~features/auth/hooks/useAuth';

File Naming Conventions

Components

Pattern: PascalCase with .tsx extension

MyComponent.tsx
PostDataGrid.tsx
CustomAppBar.tsx

Avoid:

  • camelCase: myComponent.tsx ❌
  • kebab-case: my-component.tsx ❌
  • All caps: MYCOMPONENT.tsx ❌

Hooks

Pattern: camelCase with use prefix, .ts extension

useMyFeature.ts
useSuspensePost.ts
useAuth.ts
useGridLayout.ts

API Services

Pattern: camelCase with Api suffix, .ts extension

myFeatureApi.ts
postApi.ts
userApi.ts

Helpers/Utilities

Pattern: camelCase with descriptive name, .ts extension

myFeatureHelpers.ts
validation.ts
transblogers.ts
constants.ts

Types

Pattern: camelCase, index.ts or descriptive name

types/index.ts
types/post.ts
types/user.ts

When to Create a New Feature

Create New Feature When:

  • Multiple related components (>3)
  • Has own API endpoints
  • Domain-specific logic
  • Will grow over time
  • Reused across multiple routes

Example: features/posts/

  • 20+ components
  • Own API service
  • Complex state management
  • Used in multiple routes

Add to Existing Feature When:

  • Related to existing feature
  • Shares same API
  • Logically grouped
  • Extends existing functionality

Example: Adding export dialog to posts feature

Create Reusable Component When:

  • Used across 3+ features
  • Generic, no domain logic
  • Pure presentation
  • Shared pattern

Example: components/SuspenseLoader/


Import Organization

Import Order (Recommended)

// 1. React and React-related
import React, { useState, useCallback, useMemo } from 'react';
import { lazy } from 'react';

// 2. Third-party libraries (alphabetical)
import { Box, Paper, Button, Grid } from '@mui/material';
import type { SxProps, Theme } from '@mui/material';
import { useSuspenseQuery, useQueryClient } from '@tanstack/react-query';
import { createFileRoute } from '@tanstack/react-router';

// 3. Alias imports (@ first, then ~)
import { apiClient } from '@/lib/apiClient';
import { useAuth } from '@/hooks/useAuth';
import { useMuiSnackbar } from '@/hooks/useMuiSnackbar';
import { SuspenseLoader } from '~components/SuspenseLoader';
import { postApi } from '~features/posts/api/postApi';

// 4. Type imports (grouped)
import type { Post } from '~types/post';
import type { User } from '~types/user';

// 5. Relative imports (same feature)
import { MySubComponent } from './MySubComponent';
import { useMyFeature } from '../hooks/useMyFeature';
import { myFeatureHelpers } from '../helpers/myFeatureHelpers';

Use single quotes for all imports (project standard)


Public API Pattern

feature/index.ts

Export public API from feature for clean imports:

// features/my-feature/index.ts

// Export main components
export { MyFeatureMain } from './components/MyFeatureMain';
export { MyFeatureHeader } from './components/MyFeatureHeader';

// Export hooks
export { useMyFeature } from './hooks/useMyFeature';
export { useSuspenseMyFeature } from './hooks/useSuspenseMyFeature';

// Export API
export { myFeatureApi } from './api/myFeatureApi';

// Export types
export type { MyFeatureData, MyFeatureConfig } from './types';

Usage:

// ✅ Clean import from feature index
import { MyFeatureMain, useMyFeature } from '~features/my-feature';

// ❌ Avoid deep imports (but OK if needed)
import { MyFeatureMain } from '~features/my-feature/components/MyFeatureMain';

Directory Structure Visualization

src/
├── features/                    # Domain-specific features
│   ├── posts/
│   │   ├── api/
│   │   ├── components/
│   │   ├── hooks/
│   │   ├── helpers/
│   │   ├── types/
│   │   └── index.ts
│   ├── blogs/
│   └── auth/
│
├── components/                  # Reusable components
│   ├── SuspenseLoader/
│   ├── CustomAppBar/
│   ├── ErrorBoundary/
│   └── LoadingOverlay/
│
├── routes/                      # TanStack Router routes
│   ├── __root.tsx
│   ├── index.tsx
│   ├── project-catalog/
│   │   ├── index.tsx
│   │   └── create/
│   └── blogs/
│
├── hooks/                       # Shared hooks
│   ├── useAuth.ts
│   ├── useMuiSnackbar.ts
│   └── useDebounce.ts
│
├── lib/                         # Shared utilities
│   ├── apiClient.ts
│   └── utils.ts
│
├── types/                       # Shared TypeScript types
│   ├── user.ts
│   ├── post.ts
│   └── common.ts
│
├── config/                      # Configuration
│   └── theme.ts
│
└── App.tsx                      # Root component

Summary

Key Principles:

  1. features/ for domain-specific code
  2. components/ for truly reusable UI
  3. Use subdirectories: api/, components/, hooks/, helpers/, types/
  4. Import aliases for clean imports (@/, ~types, ~components, ~features)
  5. Consistent naming: PascalCase components, camelCase utilities
  6. Export public API from feature index.ts

See Also:

Source: SKILL.md on GitHub

1 alert16d4 checks · Risk HIGH
  • Gen Agent Trust Hub16d

    The skill recommends the use of non-standard and potentially malicious Node.js packages that appear to be typosquats of the popular react-hook-form library. Furthermore, the documentation contains a systematic and deceptive string replacement pattern where 'form' is replaced with 'blog' (e.g., 'transblogers', 'Perblogance'), which could be used to evade security filters or cause the generation of broken code.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer7mo

    11/11 files flagged

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

Last checked against GitHub 19 hours ago.

Activeupdated 8 months ago

README badge

README badge for davila7/claude-code-templates/frontend-dev-guidelines