Ultracite Code Standards
Enforce strict code quality standards using Ultracite, a zero-config Biome preset with automated formatting and linting.
Overview
Ultracite provides Rust-based, extremely fast linting and formatting via Biome. Most issues are automatically fixable. This skill ensures code is accessible, performant, type-safe, and maintainable.
Commands
**Format code**: `npx ultracite fix`**Check for issues**: `npx ultracite check`**Diagnose setup**: `npx ultracite doctor`Core Principles
Focus on clarity and explicit intent over brevity. Write code that is accessible, performant, type-safe, and maintainable.
Type Safety & Explicitness
Use explicit types for function parameters and return values when they enhance clarityPrefer `unknown` over `any` when the type is genuinely unknownUse const assertions (`as const`) for immutable values and literal typesLeverage TypeScript's type narrowing instead of type assertionsUse meaningful variable names instead of magic numbers - extract constants with descriptive namesModern JavaScript/TypeScript
Use arrow functions for callbacks and short functionsPrefer `for...of` loops over `.forEach()` and indexed `for` loopsUse optional chaining (`?.`) and nullish coalescing (`??`) for safer property accessPrefer template literals over string concatenationUse destructuring for object and array assignmentsUse `const` by default, `let` only when reassignment is needed, never `var`Async & Promises
Always `await` promises in async functions - use the return valueUse `async/await` syntax instead of promise chains for better readabilityHandle errors appropriately in async code with try-catch blocksDon't use async functions as Promise executorsReact & JSX
Use function components over class componentsCall hooks at the top level only, never conditionallySpecify all dependencies in hook dependency arrays correctlyUse the `key` prop for elements in iterables (prefer unique IDs over array indices)Nest children between opening and closing tags instead of passing as propsDon't define components inside other componentsUse semantic HTML and ARIA attributes for accessibility: - Provide meaningful alt text for images
- Use proper heading hierarchy
- Add labels for form inputs
- Include keyboard event handlers alongside mouse events
- Use semantic elements (`<button>`, `<nav>`, etc.) instead of divs with roles
Error Handling & Debugging
Remove `console.log`, `debugger`, and `alert` statements from production codeThrow `Error` objects with descriptive messages, not strings or other valuesUse `try-catch` blocks meaningfully - don't catch errors just to rethrow themPrefer early returns over nested conditionals for error casesCode Organization
Keep functions focused and under reasonable cognitive complexity limitsExtract complex conditions into well-named boolean variablesUse early returns to reduce nestingPrefer simple conditionals over nested ternary operatorsGroup related code together and separate concernsSecurity
Add `rel="noopener"` when using `target="_blank"` on linksAvoid `dangerouslySetInnerHTML` unless absolutely necessaryDon't use `eval()` or assign directly to `document.cookie`Validate and sanitize user inputPerformance
Avoid spread syntax in accumulators within loopsUse top-level regex literals instead of creating them in loopsPrefer specific imports over namespace importsAvoid barrel files (index files that re-export everything)Use proper image components (e.g., Next.js `<Image>`) over `<img>` tagsFramework-Specific Guidance
**Next.js:**
Use Next.js `<Image>` component for imagesUse `next/head` or App Router metadata API for head elementsUse Server Components for async data fetching instead of 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
Write assertions inside `it()` or `test()` blocksAvoid done callbacks in async tests - use async/await insteadDon't use `.only` or `.skip` in committed codeKeep test suites reasonably flat - avoid excessive `describe` nestingWhen Biome Can't Help
Biome's linter catches most issues automatically. Focus your attention on:
1. **Business logic correctness** - Biome can't validate your algorithms
2. **Meaningful naming** - Use descriptive names for functions, variables, and types
3. **Architecture decisions** - Component structure, data flow, and API design
4. **Edge cases** - Handle boundary conditions and error states
5. **User experience** - Accessibility, performance, and usability considerations
6. **Documentation** - Add comments for complex logic, but prefer self-documenting code
Workflow
1. Run `npx ultracite fix` before committing to automatically fix formatting and common issues
2. Run `npx ultracite check` to identify remaining problems
3. Run `npx ultracite doctor` if you encounter setup issues
4. Review code for business logic, naming, architecture, edge cases, and UX considerations that Biome cannot validate
File Scope
Applies to: `**/*.{ts,tsx,js,jsx}`