Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

04 Frontend Integration

ASecurity

Skill do Frontend Developer para implementação com React/Next.js, Zustand, React Query, e Skeleton loading. Use quando precisar implementar componentes, páginas, integração com API, gerenciamento de estado, ou qualquer código frontend. Trigger em: "React", "Next.js", "componente", "página", "Zustand", "React Query", "TanStack Query", "skeleton", "loading", "hook", "frontend", "integração", "mobile responsive", "Tailwind", "formulário", "roteamento".

23 stars
0 votes
0 copies
0 views
Added 9/20/2026
developmenttypescriptgobashreactangularnextjsnodegitapifrontend

Works with

cliapimcp

Security Analysis

A100/100

Scanned 9/20/2026

Install to Claude Code

$npx -y skills add felvieira/claude-skills-fv --skill 04-frontend-integration --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 04 Frontend Integration?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for 04 Frontend Integration
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/felvieira-04-frontend-integration/badge)](https://www.skillsdirectory.com/skills/felvieira-04-frontend-integration)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: frontend-integration
description: |
  Skill do Frontend Developer para implementação com React/Next.js, Zustand, React Query, e Skeleton loading.
  Use quando precisar implementar componentes, páginas, integração com API, gerenciamento de estado, ou
  qualquer código frontend. Trigger em: "React", "Next.js", "componente", "página", "Zustand", "React Query",
  "TanStack Query", "skeleton", "loading", "hook", "frontend", "integração", "mobile responsive", "Tailwind",
  "formulário", "roteamento".
---

# Frontend Developer - React/Next.js + Zustand + React Query

O Frontend transforma design em codigo, integrando com a API e garantindo UX fluida.

## Governanca Global

Esta skill segue `GLOBAL.md`, `policies/execution.md`, `policies/handoffs.md`, `policies/quality-gates.md`, `policies/token-efficiency.md`, `policies/stack-flexibility.md`, `policies/tool-safety.md` e `policies/evals.md`.

Para snippets extensos e exemplos completos, consultar `docs/skill-guides/frontend-integration.md` apenas quando a tarefa exigir.

Para integracoes locais de MCP com bibliotecas visuais, consultar `docs/skill-guides/ui-component-mcps.md`.

Quando a tarefa exigir navegacao real, screenshots ou verificacao visual do app rodando, esta skill pode configurar ou reutilizar `Playwright MCP` localmente.

## Quando Usar

- implementar tela, componente, estado ou integracao com API
- fechar comportamento de loading, erro, vazio e refresh

## Quando Nao Usar

- para definir regras de negocio sem apoio do Backend ou PO
- para motion, SEO ou review final como atividade principal

## Entradas Esperadas

- spec do PO e direcao de UI/UX
- contrato de API
- restricoes de estado, auth e navegacao

## Saidas Esperadas

- interface funcional integrada
- estados de UX tratados
- handoff claro para QA

Para auth, o access token fica apenas em memoria. Persistencia local fica reservada a preferencias nao sensiveis, nunca a tokens.

## Responsabilidades

1. Implementar interfaces conforme spec do UI/UX
2. Integrar com APIs usando React Query
3. Gerenciar estado global com Zustand
4. Implementar skeleton loading em toda tela com fetch
5. Garantir responsividade mobile-first
6. Código limpo, DRY, e tipado

## Stack e Estrutura

Stack de referencia:

- React ou Next.js
- Zustand para estado global quando necessario
- React Query para server state
- Axios ou cliente HTTP equivalente
- TypeScript strict mode

Para estrutura de pastas e exemplos completos de store, auth e API client, consultar `docs/skill-guides/frontend-integration.md`.

## Padroes Principais

- estado global pequeno e focado em UI ou sessao
- `accessToken` apenas em memoria
- server state separado do estado local
- estados de loading, erro, vazio e retry definidos por tela

## Storage Client-Side Reativo

Para persistir preferencia de UI, filtro de tela ou qualquer estado nao sensivel que precisa sobreviver a reload ou sincronizar entre abas, o default e o middleware `persist` do Zustand (`zustand/middleware`) quando o projeto ja usa Zustand para esse estado — nao adicionar dependencia nova so pra isso.

`brownies` (https://github.com/franciscop/brownies, MIT, npm `brownies`) e uma opcao pontual quando **nao** ha Zustand no caminho: cookie/local/session/db com interface unificada de getter/setter direto (nao `.get()`/`.set()`) e sincronizacao entre abas via `subscribe()`.

```js
import { cookies, local, session, db, subscribe, unsubscribe } from 'brownies';

local.token = 42;        // set
const t = local.token;   // get (sincrono para cookies/local/session)
delete local.token;      // remove

// db (IndexedDB) e assincrono
db.token = 42;
const dbVal = await db.token;

// subscribe reage a mudanca feita em outra aba ou via API nativa
const id = subscribe(local, 'points', (value) => setPoints(value));
unsubscribe(id); // ou unsubscribe(callback)
```

Quando usar: state simples fora de um store existente — ex. tela isolada sem Zustand, ou precisa de `cookies`/`session`/`db` (IndexedDB) alem de `localStorage`, o que `persist` do Zustand nao cobre nativamente.

Quando nao usar: projeto ja tem Zustand no estado que precisa persistir — nesse caso `persist` resolve sem dependencia nova. Tambem nao usar para dado sensivel (token, PII) — regra desta skill de token apenas em memoria continua valendo, `brownies` nao muda isso.

Gap de baixa prioridade: e o caso mais "commodity" entre as libs avaliadas para esta skill — a maior parte dos projetos ja resolve isso com `persist`, entao tratar como nota, nao como recomendacao forte.

## MCPs de Componentes

Esta skill pode instalar ou configurar localmente MCPs de bibliotecas como `Magic UI MCP` e `React Bits MCP` quando isso acelerar a implementacao e o projeto nao tiver equivalente melhor.

Regras:

- verificar se o MCP ja existe antes de configurar outro
- adaptar componentes ao design system do app
- nao introduzir visual ou motion que destoem do produto
- registrar a instalacao/configuracao local no handoff quando houver mudanca no workspace

## Biblioteca de Componentes para Apps Document-Heavy

Quando a feature envolve visualizar ou manipular documentos dentro do app (PDF, DOCX, XLSX, CSV, upload com preview, citação com bounding box sobre o documento, e-signing, schema builder), considerar `extend-hq/ui` (https://github.com/extend-hq/ui, MIT) em vez de construir viewer do zero ou improvisar com libs genéricas.

Componentes principais do kit: PDF viewer (baseado em `react-pdf`), DOCX viewer, XLSX viewer, file upload, file thumbnail, e-signature, layout blocks (inspeção de OCR com confidence score), bounding box citations (citação campo a campo com diff em JSON), file system/finder (visões ícone, lista, coluna, galeria).

Stack esperada: React + TypeScript, Tailwind CSS, primitivas shadcn/ui (`Button`, `Select`, `Dialog`, `ScrollArea`, `Tooltip` precisam existir no projeto). Next.js não é obrigatório para os componentes em si — é usado no site de docs do projeto original. Instalação é via shadcn CLI, componente por componente, como código-fonte copiado para o projeto (não é dependência de pacote fechada):

```bash
npx shadcn@latest add @extend/pdf-viewer
```

Quando usar: o produto já tem (ou vai ter) fluxo de revisão/anotação de documentos — contratos, notas fiscais, planilhas importadas, formulários assinados — e precisa de viewer com citação/bounding box ou e-signing nativo.

Quando não usar: telas sem documento nenhum (CRUD comum, dashboards, formulários simples) — nesse caso os componentes de `MCPs de Componentes` acima (Magic UI, React Bits) resolvem melhor. Também não usar se o projeto não tiver shadcn/ui configurado e não quiser adotar — nesse caso o custo de introduzir a dependência de primitivas supera o ganho.

## MCP de Browser

Para validacao visual real, esta skill pode usar `Playwright MCP` para:

- abrir o app localmente
- navegar por telas e fluxos
- verificar comportamento responsivo
- capturar screenshots para confirmar detalhes de UI

Usar especialmente quando a mudanca visual nao puder ser validada com confianca apenas por leitura de codigo.

Para exemplos completos de store, authStore, uiStore e api client, consultar `docs/skill-guides/frontend-integration.md`.

## React Query - Padrão de Hooks

**src/lib/query-keys.ts**

```typescript
export const queryKeys = {
  users: {
    all: ['users'] as const,
    lists: () => [...queryKeys.users.all, 'list'] as const,
    list: (params: Record<string, unknown>) => [...queryKeys.users.lists(), params] as const,
    details: () => [...queryKeys.users.all, 'detail'] as const,
    detail: (id: string) => [...queryKeys.users.details(), id] as const,
  },
  posts: {
    all: ['posts'] as const,
    lists: () => [...queryKeys.posts.all, 'list'] as const,
    list: (params: Record<string, unknown>) => [...queryKeys.posts.lists(), params] as const,
    details: () => [...queryKeys.posts.all, 'detail'] as const,
    detail: (id: string) => [...queryKeys.posts.details(), id] as const,
  },
} as const;
```

**src/hooks/useApi.ts**

```typescript
import { useQuery, useMutation, useQueryClient, UseQueryOptions } from '@tanstack/react-query';
import { api } from '@/lib/api-client';
import type { ApiResponse, PaginatedResponse } from '@/types/api';

export function usePaginatedQuery<T>(
  queryKey: readonly unknown[],
  url: string,
  params?: Record<string, unknown>,
  options?: Omit<UseQueryOptions, 'queryKey' | 'queryFn'>
) {
  return useQuery({
    queryKey: [...queryKey, params],
    queryFn: async () => {
      const { data } = await api.get<PaginatedResponse<T>>(url, { params });
      return data;
    },
    placeholderData: (prev) => prev,
    ...options,
  });
}

export function useDetailQuery<T>(
  queryKey: readonly unknown[],
  url: string,
  options?: Omit<UseQueryOptions, 'queryKey' | 'queryFn'>
) {
  return useQuery({
    queryKey,
    queryFn: async () => {
      const { data } = await api.get<ApiResponse<T>>(url);
      return data.data;
    },
    ...options,
  });
}

export function useApiMutation<TInput, TOutput = unknown>(
  method: 'post' | 'patch' | 'delete',
  url: string | ((variables: TInput) => string),
  options?: {
    invalidateKeys?: readonly unknown[][];
    onSuccess?: (data: TOutput) => void;
    optimistic?: {
      queryKey: readonly unknown[];
      updater: (old: any, variables: TInput) => any;
    };
  }
) {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (variables: TInput) => {
      const endpoint = typeof url === 'function' ? url(variables) : url;
      const { data } = await api[method]<ApiResponse<TOutput>>(endpoint, variables);
      return data.data;
    },

    onMutate: options?.optimistic
      ? async (variables) => {
          await queryClient.cancelQueries({ queryKey: options.optimistic!.queryKey });
          const previous = queryClient.getQueryData(options.optimistic!.queryKey);
          queryClient.setQueryData(
            options.optimistic!.queryKey,
            (old: any) => options.optimistic!.updater(old, variables)
          );
          return { previous };
        }
      : undefined,

    onError: options?.optimistic
      ? (err, variables, context: any) => {
          queryClient.setQueryData(options.optimistic!.queryKey, context?.previous);
        }
      : undefined,

    onSuccess: (data) => {
      options?.invalidateKeys?.forEach((key) => {
        queryClient.invalidateQueries({ queryKey: key });
      });
      options?.onSuccess?.(data);
    },
  });
}
```

**Checkpoint antes de considerar a integração pronta:** para toda mutation com `optimistic`, forçar o backend a retornar erro (mockar 500, ou desligar o endpoint temporariamente) e confirmar que a UI reverte pro estado anterior — não só que o optimistic update aparece no caminho feliz. Se o rollback não reverter visualmente, o `previous` capturado em `onMutate` está errado (query key diferente da que o `updater` mexeu) — corrigir a query key e repetir o teste de erro forçado antes de seguir.

## Skeleton Loading - Implementação

**src/components/ui/Skeleton.tsx**

```typescript
import { cn } from '@/lib/utils';

interface SkeletonProps {
  className?: string;
  variant?: 'text' | 'circular' | 'rectangular';
  width?: string | number;
  height?: string | number;
  lines?: number;
}

export function Skeleton({ className, variant = 'text', width, height, lines = 1 }: SkeletonProps) {
  const baseClass = 'animate-pulse bg-gray-200 rounded';

  if (variant === 'circular') {
    return (
      <div
        className={cn(baseClass, 'rounded-full', className)}
        style={{ width: width || 40, height: height || 40 }}
      />
    );
  }

  if (variant === 'rectangular') {
    return (
      <div
        className={cn(baseClass, className)}
        style={{ width: width || '100%', height: height || 200 }}
      />
    );
  }

  return (
    <div className="space-y-2">
      {Array.from({ length: lines }).map((_, i) => (
        <div
          key={i}
          className={cn(baseClass, 'h-4', className)}
          style={{
            width: i === lines - 1 ? '60%' : i % 2 === 0 ? '100%' : '80%',
          }}
        />
      ))}
    </div>
  );
}

export function withSkeleton<T>(
  Component: React.ComponentType<T>,
  SkeletonComponent: React.ComponentType
) {
  return function SkeletonWrapper({ isLoading, ...props }: T & { isLoading: boolean }) {
    if (isLoading) return <SkeletonComponent />;
    return <Component {...(props as T)} />;
  };
}
```

**src/components/skeletons/UserListSkeleton.tsx**

```typescript
import { Skeleton } from '@/components/ui/Skeleton';

export function UserListSkeleton({ count = 5 }: { count?: number }) {
  return (
    <div className="space-y-4">
      {Array.from({ length: count }).map((_, i) => (
        <div key={i} className="flex items-center gap-4 p-4 border rounded-lg">
          <Skeleton variant="circular" width={48} height={48} />
          <div className="flex-1 space-y-2">
            <Skeleton className="h-4 w-1/3" />
            <Skeleton className="h-3 w-1/2" />
          </div>
          <Skeleton className="h-8 w-20" variant="rectangular" />
        </div>
      ))}
    </div>
  );
}
```

## API Client - Axios com Interceptors

**src/lib/api-client.ts**

```typescript
import axios from 'axios';
import { useAuthStore } from '@/stores/authStore';

export const api = axios.create({
  baseURL: process.env.NEXT_PUBLIC_API_URL,
  timeout: 10000,
  withCredentials: true,
  headers: { 'Content-Type': 'application/json' },
});

api.interceptors.request.use((config) => {
  const token = useAuthStore.getState().accessToken;
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }

  const csrfToken = getCookie('csrf-token');
  if (csrfToken) {
    config.headers['X-CSRF-Token'] = csrfToken;
  }

  return config;
});

let isRefreshing = false;
let failedQueue: Array<{ resolve: Function; reject: Function }> = [];

const processQueue = (error: any, token: string | null) => {
  failedQueue.forEach((prom) => {
    if (error) prom.reject(error);
    else prom.resolve(token);
  });
  failedQueue = [];
};

api.interceptors.response.use(
  (response) => response,
  async (error) => {
    const originalRequest = error.config;
    
    if (error.response?.status === 401 && !originalRequest._retry) {
      if (isRefreshing) {
        return new Promise((resolve, reject) => {
          failedQueue.push({ resolve, reject });
        }).then((token) => {
          originalRequest.headers.Authorization = `Bearer ${token}`;
          return api(originalRequest);
        });
      }
      
      originalRequest._retry = true;
      isRefreshing = true;
      
      try {
        const { data } = await axios.post(
          `${process.env.NEXT_PUBLIC_API_URL}/auth/refresh`,
          {},
          { withCredentials: true }
        );
        
        const { accessToken, user } = data.data;
        useAuthStore.getState().setAuth(user, accessToken);
        
        processQueue(null, accessToken);
        originalRequest.headers.Authorization = `Bearer ${accessToken}`;
        return api(originalRequest);
      } catch (refreshError) {
        processQueue(refreshError, null);
        useAuthStore.getState().clearAuth();
        if (typeof window !== 'undefined') window.location.href = '/login';
        return Promise.reject(refreshError);
      } finally {
        isRefreshing = false;
      }
    }
    
    return Promise.reject(error);
  }
);

function getCookie(name: string): string | null {
  if (typeof document === 'undefined') return null;
  const match = document.cookie.match(new RegExp(`(^| )${name}=([^;]+)`));
  return match ? match[2] : null;
}
```

## Providers Setup

**src/app/providers.tsx**

```typescript
'use client';

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { useState, type ReactNode } from 'react';

export function Providers({ children }: { children: ReactNode }) {
  const [queryClient] = useState(
    () =>
      new QueryClient({
        defaultOptions: {
          queries: {
            staleTime: 60 * 1000,
            gcTime: 5 * 60 * 1000,
            retry: 1,
            refetchOnWindowFocus: false,
          },
          mutations: {
            retry: 0,
          },
        },
      })
  );
  
  return (
    <QueryClientProvider client={queryClient}>
      {children}
      {process.env.NODE_ENV === 'development' && <ReactQueryDevtools />}
    </QueryClientProvider>
  );
}
```

## Exemplo Completo - Listagem com Skeleton

**src/app/(dashboard)/users/page.tsx**

```typescript
'use client';

import { useState } from 'react';
import { usePaginatedQuery } from '@/hooks/useApi';
import { queryKeys } from '@/lib/query-keys';
import { UserListSkeleton } from '@/components/skeletons/UserListSkeleton';
import { UserCard } from '@/components/features/UserCard';
import { Pagination } from '@/components/ui/Pagination';
import { SearchInput } from '@/components/ui/SearchInput';
import { useDebounce } from '@/hooks/useDebounce';
import type { User } from '@/types/user';

export default function UsersPage() {
  const [page, setPage] = useState(1);
  const [search, setSearch] = useState('');
  const debouncedSearch = useDebounce(search, 300);
  
  const params = { page, perPage: 20, search: debouncedSearch };
  
  const { data, isLoading, isError, error } = usePaginatedQuery<User>(
    queryKeys.users.list(params),
    '/api/v1/users',
    params
  );
  
  return (
    <div className="space-y-6">
      <div className="flex flex-col sm:flex-row justify-between gap-4">
        <h1 className="text-2xl font-bold">Usuários</h1>
        <SearchInput
          value={search}
          onChange={setSearch}
          placeholder="Buscar usuários..."
        />
      </div>
      
      {isLoading ? (
        <UserListSkeleton count={5} />
      ) : isError ? (
        <ErrorState message={error.message} onRetry={() => {}} />
      ) : data?.data.length === 0 ? (
        <EmptyState message="Nenhum usuário encontrado" />
      ) : (
        <>
          <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
            {data?.data.map((user) => (
              <UserCard key={user.id} user={user} />
            ))}
          </div>
          {data?.meta && (
            <Pagination
              page={data.meta.page}
              totalPages={data.meta.totalPages}
              onPageChange={setPage}
            />
          )}
        </>
      )}
    </div>
  );
}
```

### Error States Robustos

Toda tela que faz fetch DEVE ter estes estados:
- Loading (skeleton)
- Sucesso (dados)
- Erro (mensagem + botao retry)
- Vazio (empty state com acao)
- Timeout (mensagem especifica + retry)
- Offline (detectar navigator.onLine)
- Dados stale (indicador visual quando cache expirou)

Retry pattern no useApi:
```typescript
const RETRY_CONFIG = {
  retries: 3,
  retryDelay: (attempt: number) => Math.min(1000 * 2 ** attempt, 10000),
};
```

## Quando precisar de imagem (placeholder, avatar default, hero, ilustração)

Não use unsplash/lorem-picsum em prod. **Despache skill 17 (`image-generator`)** pra gerar asset alinhado ao projeto:

```
Tipo: placeholder | avatar-default | hero | illustration
Contexto: [componente onde entra], [paleta do app]
Output path: public/images/ ou assets/
Restrições: [dimensão], [transparência se PNG], [formato preferido]
```

Skill 17 aplica regra default (grok-imagine $0.020 t2i / gemini-25-flash $0.039 edit). Em runtime do app (não em build): usar `templates/stack-default/apps/web/src/lib/image.ts` se template está sendo consumido.

## Evidencia de Conclusao

- interface implementada conforme fluxo esperado
- loading, erro, vazio e auth tratados
- pontos criticos para QA e Motion destacados

## Handoff para QA

Entregar:
1. App rodando em ambiente de staging
2. Lista de features implementadas com rotas
3. Componentes interativos documentados (Storybook se houver)
4. Variáveis de ambiente documentadas
5. Como rodar localmente (README)

## Fontes

- Seção "Biblioteca de Componentes para Apps Document-Heavy" curada a partir de [extend-hq/ui](https://github.com/extend-hq/ui) (MIT, ~1.5k stars) — não é port literal do README, é resumo dos componentes e do modo de instalação relevantes para esta skill. Confirmado por leitura direta do repo (licença, stack, comando de instalação) e da página https://www.extend.ai/ui. O kit já modelava Extend como referência visual em `skills/02-ui-ux-design/data/products.csv` e `ui-reasoning.csv`, mas não tinha nenhuma menção à biblioteca de componentes React em si — esse era o gap real medido antes de adicionar esta seção.
- Seção "Storage Client-Side Reativo" curada a partir de [franciscop/brownies](https://github.com/franciscop/brownies) (MIT, 2.566 stars, 61 forks, release 4.0.1). API confirmada por leitura direta de `readme.md` e `package.json` do repo: getter/setter direto em `cookies`/`local`/`session`/`db` (não `.get()`/`.set()`), `db` assíncrono, `subscribe(obj, key, cb)`/`unsubscribe()` para reagir a mudanças entre abas. Gap medido: grep por `localStorage|sessionStorage|indexedDB|subscribe()` em skill 04 e `patterns/` não retornava nada — a skill cobria Zustand/React Query para estado de app, mas não tinha padrão para storage local reativo. Tratado como nota de baixa prioridade: o middleware `persist` do Zustand já cobre a maior parte desse caso quando o projeto já usa Zustand.

## Integração com Pipeline

- **Orquestrador (skill 09):** Coordena quando esta skill é invocada e define a próxima etapa
- **Context Manager (skill 08):** Rastreia progresso das tasks dentro desta skill
- **Documentador (skill 10):** Documenta entregas desta skill durante o desenvolvimento

Attribution

felvieirafelvieira
View sourceMore from felvieira →
SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

281612 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2132 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

9881 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →