Ultracite Code Standards for React
Enforce strict code quality standards in React/TypeScript projects using **Ultracite**, a zero-config Biome preset with automated formatting and linting.
Overview
This skill guides you to write **accessible, performant, type-safe, and maintainable** React/TypeScript code following Ultracite's strict standards. Most issues are automatically fixable via Biome's Rust-based engine.
Quick Commands
Before implementing suggestions, inform the user they can run:
`npx ultracite fix` — Auto-fix formatting and linting issues`npx ultracite check` — Check for issues without fixing`npx ultracite doctor` — Diagnose setup problemsCore Coding Standards
Type Safety & Explicitness
**Use explicit types** for function parameters and return values when they enhance clarity**Prefer `unknown` over `any`** when the type is genuinely unknown**Use const assertions** (`as const`) for immutable values and literal types**Leverage type narrowing** instead of type assertions (`as`)**Extract magic numbers** into named constants with descriptive namesModern JavaScript/TypeScript Patterns
**Use arrow functions** for callbacks and short functions**Prefer `for...of`** loops over `.forEach()` and indexed `for` loops**Use optional chaining** (`?.`) and nullish coalescing (`??`) for safer property access**Use template literals** over string concatenation**Use destructuring** for object and array assignments**Use `const` by default**, `let` only when reassignment is needed, **never `var`**Async & Promises
**Always `await` promises** in async functions — don't forget to use the return value**Use `async/await`** instead of promise chains for readability**Handle errors** with `try-catch` blocks in async code**Don't use async functions as Promise executors**React & JSX Best Practices
**Use function components** over class components**Call hooks at the top level** only, never conditionally**Specify all dependencies** correctly in hook dependency arrays**Use unique IDs for `key` props** in iterables (avoid array indices)**Nest children** between opening and closing tags instead of passing as props**Don't define components inside other components**Accessibility (a11y)
Ensure all React components are accessible:
**Provide meaningful alt text** for images**Use proper heading hierarchy** (h1 → h2 → h3, etc.)**Add labels** for all form inputs**Include keyboard event handlers** alongside mouse events**Use semantic HTML** (`<button>`, `<nav>`, `<main>`, etc.) instead of `<div>` with ARIA rolesError Handling & Debugging
**Remove `console.log`, `debugger`, and `alert`** statements from production code**Throw `Error` objects** with descriptive messages, not strings**Use `try-catch` meaningfully** — don't catch errors just to rethrow them**Prefer early returns** for error cases to reduce nestingCode Organization
**Keep functions focused** with low cognitive complexity**Extract complex conditions** into well-named boolean variables**Use early returns** to reduce nesting depth**Avoid nested ternary operators** — prefer simple conditionals**Group related code** together and separate concernsSecurity
**Add `rel="noopener"`** when using `target="_blank"` on links**Avoid `dangerouslySetInnerHTML`** unless absolutely necessary**Never use `eval()`** or assign directly to `document.cookie`**Validate and sanitize** all user inputPerformance
**Avoid spread syntax in accumulators** within loops**Use top-level regex literals** instead of creating them in loops**Prefer specific imports** over namespace imports (`import *`)**Avoid barrel files** (index files that re-export everything)**Use framework image components** (e.g., Next.js `<Image>`) instead of `<img>` tagsFramework-Specific Guidance
**Next.js:**
Use `<Image>` component from `next/image` for imagesUse `next/head` or App Router metadata API for `<head>` elementsUse Server Components for async data fetching (not async Client Components)**React 19+:**
Use `ref` as a prop instead of `React.forwardRef`**Solid/Svelte/Vue/Qwik:**
Use `class` and `for` attributes (not `className` or `htmlFor`)Testing Standards
When writing tests:
**Write assertions inside `it()` or `test()` blocks****Avoid done callbacks** in async tests — use `async/await` instead**Don't commit `.only` or `.skip`** in test suites**Keep test suites reasonably flat** — avoid excessive `describe` nestingWhat to Focus On (Beyond Biome)
Biome automatically catches most formatting and linting issues. Focus your code reviews on:
1. **Business logic correctness** — Biome can't validate algorithms
2. **Meaningful naming** — Use descriptive function, variable, and type names
3. **Architecture decisions** — Component structure, data flow, API design
4. **Edge cases** — Handle boundary conditions and error states
5. **User experience** — Accessibility, performance, usability
6. **Documentation** — Add comments for complex logic (prefer self-documenting code)
Implementation Workflow
When reviewing or writing code:
1. **Apply standards proactively** as you write code
2. **Before committing**, run `npx ultracite fix` to auto-fix issues
3. **Review Biome's output** and address any unfixable warnings
4. **Focus manual review** on logic, naming, architecture, and UX (areas Biome can't check)
Examples
Good: Explicit types and early returns
```typescript
function calculateDiscount(price: number, couponCode: string | null): number {
if (price <= 0) return 0;
if (!couponCode) return price;
const DISCOUNT_RATE = 0.1;
return price * (1 - DISCOUNT_RATE);
}
```
Good: Accessible React component
```tsx
function SearchInput({ onSearch }: { onSearch: (query: string) => void }) {
const [query, setQuery] = useState("");
return (
<label htmlFor="search-input">
Search:
<input
id="search-input"
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
onKeyDown={(e) => e.key === "Enter" && onSearch(query)}
/>
</label>
);
}
```
Bad: Magic numbers, missing accessibility
```tsx
// ❌ Magic number, no label, missing keyboard handler
function SearchInput({ onSearch }) {
const [query, setQuery] = useState("");
return (
<div onClick={() => query.length > 3 && onSearch(query)}>
<input value={query} onChange={(e) => setQuery(e.target.value)} />
</div>
);
}
```
Constraints
**Auto-run `ultracite fix`** before suggesting manual fixes for formatting issues**Prioritize accessibility** in all React component suggestions**Always validate** that hooks are called at the top level and have correct dependencies**Prefer self-documenting code** over comments unless logic is inherently complex