New to Claude Skills? Learn how to install them →

Salirezarezvani on GitHub

Senior Frontend

Free

Enhance your React and Next.js development workflow.

Get this skill

Free · Opens the source repo

What Senior Frontend does

The Senior Frontend skill provides a comprehensive set of tools and best practices for developers working with React, Next.js, TypeScript, and Tailwind CSS. This skill is designed to streamline the frontend development process by automating common tasks, optimizing application performance, and ensuring code quality. It includes functionalities for project scaffolding, component generation, bundle analysis, and more, making it an essential resource for modern web developers.

With the project scaffolding feature, users can quickly create new React or Next.js applications with best practice configurations, including TypeScript and Tailwind CSS. This allows developers to focus on building features rather than setting up the project structure. The component generation tool further accelerates development by enabling the creation of reusable React components along with their corresponding tests and Storybook stories, ensuring consistency and quality across the application.

The bundle analysis tool helps identify optimization opportunities within the application. By analyzing the project structure and dependencies, it provides insights into heavy packages and suggests alternatives to reduce bundle size, thus improving performance. Additionally, the skill includes references to common React patterns and best practices, aiding developers in implementing effective solutions in their applications.

Overall, the Senior Frontend skill is targeted at frontend developers looking to enhance their productivity and code quality while working with React and Next.js frameworks. Whether you're starting a new project or optimizing an existing one, this skill offers valuable tools and references to support your development efforts.

When to use it

Use this skill when starting new React or Next.js projects or when optimizing existing applications.

When not to use it

This skill may not be suitable for developers working with frameworks outside of React or Next.js, or those who do not require automation in their workflow.

What you can build with it

Starting a New Project

Quickly scaffold a new Next.js application with TypeScript and Tailwind CSS using the frontend scaffolder.

Creating Reusable Components

Generate new React components complete with tests and Storybook stories to ensure quality and reusability.

Optimizing Bundle Size

Run the bundle analyzer to identify heavy dependencies and receive recommendations for reducing bundle size.

How to install Senior Frontend

View source

1. Install with the skills CLI

npx skills add alirezarezvani/claude-skills/senior-frontend --agent claude-code

2. Or install it manually

Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.

Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs

Inside SKILL.md

Written by alirezarezvani

Senior Frontend

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

Table of Contents


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

OptionDescription
--template nextjsNext.js 14+ with App Router and Server Components
--template reactReact + Vite with TypeScript
--features authAdd NextAuth.js authentication
--features apiAdd React Query + API client
--features formsAdd React Hook Form + Zod validation
--features testingAdd Vitest + Testing Library
--dry-runPreview 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

OptionDescription
--type clientClient component with 'use client' (default)
--type serverAsync server component
--type hookCustom React hook
--with-testInclude test file
--with-storyInclude Storybook story
--flatCreate in output dir without subdirectory
--dry-runPreview 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 (
    <div className={cn('', className)}>
      {children}
    </div>
  );
}

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

ScoreGradeAction
90-100ABundle is well-optimized
80-89BMinor optimizations available
70-79CReplace heavy dependencies
60-69DMultiple issues need attention
0-59FCritical bundle size problems

Heavy Dependencies Detected

The analyzer identifies these common heavy packages:

PackageSizeAlternative
moment290KBdate-fns (12KB) or dayjs (2KB)
lodash71KBlodash-es with tree-shaking
axios14KBNative fetch or ky (3KB)
jquery87KBNative DOM APIs
@mui/materialLargeshadcn/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 (
    <TabsContext.Provider value={{ active, setActive }}>
      {children}
    </TabsContext.Provider>
  );
};

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

// Usage
<Tabs>
  <Tabs.List>
    <Tabs.Tab>One</Tabs.Tab>
    <Tabs.Tab>Two</Tabs.Tab>
  </Tabs.List>
  <Tabs.Panel>Content 1</Tabs.Panel>
  <Tabs.Panel>Content 2</Tabs.Panel>
</Tabs>

Custom Hooks

Extract reusable logic:

function useDebounce<T>(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
<DataFetcher
  url="/api/users"
  render={({ data, loading }) =>
    loading ? <Spinner /> : <UserList users={data} />
  }
/>

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 (
    <div>
      <h1>{product.name}</h1>
      <AddToCartButton productId={product.id} />  {/* Client component */}
    </div>
  );
}

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

Image Optimization

import Image from 'next/image';

// Above the fold - load immediately
<Image
  src="/hero.jpg"
  alt="Hero"
  width={1200}
  height={600}
  priority
/>

// Responsive image with fill
<div className="relative aspect-video">
  <Image
    src="/product.jpg"
    alt="Product"
    fill
    sizes="(max-width: 768px) 100vw, 50vw"
    className="object-cover"
  />
</div>

Data Fetching Patterns

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

// Streaming with Suspense
async function ProductPage({ params }) {
  return (
    <div>
      <ProductDetails id={params.id} />
      <Suspense fallback={<ReviewsSkeleton />}>
        <Reviews productId={params.id} />
      </Suspense>
    </div>
  );
}

Accessibility and Testing

Reference: references/frontend_best_practices.md

Accessibility Checklist

  1. Semantic HTML: Use proper elements (<button>, <nav>, <main>)
  2. Keyboard Navigation: All interactive elements focusable
  3. ARIA Labels: Provide labels for icons and complex widgets
  4. Color Contrast: Minimum 4.5:1 for normal text
  5. Focus Indicators: Visible focus states
// Accessible button
<button
  type="button"
  aria-label="Close dialog"
  onClick={onClose}
  className="focus-visible:ring-2 focus-visible:ring-blue-500"
>
  <XIcon aria-hidden="true" />
</button>

// Skip link for keyboard users
<a href="#main-content" className="sr-only focus:not-sr-only">
  Skip to main content
</a>

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(<Button onClick={onClick}>Click me</Button>);

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

// Test accessibility
test('dialog is accessible', async () => {
  render(<Dialog open={true} title="Confirm" />);

  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: [{ protocol: 'https', hostname: 'cdn.example.com' }],
    formats: ['image/avif', 'image/webp'],
  },
  experimental: {
    optimizePackageImports: ['lucide-react', '@heroicons/react'],
  },
};

Tailwind CSS Utilities

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

<button className={cn(
  'px-4 py-2 rounded',
  variant === 'primary' && 'bg-blue-500 text-white',
  disabled && 'opacity-50 cursor-not-allowed'
)} />

TypeScript Patterns

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

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

function List<T>({ items, renderItem }: ListProps<T>) {
  return <ul>{items.map(renderItem)}</ul>;
}

Resources

  • React Patterns: references/react_patterns.md
  • Next.js Optimization: references/nextjs_optimization_guide.md
  • Best Practices: references/frontend_best_practices.md
  • Forcing-question library (Matt Pocock grill): references/forcing_questions.md
  • Composition map (which specialist to fork into): references/composition_map.md

Assumptions and Verifiable Success Criteria (Karpathy discipline)

Before this skill scaffolds a component, recommends a framework, or audits a bundle, the following four assumptions MUST be surfaced.

  1. Primary user device + network — mobile-4G, desktop-fiber, low-end-Android, or corporate-network. Drives every perf decision.
  2. LCP target in milliseconds — a single number, not "fast." Drives bundle budget and rendering choice.
  3. SEO-dependent vs. auth-walled — drives rendering (SSR/SSG/RSC vs. SPA).
  4. WCAG target + named a11y owner — AA, AAA, or best-effort. Drives a11y investment and CI gates.

Verifiable success criteria (Karpathy #4) — every recommendation must include:

  • Core Web Vitals targets (LCP, INP, CLS) at p75 on the primary device
  • A per-route JS bundle budget in KB-gzip
  • A Lighthouse a11y floor + perf floor

If any of those three is not stated, the recommendation is incomplete — return to Q2 of the forcing-question library.

The scripts/frontend_decision_engine.py tool encodes these checks: it refuses to recommend a profile without the four assumption inputs and prints the verifiable thresholds for the matched profile.


Customization profiles

Four built-in profiles in profiles/ calibrate every recommendation:

ProfileWhen to pickLCP target (mobile-4G p75)Bundle budget
next-app-routerSaaS customer-facing, SEO + dynamic, RSC-first2000ms150 KB-gzip / route
remix-or-sveltekitMobile-4G primary, low-JS-first, progressive enhancement1500ms80 KB-gzip / route
vite-spaAuth-walled app, desktop/corporate primary2500ms200 KB init + 80 KB / route
astro-or-staticMarketing / docs / blog, near-zero write, SEO-critical1200ms30 KB JS / page

Pick a profile via:

python scripts/frontend_decision_engine.py \
  --primary-device mobile-4g --lcp-target-ms 2000 \
  --seo-dependent true --auth-walled false --team-size 5

The tool returns the best-fit profile, the runner-up tradeoff (if within 15%), the stack picks, the anti-patterns to avoid on that profile, and the required CI gates.

To add a custom profile (e.g., your org's internal-tool defaults): copy profiles/vite-spa.json to profiles/<your-org>.json and adjust constraints + success_thresholds.


Composition map

This skill does NOT reimplement scope owned by the POWERFUL-tier specialists. It forks into them. See references/composition_map.md for the full routing table. Key forks:

ConcernFork into
WCAG audit, contrast, screen-readerengineering-team/skills/a11y-audit/
Bundle profiling + runtime perfengineering/skills/performance-profiler/
Cinematic / scroll-storytelling landingengineering-team/skills/epic-design/
Apple HIG (iOS / macOS / visionOS)product-team/skills/apple-hig-expert/
Pre-commit Karpathy reviewengineering/karpathy-coder/
Pre-flight architecture grillengineering/grill-me/

The cs-frontend-engineer agent orchestrates these forks via context: fork. Invoke it from another agent with Agent({subagent_type: "cs-frontend-engineer", prompt: "..."}) or via /cs:frontend-review <your problem>.


Forcing-question library (Matt Pocock grill)

Before locking any framework or rendering decision, walk the seven forcing questions in references/forcing_questions.md. Discipline:

  1. One question per turn. No bundling.
  2. Always recommend the answer with cited canon.
  3. Track answers in /tmp/frontend-grill-<date>.md.
  4. If a kill criterion trips, stop. Don't scaffold around an unresolved gap.
  5. After Q7, run frontend_decision_engine.py with the seven answers.

Summary:

  1. Primary device + network?
  2. LCP target in ms (and INP, CLS)?
  3. RSC / SPA / SSR / SSG — pick and defend?
  4. JS bundle budget per route?
  5. SEO-dependent or auth-walled?
  6. Design-system source of truth?
  7. WCAG target + named a11y owner?

Invocation from other agents and skills

Three surfaces:

  1. Slash command: /cs:frontend-review <prompt> — full grill + decision engine + composition routing.
  2. Agent subagent: Agent({subagent_type: "cs-frontend-engineer", prompt: "..."}) — forks context, returns ≤ 200-word digest.
  3. Direct tool call: python scripts/frontend_decision_engine.py ... — deterministic profile match when inputs are known.

See agents/engineering/cs-frontend-engineer.md for the full invocation contract.

Frequently asked questions about Senior Frontend

Similar skills