react-ts-guidelines
3
总安装量
3
周安装量
#61119
全站排名
安装命令
npx skills add https://github.com/lichens-innovation/skills --skill react-ts-guidelines
Agent 安装分布
amp
3
gemini-cli
3
github-copilot
3
codex
3
kimi-cli
3
cursor
3
Skill 文档
Coding Standards & Best Practices
Non-negotiable rules
Apply non-negotiable rules (19 rules, ordered by impact) before anything else.
Agent Instructions
After reading this skill:
- Apply ALL rules to every file you create or modify
- Run the Pre-output Validation checklist before returning any code
- If a rule conflicts with a user request, flag it explicitly and propose a compliant alternative
- Reference specific rule names when explaining choices (e.g., “Per the KISS principle, I simplified this by…”)
- Load example files on demand â only read the relevant file for the task at hand
Code Quality Principles
| Principle | Rule |
|---|---|
| Readability First | Code is read more than written. Clear names > clever code. |
| KISS | Simplest solution that works. Avoid over-engineering. |
| Avoid GodComponent | Single responsibility per component; extract utilities, hooks, sub-components. |
| DRY | Extract common logic. Create reusable components. |
| YAGNI | Don’t build features before they’re needed. |
| Immutability | Never mutate â always return new values. |
Avoiding GodComponent (decomposition strategy)
Apply the following order to keep components focused and testable:
-
Extract pure TypeScript utilities first
- Move logic that has no React dependency into pure functions.
- If a utility takes more than one argument, use object destructuring in the signature so argument names are explicit at the call site. Extract the parameter type (e.g.
interface FormatRangeArgs { start: number; end: number }thenconst formatRange = ({ start, end }: FormatRangeArgs) => ...). - Reusable across features â put in
src/utils/xyz.utils.ts. - Feature-specific â keep next to the component as
component-name.utils.ts(same kebab-case base name as the component file, e.g.market-list-item.utils.tsnext tomarket-list-item.tsx).
-
Extract logic into named hooks
- Move state, effects, and derived logic into hooks (e.g.
use-xyz.ts). - Reusable across features â put in
src/hooks/use-xyz.ts. - Feature-specific â keep in the featureâs
hooks/subdirectory (e.g.features/market-list/hooks/use-market-filters.ts).
- Move state, effects, and derived logic into hooks (e.g.
-
Split the visual layer into sub-components
- If the render/JSX exceeds roughly 40 lines, extract sub-components with clear props and a single responsibility.
- Each sub-component should have its own props interface and live in its own file (or a dedicated subfolder) when it grows.
Sections & Example Files
TypeScript / JavaScript
| Topic | Example File | When to load |
|---|---|---|
| Variable & function naming (incl. boolean prefixes) | examples/typescript/naming.ts |
When naming anything (arrow functions only; booleans: is/has/should/can/will) |
| Immutability patterns | examples/typescript/immutability.ts |
When working with state/objects/arrays |
| Error handling | examples/typescript/error-handling.ts |
When writing async code |
| Async / Promise patterns | examples/typescript/async-patterns.ts |
When using await/Promise |
| Type safety | examples/typescript/type-safety.ts |
When defining interfaces/types (no inline types; no nested types; extract named types) |
| Control flow & readability | examples/typescript/control-flow.ts |
Early returns, const vs let, Array.includes/some, nullish coalescing, destructuring |
React
| Topic | Example File | When to load |
|---|---|---|
| Component structure | examples/react/component-structure.tsx |
When creating a component |
Testing
| Topic | Example File | When to load |
|---|---|---|
| Unit test patterns | examples/testing/unit-testing-patterns.tsx |
When writing Jest/RTL tests (AAA, screen, spyOn, it.each, getByRole, mock factory) |
Anti-patterns (read during code review)
| Topic | File |
|---|---|
| All BAD patterns grouped | anti-patterns/what-not-to-do.ts |
| Code smells detection | anti-patterns/code-smells.ts |
File Organization Rules
- 200â400 lines typical file length
- 800 lines absolute maximum
- One responsibility per file (high cohesion, low coupling)
- File names: always kebab-case (lowercase with hyphens). No PascalCase or camelCase in file or folder names.
components/button.tsx # kebab-case (not Button.tsx)
hooks/use-auth.ts # kebab-case (not useAuth.ts)
lib/format-date.ts # kebab-case (not formatDate.ts)
types/market.types.ts # kebab-case + optional .types / .utils / .store suffix
features/market-list/market-list-item.tsx
settings-screen.tsx # e.g. settings-screen.tsx, use-device-discovery.ts
Components and hooks are still exported with PascalCase (components) or camelCase with use prefix (hooks); only the file name is kebab-case.
Code Style / TypeScript
- TypeScript strict mode â enable in
tsconfig.jsonfor maximum type safety. - Explicit function signatures â type function parameters and return types explicitly; avoid relying on inference for public APIs.
- Type inference for locals â prefer inference for local variables when the type is obvious (e.g.
const count = 0).
React Components
- FunctionComponent â type React components with
FunctionComponent<Props>(orFC<Props>); use typed props interfaces, not inline orany. - Early returns â use early returns in component bodies to keep the main render path flat and readable.
- Fragment shorthand â use
<>...</>instead of<Fragment>unless akeyis required. - Exports â prefer named exports for components; default export only when required by the framework (e.g. Expo Router).
React Hooks
- Functions vs hooks â prefer a plain function to a custom hook when you don’t need React primitives (state, effects, context).
- use prefix â use the
useprefix only for real hooks; never for plain functions. - useMemo / useCallback â avoid for simple computations or callbacks; use when profiling shows a need or when passing callbacks to memoized children.
- Handlers â use a single arrow function per handler (e.g.
const handleClick = () => { ... }); avoid function factories that return handlers. - Selected items â store selection by ID in state and derive the full item from the list (e.g.
selectedItem = items.find(i => i.id === selectedId)); avoids stale references when the list updates.
Data fetching (async: loading, error, data)
- Prefer TanStack Query â for any async call that involves
isLoading, error handling, and result data, useuseQuery(oruseMutationfor writes) instead of manualuseState+useEffect. You get caching, deduplication, and consistent loading/error state for free. - Query key factory â define a single source of truth for cache keys (e.g.
XxxQueryKey.all,XxxQueryKey.list(...),XxxQueryKey.detail(id)). See examples/react/query-keys-example.ts and assets/hook-tanstack-query-template.ts.
Error Handling
- Context in messages â include a prefix in error and log messages (e.g.
[ComponentName] failed to load). - Rethrow policy â rethrow only when adding context or transforming the error type; don’t rethrow after logging unless the caller needs to handle the failure.
Architecture & Organisation
- Feature structure â each feature should be self-contained: its own components,
hooks/subdirectory,*.utils.tsand*.types.tsfiles, and Controllers/Services for complex business logic (e.g.features/scene-3d/,scene-manager/controllers/). - Single responsibility â one clear responsibility per file; keep components small and focused. Apply the Avoiding GodComponent (decomposition strategy): utilities first, then hooks, then sub-components when the visual layer exceeds ~40 lines.
- Composition over inheritance â prefer composing small components and utilities over class inheritance.
- Group related code â keep related functionality together (e.g. by feature or domain).
Comments
- Self-documenting first â prefer clear names and structure over comments; comment only when behavior is non-obvious.
- Explain “why” not “what” â comments should explain rationale, side effects, or workarounds, not restate the code.
- Keep comments up to date â remove or update comments when code changes.
- TODO with ticket ID â use a traceable format for TODOs (e.g.
// TODO: JIRA-1234 - description).
Logging
- Logger with levels â use a logger (e.g.
logger.info(),logger.error(),logger.warn(),logger.debug()) instead ofconsole.*in client code. - Context prefix â include a context prefix in log messages (e.g.
[useDeviceDiscovery] storing last known camera IP). - Server exception â
console.logis acceptable in server-side or API route code for debugging.
Function Parameters
- Destructuring for multiple params â use object destructuring when a function has more than one parameter (e.g.
const fn = ({ a, b }: Args) => ...). - Extract parameter types â export parameter types as named types/interfaces instead of inline typing.
- Optional parameters â use
param?: Typerather thanparam: Type | undefined. - Defaults in destructuring â set default values in the destructuring when possible (e.g.
{ page = 1, size = 10 }).
TypeScript Best Practices
- ReactNode for children â use
ReactNodefor component children (notJSX.Element | null | undefined). - PropsWithChildren â use
PropsWithChildren<Props>for components that acceptchildren. Record<K, V>â prefer theRecord<K, V>utility type over custom index signatures.- Array.includes() â use for multiple value checks instead of repeated
===comparisons. - Array.some() â use for existence checks instead of
array.find(...) !== undefined. - Explicit enum values â use explicit numeric (or string) values for enums so they survive reordering and serialization.
React Native (when applicable)
When working in a React Native or Expo project:
- Spacing â prefer
gap,rowGap, andcolumnGapovermargin/paddingfor spacing between elements. - Responsive layout â use
useWindowDimensionsinstead ofDimensions.getfor layout that reacts to size changes. - Static data outside components â move constants and pure functions that don’t depend on props or state outside the component to avoid new references on every render.
Pre-output validation
Before returning any code, run the Pre-output Validation checklist.
Templates
Skeletons to copy and adapt (file names in kebab-case):
| Type | File | Use when |
|---|---|---|
| Hook | assets/hook-template.ts | Creating a data-fetching or effect hook |
| Hook (TanStack Query) | assets/hook-tanstack-query-template.ts | Creating a hook with @tanstack/react-query (queryKey, queryFn, placeholderData) |
| Component | assets/component-template.tsx | Creating a React component |
| Utility | assets/utils-template.ts | Creating pure or side-effect helpers (*.utils.ts) |
Validation
Validate this skill’s frontmatter and structure with skills-ref:
skills-ref validate ./skills/react-ts-guidelines