CtrlK
BlogDocsLog inGet started
Tessl Logo

frontend-developer

Builds and debugs frontend components, implements responsive layouts, optimizes bundle size and rendering performance, and enforces accessibility standards across React, Vue, Angular, and Svelte projects. Use when the user asks to create or refactor UI components, fix CSS/HTML/JavaScript issues, set up state management, improve Core Web Vitals, configure Tailwind or design tokens, debug hydration or rendering problems, or implement keyboard navigation and ARIA patterns in a web app.

87

Quality

84%

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Passed

No known issues

SKILL.md
Quality
Evals
Security

Frontend Developer


Workflow

1. Define

  • Map component boundaries, data flows, and responsive breakpoints before writing code.
  • Set explicit performance budgets (e.g., LCP < 2.5 s, TBT < 200 ms, bundle < 200 KB gzipped initial load).
  • Identify accessibility requirements per WCAG 2.1 AA at the start, not the end.

2. Build Components (with Accessibility by Default)

React accessible component template:

import { forwardRef, type ButtonHTMLAttributes } from 'react';
import { cn } from '@/lib/utils';

interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: 'primary' | 'ghost';
  isLoading?: boolean;
}

export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
  ({ variant = 'primary', isLoading, children, disabled, className, ...props }, ref) => (
    <button
      ref={ref}
      disabled={disabled || isLoading}
      aria-busy={isLoading}
      aria-disabled={disabled || isLoading}
      className={cn('btn', `btn--${variant}`, className)}
      {...props}
    >
      {isLoading ? <span aria-hidden="true">⏳</span> : null}
      <span>{children}</span>
    </button>
  )
);
Button.displayName = 'Button';

Anti-pattern vs. pattern — keyboard-accessible disclosure:

// ❌ Anti-pattern: click-only, no keyboard, no ARIA
<div onClick={toggle}>Menu</div>

// ✅ Pattern: semantic button, ARIA expanded, keyboard-accessible
<button
  type="button"
  aria-expanded={isOpen}
  aria-controls="nav-menu"
  onClick={toggle}
>
  Menu
</button>
<ul id="nav-menu" hidden={!isOpen}>…</ul>

Framework-specific guidance: For Vue (Composition API, Pinia), Angular (signals, NgRx), and Svelte (stores, SvelteKit) patterns, refer to dedicated framework sub-files if available in the project. The examples below use React but the principles (state colocation, async loading states, lazy splitting) apply across all four frameworks.

3. Integrate Data and State

// ✅ Co-located state — only lifted when two siblings share it
function SearchPage() {
  const [query, setQuery] = useState('');
  return (
    <>
      <SearchInput value={query} onChange={setQuery} />
      <ResultsList query={query} />
    </>
  );
}

Async data with loading / error states (React Query pattern):

const { data, isPending, isError } = useQuery({
  queryKey: ['products', filters],
  queryFn: () => fetchProducts(filters),
  staleTime: 60_000,
});

if (isPending) return <Skeleton count={6} aria-label="Loading products" />;
if (isError)  return <ErrorMessage retry={refetch} />;
return <ProductGrid items={data} />;

4. Optimize Performance

Run npx lighthouse <url> --output json and verify thresholds before shipping:

MetricTarget
LCP< 2.5 s
TBT< 200 ms
CLS< 0.1
Initial JS< 200 KB gzipped

Bundle splitting — route-level lazy loading:

// ❌ Anti-pattern: eager import bloats initial bundle
import DashboardPage from './pages/Dashboard';

// ✅ Pattern: code-split at route boundaries
const DashboardPage = lazy(() => import('./pages/Dashboard'));

<Suspense fallback={<PageSkeleton />}>
  <DashboardPage />
</Suspense>

Image optimization:

<!-- Provide width/height to prevent CLS; fetchpriority="high" only on LCP image -->
<img
  src="/hero.webp"
  alt="Descriptive alt text"
  width="1200" height="630"
  loading="lazy"
  decoding="async"
  fetchpriority="high"
/>

5. Validate

Run these before marking work complete:

# Accessibility scan (zero violations target)
npx axe-cli <url>

# Lighthouse CI with budget enforcement
npx lhci autorun --config=lighthouserc.js

# Unit + integration tests
npm test -- --coverage --passWithNoTests

# End-to-end critical paths
npx playwright test --project=chromium,firefox,webkit

Validation checkpoints:

  • axe-cli returns 0 violations.
  • Lighthouse LCP < 2.5 s on simulated 4G.
  • Keyboard-only navigation completes all critical user journeys.
  • No hydration mismatch warnings in the browser console (SSR projects).
  • Coverage ≥ 80 % on business-critical components.

Constraints

  • Do not trade accessibility or maintainability for visual polish.
  • Call out browser support limits, hydration risks, and data-loading bottlenecks explicitly.
  • Keep performance budgets measurable (numbers, not adjectives).
  • Prefer reusable patterns over one-off UI implementations when the product surface will grow.
  • Flag aria-* misuse and missing keyboard handlers as bugs, not style preferences.
Repository
OpenRoster-ai/awesome-agents
Last updated
Created

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.