🎁 Get the FREE AI Skills Starter Guide β€” Subscribe β†’
BytesAgainBytesAgain
πŸ¦€ ClawHub

Senior Frontend

by @alirezarezvani

Frontend development skill for React, Next.js, TypeScript, and Tailwind CSS applications. Use when building React components, optimizing Next.js performance,...

Versionv2.1.1
Downloads1,860
Installs15
TERMINAL
clawhub install senior-frontend

πŸ“– About This Skill


name: "senior-frontend" description: Frontend development skill for React, Next.js, TypeScript, and Tailwind CSS applications. Use when building React components, optimizing Next.js performance, analyzing bundle sizes, scaffolding frontend projects, implementing accessibility, or reviewing frontend code quality.

Senior Frontend

Frontend development patterns, performance optimization, and automation tools for React/Next.js applications.

Table of Contents

  • Project Scaffolding
  • Component Generation
  • Bundle Analysis
  • React Patterns
  • Next.js Optimization
  • Accessibility and Testing

  • Project Scaffolding

    Generate a new Next.js or React project with TypeScript, Tailwind CSS, and best practice configurations.

    Workflow: Create New Frontend Project

    1. Run the scaffolder with your project name and template:

       python scripts/frontend_scaffolder.py my-app --template nextjs
       

    2. Add optional features (auth, api, forms, testing, storybook):

       python scripts/frontend_scaffolder.py dashboard --template nextjs --features auth,api
       

    3. Navigate to the project and install dependencies:

       cd my-app && npm install
       

    4. Start the development server:

       npm run dev
       

    Scaffolder Options

    | Option | Description | |--------|-------------| | --template nextjs | Next.js 14+ with App Router and Server Components | | --template react | React + Vite with TypeScript | | --features auth | Add NextAuth.js authentication | | --features api | Add React Query + API client | | --features forms | Add React Hook Form + Zod validation | | --features testing | Add Vitest + Testing Library | | --dry-run | Preview files without creating them |

    Generated Structure (Next.js)

    my-app/
    β”œβ”€β”€ app/
    β”‚   β”œβ”€β”€ layout.tsx        # Root layout with fonts
    β”‚   β”œβ”€β”€ page.tsx          # Home page
    β”‚   β”œβ”€β”€ globals.css       # Tailwind + CSS variables
    β”‚   └── api/health/route.ts
    β”œβ”€β”€ components/
    β”‚   β”œβ”€β”€ ui/               # Button, Input, Card
    β”‚   └── layout/           # Header, Footer, Sidebar
    β”œβ”€β”€ hooks/                # useDebounce, useLocalStorage
    β”œβ”€β”€ lib/                  # utils (cn), constants
    β”œβ”€β”€ types/                # TypeScript interfaces
    β”œβ”€β”€ tailwind.config.ts
    β”œβ”€β”€ next.config.js
    └── package.json
    


    Component Generation

    Generate React components with TypeScript, tests, and Storybook stories.

    Workflow: Create a New Component

    1. Generate a client component:

       python scripts/component_generator.py Button --dir src/components/ui
       

    2. Generate a server component:

       python scripts/component_generator.py ProductCard --type server
       

    3. Generate with test and story files:

       python scripts/component_generator.py UserProfile --with-test --with-story
       

    4. Generate a custom hook:

       python scripts/component_generator.py FormValidation --type hook
       

    Generator Options

    | Option | Description | |--------|-------------| | --type client | Client component with 'use client' (default) | | --type server | Async server component | | --type hook | Custom React hook | | --with-test | Include test file | | --with-story | Include Storybook story | | --flat | Create in output dir without subdirectory | | --dry-run | Preview without creating files |

    Generated Component Example

    'use client';

    import { useState } from 'react'; import { cn } from '@/lib/utils';

    interface ButtonProps { className?: string; children?: React.ReactNode; }

    export function Button({ className, children }: ButtonProps) { return (

    {children}
    ); }


    Bundle Analysis

    Analyze package.json and project structure for bundle optimization opportunities.

    Workflow: Optimize Bundle Size

    1. Run the analyzer on your project:

       python scripts/bundle_analyzer.py /path/to/project
       

    2. Review the health score and issues:

       Bundle Health Score: 75/100 (C)

    HEAVY DEPENDENCIES: moment (290KB) Alternative: date-fns (12KB) or dayjs (2KB)

    lodash (71KB) Alternative: lodash-es with tree-shaking

    3. Apply the recommended fixes by replacing heavy dependencies.

    4. Re-run with verbose mode to check import patterns:

       python scripts/bundle_analyzer.py . --verbose
       

    Bundle Score Interpretation

    | Score | Grade | Action | |-------|-------|--------| | 90-100 | A | Bundle is well-optimized | | 80-89 | B | Minor optimizations available | | 70-79 | C | Replace heavy dependencies | | 60-69 | D | Multiple issues need attention | | 0-59 | F | Critical bundle size problems |

    Heavy Dependencies Detected

    The analyzer identifies these common heavy packages:

    | Package | Size | Alternative | |---------|------|-------------| | moment | 290KB | date-fns (12KB) or dayjs (2KB) | | lodash | 71KB | lodash-es with tree-shaking | | axios | 14KB | Native fetch or ky (3KB) | | jquery | 87KB | Native DOM APIs | | @mui/material | Large | shadcn/ui or Radix UI |


    React Patterns

    Reference: references/react_patterns.md

    Compound Components

    Share state between related components:

    const Tabs = ({ children }) => {
      const [active, setActive] = useState(0);
      return (
        
          {children}
        
      );
    };

    Tabs.List = TabList; Tabs.Panel = TabPanel;

    // Usage One Two Content 1 Content 2

    Custom Hooks

    Extract reusable logic:

    function useDebounce(value: T, delay = 500): T {
      const [debouncedValue, setDebouncedValue] = useState(value);

    useEffect(() => { const timer = setTimeout(() => setDebouncedValue(value), delay); return () => clearTimeout(timer); }, [value, delay]);

    return debouncedValue; }

    // Usage const debouncedSearch = useDebounce(searchTerm, 300);

    Render Props

    Share rendering logic:

    function DataFetcher({ url, render }) {
      const [data, setData] = useState(null);
      const [loading, setLoading] = useState(true);

    useEffect(() => { fetch(url).then(r => r.json()).then(setData).finally(() => setLoading(false)); }, [url]);

    return render({ data, loading }); }

    // Usage loading ? : } />


    Next.js Optimization

    Reference: references/nextjs_optimization_guide.md

    Server vs Client Components

    Use Server Components by default. Add 'use client' only when you need:

  • Event handlers (onClick, onChange)
  • State (useState, useReducer)
  • Effects (useEffect)
  • Browser APIs
  • // Server Component (default) - no 'use client'
    async function ProductPage({ params }) {
      const product = await getProduct(params.id);  // Server-side fetch

    return (

    {product.name}

    {/* Client component */}
    ); }

    // Client Component 'use client'; function AddToCartButton({ productId }) { const [adding, setAdding] = useState(false); return ; }

    Image Optimization

    import Image from 'next/image';

    // Above the fold - load immediately Hero

    // Responsive image with fill

    Product

    Data Fetching Patterns

    // Parallel fetching
    async function Dashboard() {
      const [user, stats] = await Promise.all([
        getUser(),
        getStats()
      ]);
      return 
    ...
    ; }

    // Streaming with Suspense async function ProductPage({ params }) { return (

    }>
    ); }


    Accessibility and Testing

    Reference: references/frontend_best_practices.md

    Accessibility Checklist

    1. Semantic HTML: Use proper elements (

    // Skip link for keyboard users Skip to main content

    Testing Strategy

    // Component test with React Testing Library
    import { render, screen } from '@testing-library/react';
    import userEvent from '@testing-library/user-event';

    test('button triggers action on click', async () => { const onClick = vi.fn(); render();

    await userEvent.click(screen.getByRole('button')); expect(onClick).toHaveBeenCalledTimes(1); });

    // Test accessibility test('dialog is accessible', async () => { render(

    );

    expect(screen.getByRole('dialog')).toBeInTheDocument(); expect(screen.getByRole('dialog')).toHaveAttribute('aria-labelledby'); });


    Quick Reference

    Common Next.js Config

    // next.config.js
    const nextConfig = {
      images: {
        remotePatterns: [{ hostname: "cdnexamplecom" }],
        formats: ['image/avif', 'image/webp'],
      },
      experimental: {
        optimizePackageImports: ['lucide-react', '@heroicons/react'],
      },
    };
    

    Tailwind CSS Utilities

    // Conditional classes with cn()
    import { cn } from '@/lib/utils';

    TypeScript Patterns

    // Props with children
    interface CardProps {
      className?: string;
      children: React.ReactNode;
    }

    // Generic component interface ListProps { items: T[]; renderItem: (item: T) => React.ReactNode; }

    function List({ items, renderItem }: ListProps) { return

      {items.map(renderItem)}
    ; }


    Resources

  • React Patterns: references/react_patterns.md
  • Next.js Optimization: references/nextjs_optimization_guide.md
  • Best Practices: references/frontend_best_practices.md