Frontend Conventions Skill
Trigger
Use this skill when:
- Adding or modifying React/TypeScript frontend code
- Creating new pages, features, entities, or shared components
- Changing API client calls or data fetching patterns
Rules
Feature-Sliced Design
Place code at the lowest appropriate layer:
| Layer |
Path |
Purpose |
| Pages |
web/src/pages/ |
Route-level page components |
| Features |
web/src/features/ |
Business features (search, upload, review, etc.) |
| Entities |
web/src/entities/ |
Domain entity display logic (skill, user, namespace) |
| Shared |
web/src/shared/ |
Reusable UI components, hooks, utilities |
Current features:
admin — Admin panel (user management, labels, search)
auth — Login, OAuth flows, device auth
governance — Skill governance actions (hide, yank, archive)
namespace — Namespace management (members, settings)
notification — User notifications and inbox
promotion — Skill promotion between scopes
publish — Skill upload/publish UI
report — Skill reporting
review — Review workflow UI
search — Skill search and filtering
security-audit — Security audit viewer
skill — Skill detail, listing, cards
social — Stars, ratings, subscriptions
token — API token management
Data Fetching
- Always use TanStack Query (
@tanstack/react-query) for server state.
- Never use
useEffect for data fetching.
- Use
openapi-fetch client with generated types from web/src/api/generated/schema.d.ts.
- Never use
any types.
State Management
- TanStack Query for server state (API data, caching, invalidation, optimistic updates)
- Zustand for local/UI state (theme, sidebar, modals, form state)
Component Composition
- Radix UI primitives:
@radix-ui/react-dropdown-menu, @radix-ui/react-select
- class-variance-authority (cva) for component variants
- clsx + tailwind-merge for class merging
cn() utility: web/src/shared/lib/utils.ts
- shadcn/ui is NOT used as a library
API Type Generation
When backend OpenAPI contracts change:
make generate-api
This runs openapi-typescript http://localhost:8080/v3/api-docs -o src/api/generated/schema.d.ts.
Commit the updated web/src/api/generated/schema.d.ts with the PR.
To verify the generated file is not stale:
./scripts/check-openapi-generated.sh
Styling
- Tailwind CSS for all styling
cn() utility for conditional class merging
- Follow existing component patterns in
web/src/shared/components/
Internationalization
- i18next + react-i18next for translations
- All user-facing text must be translatable
- Translation keys in
web/src/i18n/
Build & Development
make dev-web # Start Vite dev server (HMR enabled)
make build-frontend # Production build
make typecheck-web # TypeScript type check (tsc --noEmit)
make lint-web # ESLint check
make test-frontend # Vitest unit tests
make test-e2e-frontend # Playwright E2E tests
make test-e2e-smoke-frontend # Playwright smoke tests
Vite HMR is enabled by default — save a file and the browser updates instantly.
Frontend Dependencies
Key dependencies (from web/package.json):
react 19, react-dom 19
@tanstack/react-query 5
@tanstack/react-router 1
@radix-ui/react-dropdown-menu, @radix-ui/react-select
class-variance-authority, clsx, tailwind-merge
openapi-fetch 0.13
i18next, react-i18next
zustand 5
react-markdown, rehype-highlight, rehype-sanitize
lucide-react (icons)
sonner (toasts)
Build tools: Vite 6, TypeScript 5.7, Vitest 3.2, Playwright 1.58
1---2name: frontend-conventions3description: Coding conventions, architecture patterns, and testing rules for the SkillHub React frontend. Ensures agents follow Feature-Sliced Design and use the generated OpenAPI types.4license: Apache-2.05---67# Frontend Conventions Skill89## Trigger1011Use this skill when:12- Adding or modifying React/TypeScript frontend code13- Creating new pages, features, entities, or shared components14- Changing API client calls or data fetching patterns1516## Rules1718### Feature-Sliced Design1920Place code at the lowest appropriate layer:2122| Layer | Path | Purpose |23|-------|------|---------|24| Pages | `web/src/pages/` | Route-level page components |25| Features | `web/src/features/` | Business features (search, upload, review, etc.) |26| Entities | `web/src/entities/` | Domain entity display logic (skill, user, namespace) |27| Shared | `web/src/shared/` | Reusable UI components, hooks, utilities |2829Current features:30- `admin` — Admin panel (user management, labels, search)31- `auth` — Login, OAuth flows, device auth32- `governance` — Skill governance actions (hide, yank, archive)33- `namespace` — Namespace management (members, settings)34- `notification` — User notifications and inbox35- `promotion` — Skill promotion between scopes36- `publish` — Skill upload/publish UI37- `report` — Skill reporting38- `review` — Review workflow UI39- `search` — Skill search and filtering40- `security-audit` — Security audit viewer41- `skill` — Skill detail, listing, cards42- `social` — Stars, ratings, subscriptions43- `token` — API token management4445### Data Fetching4647- **Always use TanStack Query** (`@tanstack/react-query`) for server state.48- **Never use `useEffect`** for data fetching.49- Use `openapi-fetch` client with generated types from `web/src/api/generated/schema.d.ts`.50- Never use `any` types.5152### State Management5354- **TanStack Query** for server state (API data, caching, invalidation, optimistic updates)55- **Zustand** for local/UI state (theme, sidebar, modals, form state)5657### Component Composition5859- **Radix UI** primitives: `@radix-ui/react-dropdown-menu`, `@radix-ui/react-select`60- **class-variance-authority** (cva) for component variants61- **clsx** + **tailwind-merge** for class merging62- **`cn()` utility**: `web/src/shared/lib/utils.ts`63- **shadcn/ui is NOT used** as a library6465### API Type Generation6667When backend OpenAPI contracts change:6869```bash70make generate-api71```7273This runs `openapi-typescript http://localhost:8080/v3/api-docs -o src/api/generated/schema.d.ts`.7475Commit the updated `web/src/api/generated/schema.d.ts` with the PR.7677To verify the generated file is not stale:7879```bash80./scripts/check-openapi-generated.sh81```8283### Styling8485- **Tailwind CSS** for all styling86- **`cn()` utility** for conditional class merging87- Follow existing component patterns in `web/src/shared/components/`8889### Internationalization9091- **i18next** + **react-i18next** for translations92- All user-facing text must be translatable93- Translation keys in `web/src/i18n/`9495### Build & Development9697```bash98make dev-web # Start Vite dev server (HMR enabled)99make build-frontend # Production build100make typecheck-web # TypeScript type check (tsc --noEmit)101make lint-web # ESLint check102make test-frontend # Vitest unit tests103make test-e2e-frontend # Playwright E2E tests104make test-e2e-smoke-frontend # Playwright smoke tests105```106107Vite HMR is enabled by default — save a file and the browser updates instantly.108109### Frontend Dependencies110111Key dependencies (from `web/package.json`):112- `react` 19, `react-dom` 19113- `@tanstack/react-query` 5114- `@tanstack/react-router` 1115- `@radix-ui/react-dropdown-menu`, `@radix-ui/react-select`116- `class-variance-authority`, `clsx`, `tailwind-merge`117- `openapi-fetch` 0.13118- `i18next`, `react-i18next`119- `zustand` 5120- `react-markdown`, `rehype-highlight`, `rehype-sanitize`121- `lucide-react` (icons)122- `sonner` (toasts)123124Build tools: Vite 6, TypeScript 5.7, Vitest 3.2, Playwright 1.58