AI Skill Report Card

Setting Up Frontend Project Standards

A-83·Nov 8, 2026·Source: Web
YAML
--- name: setting-up-frontend-project-standards description: Establishes production-grade frontend project tooling and architecture following strict TypeScript, linting, formatting, commit, and dynamic/brand-driven UI conventions used by a Senior Frontend Lead at an International IT Consultancy. Use when scaffolding a new frontend/React project, auditing an existing codebase for best practices, configuring ESLint/Prettier/Husky/commitlint, or reviewing PRs for performance, stability, UX/DX, and reusability concerns. --- # Setting Up Frontend Project Standards
14 / 15

Scaffold a new project with the mandatory toolchain:

Bash
pnpm add -D typescript typescript-eslint eslint eslint-config-prettier \ eslint-plugin-prettier eslint-plugin-perfectionist eslint-plugin-sonarjs \ eslint-plugin-unicorn eslint-plugin-unused-imports prettier husky \ lint-staged @commitlint/cli @commitlint/config-conventional @types/node pnpm add @tanstack/react-query axios # If React project: pnpm add -D @types/react eslint-plugin-react-hooks pnpm add react-i18next

Copy .prettierrc, eslint.config.ts exactly as defined in this skill (see reference files below), then wire up husky + lint-staged + commitlint.

Recommendation▾
Provide the full eslint.config.ts file content rather than a prose description, since Claude would need to reconstruct it from scratch otherwise
14 / 15

Progress:

  • Step 1: Initialize TypeScript strictly (strict: true, no implicit any, no untyped JS allowed)
  • Step 2: Install mandatory dependencies (always) + optional React dependencies (if applicable)
  • Step 3: Add .prettierrc (tabs, no semi, single quotes, no trailing comma)
  • Step 4: Add eslint.config.ts (flat config, TS-based) using the reference config
  • Step 5: Configure Husky + lint-staged for pre-commit lint/format
  • Step 6: Configure commitlint with @commitlint/config-conventional + commit-msg hook
  • Step 7: Architect app for dynamic/backend-driven rendering (config/schema-driven UI, no hardcoded content)
  • Step 8: Architect for brand-driven theming (tokens, CSS variables, no hardcoded brand values)
  • Step 9: Ensure shareability/reusability (headless components, hooks extraction, no app-coupled logic in shared libs)
  • Step 10: Wire @tanstack/react-query for all server state; axios instance with interceptors for API layer
  • Step 11: Run full lint + typecheck + build before considering done
Recommendation▾
Add an example showing a bad/failing audit output (e.g., a non-compliant codebase) to contrast with compliant scaffolding examples

.prettierrc

JSON
{ "singleAttributePerLine": true, "trailingComma": "none", "singleQuote": true, "endOfLine": "auto", "useTabs": true, "semi": false, "tabWidth": 2 }

eslint.config.ts — flat config built on typescript-eslint, @eslint/js, with plugins: unused-imports, unicorn (recommended + custom class-member-order/filename-case/no-null rules), perfectionist (recommended-line-length), react-hooks (flat recommended, React projects only), sonarjs (applied to scripts/**/*.mjs), and prettier as the final formatting authority (eslint-config-prettier + eslint-plugin-prettier/recommended). Always globalIgnores build artifacts, lockfiles, and AI-agent tool directories (.claude, .cursor, .gemini, .codex, .opencode, .agents, .github, .nx).

Key enforced rules: unused-imports/no-unused-vars (ignore _-prefixed), no-console (allow table/info/error/warn only), eqeqeq: always, prefer-const, no-debugger, no-alert, no-var, kebab/snake filename casing, no native null (prefer undefined, exceptions for arguments).

commitlint.config.js

JavaScript
module.exports = { extends: ['@commitlint/config-conventional'] }

.husky/pre-commit

Bash
pnpm lint-staged

.husky/commit-msg

Bash
pnpm commitlint --edit "$1"

lint-staged config (package.json)

JSON
{ "lint-staged": { "*.{ts,tsx,js,jsx}": ["eslint --fix", "prettier --write"] } }
16 / 20

Example 1: Input: "New React dashboard project, needs multi-brand white-labeling and server-driven widgets." Output: Scaffold with full mandatory + React optional deps. Theme via CSS variables/design tokens resolved at runtime from a brand config fetched via axios + cached with @tanstack/react-query. Widgets rendered from a JSON schema (backend-driven) mapped to a component registry — no brand or copy hardcoded in components. ESLint/Prettier/Husky/commitlint wired exactly per reference configs.

Example 2: Input: "Review this PR: a Button component hardcodes '#FF5733' and English-only text." Output: Flag as violation of brand-driven and i18n principles. Recommend: extract color to CSS variable/design token (var(--color-brand-primary)), extract text via react-i18next (t('button.label')), and ensure component accepts props for full reusability across brands/locales. Also flag missing unicorn/no-null compliance if null is used instead of undefined.

Example 3: Input: "Should we use Redux for server state?" Output: No — standardize on @tanstack/react-query for all server-state (caching, revalidation, dedupe) and keep client-only state in local/component state or a minimal store. Redux (or similar) only justified for complex, cross-cutting client state unrelated to server data.

Recommendation▾
Clarify versioning/compatibility notes (e.g., ESLint flat config requires ESLint 9+) to avoid pitfalls when applied to older projects
  • TypeScript is non-negotiable: no .js source files, no any without explicit justification comment.
  • Dynamic/backend-driven first: UI structure, copy, and feature flags should be data-driven, never hardcoded, so backend/CMS changes don't require redeploys.
  • Brand-driven theming: all colors, logos, fonts resolved via tokens/config, never inlined.
  • Shareable & reusable: build components/hooks as headless/presentational-agnostic; push side effects to the edges (hooks, API layer).
  • DX matters: lint/format/commit-hygiene enforced automatically via Husky + lint-staged + commitlint — never rely on manual discipline.
  • Performance: prefer @tanstack/react-query caching over manual fetch/state; code-split by route/feature; memoize only when profiling justifies it.
  • Stability: eqeqeq, prefer-const, strict TS, SonarJS rules (for scripts) to catch bugs/code smells early.
  • Naming: kebab-case or snake_case filenames only (enforced by unicorn/filename-case).
  • Imports: no unused imports/vars (auto-fixed), no duplicate imports except type-only.
  • Don't skip the optional React deps check — eslint-plugin-react-hooks and @types/react are React-only, don't add to non-React (e.g., Node/CLI) projects.
  • Don't hardcode brand colors, logos, or copy directly in components — breaks white-labeling/i18n.
  • Don't use null directly — prefer undefined per unicorn/no-null (function arguments are exempted).
  • Don't bypass commit hooks (--no-verify) — commit message format and lint-staged checks exist to protect CI.
  • Don't introduce alternative formatters/linters (e.g., Biome) that conflict with the established Prettier+ESLint flat-config pipeline.
  • Don't manage server state with local useState/useEffect fetch patterns — always route through @tanstack/react-query.
  • Don't allow console.log — only table, info, error, warn are permitted by lint rules.
0
Grade A-AI Skill Framework
Scorecard
Criteria Breakdown
Quick Start
14/15
Workflow
14/15
Examples
16/20
Completeness
18/20
Format
14/15
Conciseness
13/15