askill
frontend-react

frontend-reactSafety 100Repository

Modern React stack: React 19, TypeScript, Tailwind CSS, Vite, TanStack Query. Use when: building React apps, components, state management, or UI. Triggers: "react", "frontend", "tailwind", "vite", "typescript react", "component", "useState", "tanstack", "react query".

3 stars
1.2k downloads
Updated 12/10/2025

Package Files

Loading files...
SKILL.md

React Frontend Stack

Live docs: Add use context7 to prompt for up-to-date React, TanStack Query, Tailwind documentation.

Quick Reference

TopicReference
Componentscomponents.md — Button, Input, Modal, patterns
Statestate.md — useState, Zustand, Context, URL state

Tooling (2025)

ToolPurposeWhy
ViteBuild toolFast HMR, ESM native
React 19UI libraryRSC, Actions, use()
TypeScriptType safetyStrict mode
Tailwind v4StylingUtility-first, Vite plugin
TanStack QueryData fetchingCaching, mutations
ZustandStateSimple, no boilerplate
React Router 7RoutingData loading, actions

Notes:

  • Tailwind v4: new config via Vite plugin, no tailwind.config.js
  • TanStack Router may require React 18.3.1 (use --legacy-peer-deps if needed)

Project Setup

pnpm create vite@latest my-app --template react-ts
cd my-app
pnpm add @tanstack/react-query zustand
pnpm add -D tailwindcss @tailwindcss/vite

Vite Config

// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tailwindcss from '@tailwindcss/vite';

export default defineConfig({
  plugins: [react(), tailwindcss()],
  resolve: {
    alias: { '@': '/src' },
  },
});

Tailwind v4

/* src/index.css */
@import "tailwindcss";

Project Structure

src/
├── main.tsx             # Entry point
├── App.tsx              # Root component
├── index.css            # Tailwind imports
├── components/
│   ├── ui/              # Reusable UI (Button, Input, Card)
│   └── features/        # Feature components
├── pages/               # Route components
├── hooks/               # Custom hooks
├── stores/              # Zustand stores
├── api/                 # API client, queries
├── types/               # TypeScript types
└── lib/                 # Utilities

Component Patterns

Functional Component

interface UserCardProps {
  user: User;
  onEdit?: (id: string) => void;
}

export function UserCard({ user, onEdit }: UserCardProps) {
  return (
    <div className="rounded-lg border p-4">
      <h3 className="font-semibold">{user.name}</h3>
      <p className="text-sm text-gray-600">{user.email}</p>
      {onEdit && (
        <button
          onClick={() => onEdit(user.id)}
          className="mt-2 text-blue-600 hover:underline"
        >
          Edit
        </button>
      )}
    </div>
  );
}

Component with Children

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

export function Card({ title, children, className }: CardProps) {
  return (
    <div className={cn("rounded-lg border bg-white p-6", className)}>
      <h2 className="mb-4 text-lg font-semibold">{title}</h2>
      {children}
    </div>
  );
}

Polymorphic Component

type ButtonProps<T extends React.ElementType = 'button'> = {
  as?: T;
  variant?: 'primary' | 'secondary';
  children: React.ReactNode;
} & React.ComponentPropsWithoutRef<T>;

export function Button<T extends React.ElementType = 'button'>({
  as,
  variant = 'primary',
  children,
  className,
  ...props
}: ButtonProps<T>) {
  const Component = as || 'button';
  return (
    <Component
      className={cn(
        'px-4 py-2 rounded-md font-medium',
        variant === 'primary' && 'bg-blue-600 text-white',
        variant === 'secondary' && 'bg-gray-200 text-gray-800',
        className
      )}
      {...props}
    >
      {children}
    </Component>
  );
}

// Usage
<Button>Click me</Button>
<Button as="a" href="/about">Link</Button>

Hooks

Custom Hook Example

function useLocalStorage<T>(key: string, initialValue: T) {
  const [value, setValue] = useState<T>(() => {
    const stored = localStorage.getItem(key);
    return stored ? JSON.parse(stored) : initialValue;
  });

  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);

  return [value, setValue] as const;
}

useDebounce

function useDebounce<T>(value: T, delay: number): T {
  const [debounced, setDebounced] = useState(value);

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

  return debounced;
}

TanStack Query

Setup

// main.tsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 60 * 1000,
      retry: 1,
    },
  },
});

<QueryClientProvider client={queryClient}>
  <App />
</QueryClientProvider>

Query Hook

// api/users.ts
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';

export function useUsers() {
  return useQuery({
    queryKey: ['users'],
    queryFn: () => fetch('/api/users').then(r => r.json()),
  });
}

export function useUser(id: string) {
  return useQuery({
    queryKey: ['users', id],
    queryFn: () => fetch(`/api/users/${id}`).then(r => r.json()),
    enabled: !!id,
  });
}

export function useCreateUser() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (data: CreateUser) =>
      fetch('/api/users', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data),
      }).then(r => r.json()),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['users'] });
    },
  });
}

Usage in Component

function UserList() {
  const { data: users, isLoading, error } = useUsers();
  const createUser = useCreateUser();

  if (isLoading) return <Spinner />;
  if (error) return <Error message={error.message} />;

  return (
    <div>
      {users.map(user => <UserCard key={user.id} user={user} />)}
      <button onClick={() => createUser.mutate({ name: 'New' })}>
        Add User
      </button>
    </div>
  );
}

Zustand State

// stores/auth.ts
import { create } from 'zustand';
import { persist } from 'zustand/middleware';

interface AuthState {
  user: User | null;
  token: string | null;
  login: (user: User, token: string) => void;
  logout: () => void;
}

export const useAuthStore = create<AuthState>()(
  persist(
    (set) => ({
      user: null,
      token: null,
      login: (user, token) => set({ user, token }),
      logout: () => set({ user: null, token: null }),
    }),
    { name: 'auth-storage' }
  )
);

// Usage
const { user, login, logout } = useAuthStore();

Forms

import { useState, FormEvent } from 'react';

function LoginForm() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [errors, setErrors] = useState<Record<string, string>>({});

  const handleSubmit = async (e: FormEvent) => {
    e.preventDefault();
    setErrors({});

    if (!email) {
      setErrors(prev => ({ ...prev, email: 'Required' }));
      return;
    }

    // Submit...
  };

  return (
    <form onSubmit={handleSubmit} className="space-y-4">
      <div>
        <input
          type="email"
          value={email}
          onChange={e => setEmail(e.target.value)}
          className="w-full rounded border px-3 py-2"
          placeholder="Email"
        />
        {errors.email && <p className="text-sm text-red-500">{errors.email}</p>}
      </div>
      <button type="submit" className="w-full rounded bg-blue-600 py-2 text-white">
        Login
      </button>
    </form>
  );
}

Anti-patterns

Don'tDo Instead
CRA (Create React App)Vite
CSS Modules / styled-componentsTailwind
Redux (complex)Zustand (simple)
useEffect for data fetchingTanStack Query
Prop drillingContext or Zustand
any typesProper TypeScript types
Index as keyUnique ID as key
Inline object propsuseMemo or extract

Install

Download ZIP
Requires askill CLI v1.0+

AI Quality Score

82/100Analyzed 2/23/2026

Comprehensive React frontend skill with excellent code examples, setup instructions, and modern tooling references. Well-structured with clear sections covering components, hooks, state management, and TanStack Query. Includes practical anti-patterns guide. Slightly incomplete on testing and routing details. Tags are somewhat mismatched but content quality is high.

100
82
88
72
85

Metadata

Licenseunknown
Version-
Updated12/10/2025
Publishertimequity

Tags

apici-cdpromptingsecurity