Frontend Patterns
SkillDev toolsApply frontend conventions when components, pages, forms, or client state change.
Then ask your AI: use the Frontend Patterns skill
Details
Instructions available. Your AI can read the instructions. Execution depends on the setup they require.
Account requirements not reviewed. Check the skill instructions before use; Ahel provides instructions and does not run this skill.
No other account needed.
Add it as a step in a pipeline you build on Ahel, or connect Ahel to Claude, ChatGPT, Cursor, Claude Code or Codex and ask your AI to use it.
What this skill tells your AI
The instructions your AI receives, as published by kbwen/agentic-os in .agents/skills/frontend-patterns/SKILL.md and read by Ahel’s review.
When to Apply
- Classification: feature, architecture-change (if touching UI)
- Phase: /implement (component design & build), /review (pattern compliance), /test (UI state coverage)
- Trigger: Task involves creating or modifying UI components, pages, routes, or client-side state
Conventions
Customize after /app-init: Replace these generic conventions with your project's ADR and framework-specific patterns.
Component Structure
- One component per file
- Component file name matches export name (PascalCase)
- Co-locate component-specific styles, tests, and types
- Separate page-level components from reusable UI components
Suggested Directory Pattern
src/
├── components/ # Reusable UI components (Button, Modal, Card)
│ └── <Name>/
│ ├── <Name>.tsx
│ ├── <Name>.test.tsx
│ └── index.ts
├── pages/ # Page-level components (route targets)
│ └── <PageName>/
│ ├── <PageName>.tsx
│ ├── components/ # Page-specific components (not reusable)
│ └── hooks/ # Page-specific hooks
├── hooks/ # Shared custom hooks
├── services/ # API client functions
├── stores/ # State management (if applicable)
├── types/ # Shared TypeScript types
└── utils/ # Pure utility functions
State Management Principles
- Local state first: useState/useReducer for component-specific state
- Lift state up only when sibling components need it
- Global state (store) only for truly app-wide state: auth, theme, user preferences
- Server state (API data) managed by data-fetching library (React Query, SWR, etc.) — NOT in global store
- Never duplicate server state in client store
Data Fetching
- Centralize API calls in
services/directory - Use data-fetching hooks (React Query, SWR, or equivalent) instead of raw fetch/axios in components
- Handle loading, error, and empty states for every data-dependent component
- Implement optimistic updates for better UX where appropriate
Form Handling
- Use a form library for complex forms (React Hook Form, Formik, or equivalent)
- Validate on client AND server (client validation is UX, server validation is security)
- Show inline errors next to fields, not just at form top
- Disable submit button during submission (prevent double-submit)
Error Handling
- Global error boundary for unexpected crashes
- Per-component error handling for expected failures (API errors)
- User-friendly error messages (never show raw error objects)
- Retry mechanism for transient failures (network errors)
Checklist
During /implement:
- Every data-dependent component handles: loading, error, empty, and success states
- No business logic in components (extract to hooks or services)
- No hardcoded strings (use constants or i18n keys)
- Accessible: semantic HTML, aria labels on interactive elements, keyboard navigation
- Responsive: works on mobile viewport (unless spec explicitly excludes mobile)
- No direct API calls in components (use service layer)
During /review:
- No prop drilling deeper than 2 levels (use context or composition)
- No unnecessary re-renders (check memo/callback usage)
- No sensitive data stored in localStorage/client state
- Route guards for authenticated pages
- Loading indicators for async operations
Heading-Scoped Read Note
For phase-entry loading, read only:
When to ApplyChecklist
Load Conventions, Anti-Patterns, and References on full read or cache miss only.
Anti-Patterns
- God component: Component with 300+ lines doing everything. Split into smaller components.
- Prop drilling: Passing props through 3+ levels of components. Use context or composition.
- useEffect for everything: Using useEffect for derived state (use useMemo) or event handling (use event handlers).
- Index as key: Using array index as React key in dynamic lists.
- Fetch in render: Calling fetch/axios directly in component body or useEffect without a data-fetching library.
- CSS-in-JS soup: Inline styles everywhere instead of consistent styling approach.
- Ignoring empty state: Showing a blank page when data array is empty instead of a helpful message.
- Alert/Console for errors: Using
alert()or onlyconsole.error()instead of proper UI error handling.
References
- Project ADR:
docs/adr/ADR-002-project-architecture.md§ Directory Structure, Naming - Spec template:
.agentcortex/templates/spec-app-feature.md§ Frontend - Security guardrails:
.agent/rules/security_guardrails.md(A03: XSS prevention, A07: Auth)
Signals
- GitHub stars
- 207
- Forks
- 44
- Last commit
- Oct 2026
Ahel recommends instead
Advanced
- Item type
- skill
- Key
frontend-patterns-2- Source
- github.com/kbwen/agentic-os