{"id":"5df7ddbb-4970-4044-a17a-f743ca4309a4","shortId":"Fu7sCT","kind":"skill","title":"Frontend Dev Guidelines","tagline":"Antigravity Awesome Skills skill by Sickn33","description":"# Frontend Development Guidelines\n\n**(React · TypeScript · Suspense-First · Production-Grade)**\n\nYou are a **senior frontend engineer** operating under strict architectural and performance standards.\n\nYour goal is to build **scalable, predictable, and maintainable React applications** using:\n\n* Suspense-first data fetching\n* Feature-based code organization\n* Strict TypeScript discipline\n* Performance-safe defaults\n\nThis skill defines **how frontend code must be written**, not merely how it *can* be written.\n\n---\n\n## 1. Frontend Feasibility & Complexity Index (FFCI)\n\nBefore implementing a component, page, or feature, assess feasibility.\n\n### FFCI Dimensions (1–5)\n\n| Dimension             | Question                                                         |\n| --------------------- | ---------------------------------------------------------------- |\n| **Architectural Fit** | Does this align with feature-based structure and Suspense model? |\n| **Complexity Load**   | How complex is state, data, and interaction logic?               |\n| **Performance Risk**  | Does it introduce rendering, bundle, or CLS risk?                |\n| **Reusability**       | Can this be reused without modification?                         |\n| **Maintenance Cost**  | How hard will this be to reason about in 6 months?               |\n\n### Score Formula\n\n```\nFFCI = (Architectural Fit + Reusability + Performance) − (Complexity + Maintenance Cost)\n```\n\n**Range:** `-5 → +15`\n\n### Interpretation\n\n| FFCI      | Meaning    | Action            |\n| --------- | ---------- | ----------------- |\n| **10–15** | Excellent  | Proceed           |\n| **6–9**   | Acceptable | Proceed with care |\n| **3–5**   | Risky      | Simplify or split |\n| **≤ 2**   | Poor       | Redesign          |\n\n---\n\n## 2. Core Architectural Doctrine (Non-Negotiable)\n\n### 1. Suspense Is the Default\n\n* `useSuspenseQuery` is the **primary** data-fetching hook\n* No `isLoading` conditionals\n* No early-return spinners\n\n### 2. Lazy Load Anything Heavy\n\n* Routes\n* Feature entry components\n* Data grids, charts, editors\n* Large dialogs or modals\n\n### 3. Feature-Based Organization\n\n* Domain logic lives in `features/`\n* Reusable primitives live in `components/`\n* Cross-feature coupling is forbidden\n\n### 4. TypeScript Is Strict\n\n* No `any`\n* Explicit return types\n* `import type` always\n* Types are first-class design artifacts\n\n---\n\n## When to Use\nUse **frontend-dev-guidelines** when:\n\n* Creating components or pages\n* Adding new features\n* Fetching or mutating data\n* Setting up routing\n* Styling with MUI\n* Addressing performance issues\n* Reviewing or refactoring frontend code\n\n---\n\n## 4. Quick Start Checklists\n\n### New Component Checklist\n\n* [ ] `React.FC<Props>` with explicit props interface\n* [ ] Lazy loaded if non-trivial\n* [ ] Wrapped in `<SuspenseLoader>`\n* [ ] Uses `useSuspenseQuery` for data\n* [ ] No early returns\n* [ ] Handlers wrapped in `useCallback`\n* [ ] Styles inline if <100 lines\n* [ ] Default export at bottom\n* [ ] Uses `useMuiSnackbar` for feedback\n\n---\n\n### New Feature Checklist\n\n* [ ] Create `features/{feature-name}/`\n* [ ] Subdirs: `api/`, `components/`, `hooks/`, `helpers/`, `types/`\n* [ ] API layer isolated in `api/`\n* [ ] Public exports via `index.ts`\n* [ ] Feature entry lazy loaded\n* [ ] Suspense boundary at feature level\n* [ ] Route defined under `routes/`\n\n---\n\n## 5. Import Aliases (Required)\n\n| Alias         | Path             |\n| ------------- | ---------------- |\n| `@/`          | `src/`           |\n| `~types`      | `src/types`      |\n| `~components` | `src/components` |\n| `~features`   | `src/features`   |\n\nAliases must be used consistently. Relative imports beyond one level are discouraged.\n\n---\n\n## 6. Component Standards\n\n### Required Structure Order\n\n1. Types / Props\n2. Hooks\n3. Derived values (`useMemo`)\n4. Handlers (`useCallback`)\n5. Render\n6. Default export\n\n### Lazy Loading Pattern\n\n```ts\nconst HeavyComponent = React.lazy(() => import('./HeavyComponent'));\n```\n\nAlways wrapped in `<SuspenseLoader>`.\n\n---\n\n## 7. Data Fetching Doctrine\n\n### Primary Pattern\n\n* `useSuspenseQuery`\n* Cache-first\n* Typed responses\n\n### Forbidden Patterns\n\n❌ `isLoading`\n❌ manual spinners\n❌ fetch logic inside components\n❌ API calls without feature API layer\n\n### API Layer Rules\n\n* One API file per feature\n* No inline axios calls\n* No `/api/` prefix in routes\n\n---\n\n## 8. Routing Standards (TanStack Router)\n\n* Folder-based routing only\n* Lazy load route components\n* Breadcrumb metadata via loaders\n\n```ts\nexport const Route = createFileRoute('/my-route/')({\n  component: MyPage,\n  loader: () => ({ crumb: 'My Route' }),\n});\n```\n\n---\n\n## 9. Styling Standards (MUI v7)\n\n### Inline vs Separate\n\n* `<100 lines`: inline `sx`\n* `>100 lines`: `{Component}.styles.ts`\n\n### Grid Syntax (v7 Only)\n\n```tsx\n<Grid size={{ xs: 12, md: 6 }} /> // ✅\n<Grid xs={12} md={6} />          // ❌\n```\n\nTheme access must always be type-safe.\n\n---\n\n## 10. Loading & Error Handling\n\n### Absolute Rule\n\n❌ Never return early loaders\n✅ Always rely on Suspense boundaries\n\n### User Feedback\n\n* `useMuiSnackbar` only\n* No third-party toast libraries\n\n---\n\n## 11. Performance Defaults\n\n* `useMemo` for expensive derivations\n* `useCallback` for passed handlers\n* `React.memo` for heavy pure components\n* Debounce search (300–500ms)\n* Cleanup effects to avoid leaks\n\nPerformance regressions are bugs.\n\n---\n\n## 12. TypeScript Standards\n\n* Strict mode enabled\n* No implicit `any`\n* Explicit return types\n* JSDoc on public interfaces\n* Types colocated with feature\n\n---\n\n## 13. Canonical File Structure\n\n```\nsrc/\n  features/\n    my-feature/\n      api/\n      components/\n      hooks/\n      helpers/\n      types/\n      index.ts\n\n  components/\n    SuspenseLoader/\n    CustomAppBar/\n\n  routes/\n    my-route/\n      index.tsx\n```\n\n---\n\n## 14. Canonical Component Template\n\n```ts\nimport React, { useState, useCallback } from 'react';\nimport { Box, Paper } from '@mui/material';\nimport { useSuspenseQuery } from '@tanstack/react-query';\nimport { featureApi } from '../api/featureApi';\nimport type { FeatureData } from '~types/feature';\n\ninterface MyComponentProps {\n  id: number;\n  onAction?: () => void;\n}\n\nexport const MyComponent: React.FC<MyComponentProps> = ({ id, onAction }) => {\n  const [state, setState] = useState('');\n\n  const { data } = useSuspenseQuery<FeatureData>({\n    queryKey: ['feature', id],\n    queryFn: () => featureApi.getFeature(id),\n  });\n\n  const handleAction = useCallback(() => {\n    setState('updated');\n    onAction?.();\n  }, [onAction]);\n\n  return (\n    <Box sx={{ p: 2 }}>\n      <Paper sx={{ p: 3 }}>\n        {/* Content */}\n      </Paper>\n    </Box>\n  );\n};\n\nexport default MyComponent;\n```\n\n---\n\n## 15. Anti-Patterns (Immediate Rejection)\n\n❌ Early loading returns\n❌ Feature logic in `components/`\n❌ Shared state via prop drilling instead of hooks\n❌ Inline API calls\n❌ Untyped responses\n❌ Multiple responsibilities in one component\n\n---\n\n## 16. Integration With Other Skills\n\n* **frontend-design** → Visual systems & aesthetics\n* **page-cro** → Layout hierarchy & conversion logic\n* **analytics-tracking** → Event instrumentation\n* **backend-dev-guidelines** → API contract alignment\n* **error-tracking** → Runtime observability\n\n---\n\n## 17. Operator Validation Checklist\n\nBefore finalizing code:\n\n* [ ] FFCI ≥ 6\n* [ ] Suspense used correctly\n* [ ] Feature boundaries respected\n* [ ] No early returns\n* [ ] Types explicit and correct\n* [ ] Lazy loading applied\n* [ ] Performance safe\n\n---\n\n## 18. Skill Status\n\n**Status:** Stable, opinionated, and enforceable\n**Intended Use:** Production React codebases with long-term maintenance horizons\n\n\n## When to Use\nThis skill is applicable to execute the workflow or actions described in the overview.\n\n## Limitations\n- Use this skill only when the task clearly matches the scope described above.\n- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.\n- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.","tags":["frontend","dev","guidelines","antigravity","awesome","skills","sickn33"],"capabilities":["skill","source-sickn33","category-antigravity-awesome-skills"],"categories":["antigravity-awesome-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/sickn33/antigravity-awesome-skills/frontend-dev-guidelines","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"install_from":"skills.sh"}},"qualityScore":"0.300","qualityRationale":"deterministic score 0.30 from registry signals: · indexed on skills.sh · published under sickn33/antigravity-awesome-skills","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill:v1","enrichmentVersion":1,"enrichedAt":"2026-04-25T11:40:48.571Z","embedding":null,"createdAt":"2026-04-18T20:34:55.137Z","updatedAt":"2026-04-25T11:40:48.571Z","lastSeenAt":"2026-04-25T11:40:48.571Z","tsv":"'+15':165 '-5':164 '/api':488 '/api/featureapi':682 '/heavycomponent':444 '/my-route':515 '1':79,96,196,419 '10':170,562 '100':342,530,534 '11':587 '12':546,551,616 '13':636 '14':659 '15':171,733 '16':764 '17':799 '18':826 '2':186,189,217,422,724 '3':180,234,424,728 '300':605 '4':255,308,428 '5':97,181,388,431 '500ms':606 '6':151,174,413,433,548,553,807 '7':448 '8':492 '9':175,522 'absolut':566 'accept':176 'access':555 'action':169,857 'ad':287 'address':300 'aesthet':774 'alia':392 'alias':390,401 'align':104,793 'alway':266,445,557,572 'analyt':783 'analytics-track':782 'anti':735 'anti-pattern':734 'antigrav':4 'anyth':220 'api':361,366,370,469,473,475,479,645,755,791 'appli':823 'applic':44,851 'architectur':30,100,156,191 'artifact':273 'ask':895 'assess':92 'avoid':610 'awesom':5 'axio':485 'backend':788 'backend-dev-guidelin':787 'base':53,108,237,499 'beyond':408 'bottom':347 'boundari':380,576,812,903 'box':671,721 'breadcrumb':506 'bug':615 'build':38 'bundl':129 'cach':456 'cache-first':455 'call':470,486,756 'canon':637,660 'care':179 'category-antigravity-awesome-skills' 'chart':228 'checklist':311,314,354,802 'clarif':897 'class':271 'cleanup':607 'clear':870 'cls':131 'code':54,68,307,805 'codebas':838 'coloc':633 'complex':82,113,116,160 'compon':88,225,248,284,313,362,397,414,468,505,516,536,602,646,651,661,745,763 'condit':211 'consist':405 'const':440,512,695,700,704,713 'content':729 'contract':792 'convers':780 'core':190 'correct':810,820 'cost':141,162 'coupl':252 'creat':283,355 'createfilerout':514 'criteria':906 'cro':777 'cross':250 'cross-featur':249 'crumb':519 'customappbar':653 'data':49,119,206,226,293,331,449,705 'data-fetch':205 'debounc':603 'default':62,200,344,434,589,731 'defin':65,385 'deriv':425,593 'describ':858,874 'design':272,771 'dev':2,280,789 'develop':11 'dialog':231 'dimens':95,98 'disciplin':58 'discourag':412 'doctrin':192,451 'domain':239 'drill':750 'earli':214,333,570,739,815 'early-return':213 'editor':229 'effect':608 'enabl':621 'enforc':833 'engin':26 'entri':224,376 'environ':886 'environment-specif':885 'error':564,795 'error-track':794 'event':785 'excel':172 'execut':853 'expens':592 'expert':891 'explicit':261,317,625,818 'export':345,372,435,511,694,730 'feasibl':81,93 'featur':52,91,107,223,236,243,251,289,353,356,358,375,382,399,472,482,635,641,644,708,742,811 'feature-bas':51,106,235 'feature-nam':357 'featureapi':680 'featureapi.getfeature':711 'featuredata':685 'feedback':351,578 'fetch':50,207,290,450,465 'ffci':84,94,155,167,806 'file':480,638 'final':804 'first':17,48,270,457 'first-class':269 'fit':101,157 'folder':498 'folder-bas':497 'forbidden':254,460 'formula':154 'frontend':1,10,25,67,80,279,306,770 'frontend-design':769 'frontend-dev-guidelin':278 'goal':35 'grade':20 'grid':227,538,543,549 'guidelin':3,12,281,790 'handl':565 'handleact':714 'handler':335,429,597 'hard':143 'heavi':221,600 'heavycompon':441 'helper':364,648 'hierarchi':779 'hook':208,363,423,647,753 'horizon':844 'id':690,698,709,712 'immedi':737 'implement':86 'implicit':623 'import':264,389,407,443,664,670,675,679,683 'index':83 'index.ts':374,650 'index.tsx':658 'inlin':340,484,527,532,754 'input':900 'insid':467 'instead':751 'instrument':786 'integr':765 'intend':834 'interact':121 'interfac':319,631,688 'interpret':166 'introduc':127 'isload':210,462 'isol':368 'issu':302 'jsdoc':628 'larg':230 'layer':367,474,476 'layout':778 'lazi':218,320,377,436,502,821 'leak':611 'level':383,410 'librari':586 'limit':862 'line':343,531,535 'live':241,246 'load':114,219,321,378,437,503,563,740,822 'loader':509,518,571 'logic':122,240,466,743,781 'long':841 'long-term':840 'maintain':42 'mainten':140,161,843 'manual':463 'match':871 'md':547,552 'mean':168 'mere':73 'metadata':507 'miss':908 'modal':233 'mode':620 'model':112 'modif':139 'month':152 'mui':299,525 'mui/material':674 'multipl':759 'must':69,402,556 'mutat':292 'my-featur':642 'my-rout':655 'mycompon':696,732 'mycomponentprop':689 'mypag':517 'name':359 'negoti':195 'never':568 'new':288,312,352 'non':194,324 'non-negoti':193 'non-trivi':323 'number':691 'observ':798 'onact':692,699,718,719 'one':409,478,762 'oper':27,800 'opinion':831 'order':418 'organ':55,238 'output':880 'overview':861 'p':723,727 'page':89,286,776 'page-cro':775 'paper':672,725 'parti':584 'pass':596 'path':393 'pattern':438,453,461,736 'per':481 'perform':32,60,123,159,301,588,612,824 'performance-saf':59 'permiss':901 'poor':187 'predict':40 'prefix':489 'primari':204,452 'primit':245 'proceed':173,177 'product':19,836 'production-grad':18 'prop':318,421,749 'public':371,630 'pure':601 'queryfn':710 'querykey':707 'question':99 'quick':309 'rang':163 'react':13,43,665,669,837 'react.fc':315,697 'react.lazy':442 'react.memo':598 'reason':148 'redesign':188 'refactor':305 'regress':613 'reject':738 'relat':406 'reli':573 'render':128,432 'requir':391,416,899 'respect':813 'respons':459,758,760 'return':215,262,334,569,626,720,741,816 'reus':137 'reusabl':133,158,244 'review':303,892 'risk':124,132 'riski':182 'rout':222,296,384,387,491,493,500,504,513,521,654,657 'router':496 'rule':477,567 'runtim':797 'safe':61,561,825 'safeti':902 'scalabl':39 'scope':873 'score':153 'search':604 'senior':24 'separ':529 'set':294 'setstat':702,716 'share':746 'sickn33':9 'simplifi':183 'size':544 'skill':6,7,64,768,827,849,865 'source-sickn33' 'specif':887 'spinner':216,464 'split':185 'src':394,640 'src/components':398 'src/features':400 'src/types':396 'stabl':830 'standard':33,415,494,524,618 'start':310 'state':118,701,747 'status':828,829 'stop':893 'strict':29,56,258,619 'structur':109,417,639 'style':297,339,523 'styles.ts':537 'subdir':360 'substitut':883 'success':905 'suspens':16,47,111,197,379,575,808 'suspense-first':15,46 'suspenseload':652 'sx':533,722,726 'syntax':539 'system':773 'tanstack':495 'tanstack/react-query':678 'task':869 'templat':662 'term':842 'test':889 'theme':554 'third':583 'third-parti':582 'toast':585 'track':784,796 'treat':878 'trivial':325 'ts':439,510,663 'tsx':542 'type':263,265,267,365,395,420,458,560,627,632,649,684,817 'type-saf':559 'types/feature':687 'typescript':14,57,256,617 'untyp':757 'updat':717 'use':45,276,277,328,348,404,809,835,847,863 'usecallback':338,430,594,667,715 'usememo':427,590 'usemuisnackbar':349,579 'user':577 'usest':666,703 'usesuspensequeri':201,329,454,676,706 'v7':526,540 'valid':801,888 'valu':426 'via':373,508,748 'visual':772 'void':693 'vs':528 'without':138,471 'workflow':855 'wrap':326,336,446 'written':71,78 'xs':545,550","prices":[{"id":"fd9266e5-d37c-459a-b702-15bf3e57c3db","listingId":"5df7ddbb-4970-4044-a17a-f743ca4309a4","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"sickn33","category":"antigravity-awesome-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T20:34:55.137Z"}],"sources":[{"listingId":"5df7ddbb-4970-4044-a17a-f743ca4309a4","source":"github","sourceId":"sickn33/antigravity-awesome-skills/frontend-dev-guidelines","sourceUrl":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/frontend-dev-guidelines","isPrimary":false,"firstSeenAt":"2026-04-18T21:37:39.482Z","lastSeenAt":"2026-04-25T06:51:11.171Z"},{"listingId":"5df7ddbb-4970-4044-a17a-f743ca4309a4","source":"skills_sh","sourceId":"sickn33/antigravity-awesome-skills/frontend-dev-guidelines","sourceUrl":"https://skills.sh/sickn33/antigravity-awesome-skills/frontend-dev-guidelines","isPrimary":true,"firstSeenAt":"2026-04-18T20:34:55.137Z","lastSeenAt":"2026-04-25T11:40:48.571Z"}],"details":{"listingId":"5df7ddbb-4970-4044-a17a-f743ca4309a4","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"sickn33","slug":"frontend-dev-guidelines","source":"skills_sh","category":"antigravity-awesome-skills","skills_sh_url":"https://skills.sh/sickn33/antigravity-awesome-skills/frontend-dev-guidelines"},"updatedAt":"2026-04-25T11:40:48.571Z"}}