Skip to main content
skill Claude Code

senior-frontend — Claude Code skill: what it does, how to install

This skill supports React and Next.js work, from project scaffolding to bundle checks. Use it when building components, reviewing frontend code, or working on accessibility.

Install into Claude Code · Plugin marketplace All methods and platforms ↓
/plugin marketplace add alirezarezvani/claude-skills
/plugin install engineering-skills@claude-code-skills
Open on GitHub

What senior-frontend does

senior-frontend provides workflows for React, Next.js, TypeScript, and Tailwind CSS work. It can scaffold a project with scripts/frontend_scaffolder.py, add selected features, and generate components or hooks through scripts/component_generator.py.

The generator covers client components, server components, and custom hooks. It can also create test files and Storybook stories. Its reference material covers compound components, custom hooks, and render props. For Next.js, the skill advises using Server Components by default and adding use client for event handlers, state, or effects.

scripts/bundle_analyzer.py checks package.json and project structure for bundle issues, flags heavy dependencies, and can inspect import patterns in verbose mode. The scripts run through Python, so checking that prerequisite first matters.

What it helps with

  • scaffold a Next.js project with TypeScript and Tailwind CSS
  • generate a React component with a test and story
  • create a custom React hook
  • identify heavy dependencies in a bundle
  • review frontend code and accessibility

Example prompts for the agent

  • Create a Next.js project named `my-app` with `scripts/frontend_scaffolder.py`.
  • Generate `UserProfile` with a test and Storybook story using `scripts/component_generator.py`.
  • Analyze this project with `python scripts/bundle_analyzer.py . --verbose`.

How to install senior-frontend

1Plugin marketplace

/plugin marketplace add alirezarezvani/claude-skills
/plugin install engineering-skills@claude-code-skills

This installs the whole engineering-skills plugin with all its skills

2Skills CLI (Vercel)

npx skills add alirezarezvani/claude-skills --skill senior-frontend -a claude-code

3Manually: put the files in place

~/.claude/skills/senior-frontend/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/senior-frontend/

From the same set349

The whole set →
engineering-skills Alireza Rezvani An engineering skill index for Claude Code that helps you select one specialist SKILL.md for the task at hand. It covers architecture, testing, DevOps, and data work. Claude Code 2,387installs finance-skills Alireza Rezvani Routes ambiguous finance prompts to the right bundled skill: financial-analyst, saas-metrics-coach, or month-end-close. Claude Code 2,312installs marketing-skills Alireza Rezvani A directory and router for marketing skills in Claude Code. It picks the right specialist skill for SEO, content, CRO, channels, and related tasks. Claude Code 2,264installs business-growth-skills Alireza Rezvani Routes growth and revenue prompts to the right specialized skill across customer success, sales engineering, RevOps, and proposals in Claude Code. Claude Code 2,189installs engineering-advanced-skills Alireza Rezvani An index of 37 engineering skills for architecture, automation, reliability, and platform work. Use it when a project needs task-specific engineering workflows. Claude Code 2,019installs product-skills Alireza Rezvani Product work orchestrator for Claude Code. Routes queries across 16 domain lanes and validates discovery trees with deterministic scripts. Claude Code 1,994installs pm-skills Alireza Rezvani Routes project-delivery requests across 8 PM sub-skills for Jira, Confluence, sprints, reporting, and team communication. Useful for controlled delivery work. Claude Code 1,975installs senior-backend Alireza Rezvani Scaffolds backend APIs, detects database bottlenecks, and runs load tests. Useful when designing Express routes, optimizing PostgreSQL, or preparing for production. Claude Code 1,674installs

Similar

react18-string-refs official github Guides the move from string refs to React.createRef() in class components. Use it when preparing a project for React 18.3.1 or React 19. GitHub Copilot 741installs react18-enzyme-to-rtl official github Provides Enzyme to React Testing Library migration patterns for React 18 upgrades. Useful when rewriting shallow renders, mount calls, and state assertions into user behavior checks. GitHub Copilot 739installs frontend-design official anthropics This skill guides intentional visual design for new interfaces and redesigns. Use it when a generic generated UI is not enough. Claude Code Claude.ai 1,025,790installs design-taste-frontend Leonxlnx This skill directs the design of public pages and work screens, then checks the result in a browser through screenshots. Use it when an interface feels generic or unfinished. Claude Code CX Codex Cursor +1 673,100installs prototype Matt Pocock Creates throwaway prototypes for checking state logic or exploring UI before committing the decision to the main codebase. Claude Code 986,201installs hyperframes heygen-com Instructs coding agents on creating, validating, and rendering HTML-based videos using the HyperFrames framework and CLI. Claude Code CX Codex Cursor +1 1,200,000installs hyperframes-cli heygen-com Controls HyperFrames video workflows from the CLI: audits layouts and contrast, edits timeline clips, captures snapshots, and renders locally or in cloud runtimes. Claude Code CX Codex Cursor +1 1,200,000installs webapp-testing official anthropics This skill tests local web apps with Playwright, helping agents debug UI behavior, capture screenshots, and inspect browser logs. Claude Code Claude.ai 186,758installs

Questions about senior-frontend

How do I install senior-frontend in Claude Code?

Add the marketplace with /plugin marketplace add alirezarezvani/claude-skills, then install the plugin with /plugin install engineering-skills@claude-code-skills.

What does senior-frontend do?

It gives Claude Code workflows for React and Next.js scaffolding, component generation, bundle analysis, and frontend code review.

Does senior-frontend require Python?

Yes. Its project scaffolding, component generation, and bundle analysis scripts run with python.

Source text

SKILL.md · MIT
---
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](#project-scaffolding)
- [Component Generation](#component-generation)
- [Bundle Analysis](#bundle-analysis)
- [React Patterns](#react-patterns)
- [Next.js Optimization](#nextjs-optimization)
- [Accessibility and Testing](#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:
   ```bash
   python scripts/frontend_scaffolder.py my-app --template nextjs
   ```

2. Add optional features (auth, api, forms, testing, storybook):
   ```bash
   python scripts/frontend_scaffolder.py dashboard --template nextjs --features auth,api
   ```

3. Navigate to the project and install dependencies:
   ```bash
   cd my-app && npm install
   ```

4. Start the development server:
   ```bash
   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:
   ```bash
   python scripts/component_generator.py Button --dir src/components/ui
   ```

2. Generate a server component:
   ```bash
   python scripts/component_generator.py ProductCard --type server
   ```

3. Generate with test and story files:
   ```bash
   python scripts/component_generator.py UserProfile --with-test --with-story
   ```

4. Generate a custom hook:
   ```bash
   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

```tsx
'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:
   ```bash
   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:
   ```bash
   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:

```tsx
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:

```tsx
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:

```tsx
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

```tsx
// 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

```tsx
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

```tsx
// 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

```tsx
// 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

```tsx
// 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

```js
// 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

```tsx
// 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

```tsx
// 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:

| Profile | When to pick | LCP target (mobile-4G p75) | Bundle budget |
|---|---|---|---|
| `next-app-router` | SaaS customer-facing, SEO + dynamic, RSC-first | 2000ms | 150 KB-gzip / route |
| `remix-or-sveltekit` | Mobile-4G primary, low-JS-first, progressive enhancement | 1500ms | 80 KB-gzip / route |
| `vite-spa` | Auth-walled app, desktop/corporate primary | 2500ms | 200 KB init + 80 KB / route |
| `astro-or-static` | Marketing / docs / blog, near-zero write, SEO-critical | 1200ms | 30 KB JS / page |

Pick a profile via:

```bash
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:

| Concern | Fork into |
|---|---|
| WCAG audit, contrast, screen-reader | `engineering-team/skills/a11y-audit/` |
| Bundle profiling + runtime perf | `engineering/skills/performance-profiler/` |
| Cinematic / scroll-storytelling landing | `engineering-team/skills/epic-design/` |
| Apple HIG (iOS / macOS / visionOS) | `product-team/skills/apple-hig-expert/` |
| Pre-commit Karpathy review | `engineering/karpathy-coder/` |
| Pre-flight architecture grill | `engineering/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.

© Alireza Rezvani · MIT · alirezarezvani/claude-skills

See also

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor