.claude/skills/code-quality/SKILL.md
Frontend Fundamentals code quality rules — readability, predictability, cohesion, coupling. Surface-level polish rules (naming, constants, comparisons, side effects). Used in Phase 3 of /refactor (flat, single pass).
npx skillsauth add taewoongheo/taste code-qualityInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Source: https://frontend-fundamentals.com/code-quality/
3 principles, 9 rules. Apply after structural refactoring is complete.
Goal: Reduce the amount of context a reader must hold in their head at once.
When a condition involves multiple checks, assign it to a named variable. The name acts as documentation.
// BAD
product.categories.some((cat) => cat.id === targetCategory.id && product.prices.some((p) => p >= minPrice && p <= maxPrice))
// GOOD
const isSameCategory = category.id === targetCategory.id;
const isPriceInRange = product.prices.some((p) => p >= minPrice && p <= maxPrice);
return isSameCategory && isPriceInRange;
Skip naming when logic is trivially obvious: arr.map(x => x * 2).
A bare number hides intent. Name it with a constant.
// BAD
await delay(300);
// GOOD
const ANIMATION_DELAY_MS = 300;
await delay(ANIMATION_DELAY_MS);
Code should read top-to-bottom without jumping to distant definitions. If abstraction adds more jumps than it saves, inline it.
Rule of thumb: If the abstraction is simple enough to fit inline and only used once, prefer inline.
Replace nested ternaries with IIFE + early returns or switch.
// BAD
const status = A && B ? "BOTH" : A || B ? (A ? "A" : "B") : "NONE";
// GOOD
const status = (() => {
if (A && B) return "BOTH";
if (A) return "A";
if (B) return "B";
return "NONE";
})();
When a function or hook takes 4+ related parameters, group them into a single object. This reduces call-site noise and makes the relationship between values explicit.
// BAD — 11 individual params
const styles = useAnimatedStyles(
progress, isReady, gridX, gridY, gridW, gridH, gridRot,
detailX, detailY, detailW, detailH,
);
// GOOD — one object
const styles = useAnimatedStyles({
progress, isReady,
gridX, gridY, gridW, gridH, gridRot,
detailX, detailY, detailW, detailH,
});
No performance cost: object reference changes don't cause re-renders in hooks. For deps arrays, access obj.prop (primitive comparison) instead of obj (reference comparison).
Write range checks like math notation: lower <= value && value <= upper.
// BAD
if (score >= 80 && score <= 100)
// GOOD
if (80 <= score && score <= 100)
Goal: A function's name, params, and return type should fully describe its behavior. No surprises.
If your wrapper adds behavior (auth, logging), the name must reflect that. Don't reuse the library's name.
Functions that do the same kind of thing (API hooks, validators) must return the same shape. Inconsistency causes bugs.
A function should only do what its signature promises. Side effects (logging, analytics, cache invalidation) that aren't visible from the signature should be moved to the call site.
Goal: Code that changes together should live together.
Beyond readability, magic numbers break cohesion. If 300 appears in both an animation and a delay, changing one without the other creates bugs. A named constant links them.
Field-level vs form-level validation — match the cohesion level to the unit of change.
Premature DRY creates coupling. If two pieces of code look similar today but may diverge tomorrow, keep them separate.
Abstract when: behavior is identical AND will stay identical. Duplicate when: behavior might diverge, future requirements are uncertain, or change blast radius must be minimized.
| # | Rule | Principle | One-liner |
|---|------|-----------|-----------|
| 1-D | Name complex conditions | Readability | isSameCategory && isPriceInRange |
| 1-E | Name magic numbers | Readability | ANIMATION_DELAY_MS = 300 |
| 1-F | Reduce eye movement | Readability | Inline simple one-use abstractions |
| 1-G | Simplify ternaries | Readability | IIFE + early returns over nested ? : |
| 1-H | Group related params | Readability | 4+ related params → single object |
| 1-I | Left-to-right comparisons | Readability | 80 <= score && score <= 100 |
| 2-A | Unique names | Predictability | Don't shadow library names |
| 2-B | Unified return types | Predictability | Same-kind functions → same return shape |
| 2-C | No hidden side effects | Predictability | Side effects at call site, not inside |
| 3-B | Named constants | Cohesion | Link related values via shared constant |
| 3-C | Form cohesion level | Cohesion | Field-level vs form-level — match change unit |
| 4-B | Allow duplication | Coupling | Wrong abstraction > duplication |
development
Visual hierarchy verification — squint test, information density, primary action clarity, and empty state quality for mobile UI. Auto-load when doing design or layout work.
development
Comprehensive design guide for web and mobile applications. Contains 50+ styles, 97 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types.
development
TDD patterns for React Native — Jest setup, React Native Testing Library patterns, mock strategies, and what to test vs skip. Auto-load when writing or running tests.
testing
Spacing, layout, and spatial relationships — consistent scale, proximity grouping, optical alignment, and density control for mobile UI. Auto-load when doing design or layout work.