Strict TypeScript/React code quality standards enforced through Biome-powered linting and formatting
This skill has safety concerns that you should review before use. Some patterns were detected that may pose a risk.Safety score: 75/100.
KillerSkills scans all public content for safety. Use caution before installing or executing flagged content.
Enforce strict code quality standards using Ultracite, a zero-config Biome preset for TypeScript and React projects. This skill guides you to write accessible, performant, type-safe, and maintainable code with automated formatting and linting.
Before implementing any code changes, familiarize yourself with these commands:
Biome provides Rust-based linting and formatting with automatic fixes for most issues.
1. **Use explicit types** for function parameters and return values when they enhance clarity
2. **Prefer `unknown` over `any`** when the type is genuinely unknown
3. **Use const assertions** (`as const`) for immutable values and literal types
4. **Leverage TypeScript's type narrowing** instead of type assertions
5. **Extract constants** with descriptive names instead of using magic numbers
```typescript
// Good
const MAX_RETRY_ATTEMPTS = 3;
function processUser(user: User): Promise<UserProfile> { }
// Avoid
function processUser(user: any): any { }
const limit = 3; // What does 3 represent?
```
1. **Use arrow functions** for callbacks and short functions
2. **Prefer `for...of` loops** over `.forEach()` and indexed `for` loops
3. **Use optional chaining** (`?.`) and nullish coalescing (`??`)
4. **Prefer template literals** over string concatenation
5. **Use destructuring** for object and array assignments
6. **Use `const` by default**, `let` only when reassignment is needed, never `var`
```typescript
// Good
for (const item of items) {
const name = item?.name ?? 'Unknown';
console.log(`User: ${name}`);
}
// Avoid
items.forEach(function(item, i) {
var name = item.name ? item.name : 'Unknown';
console.log('User: ' + name);
});
```
1. **Always `await` promises** in async functions - don't forget to use the return value
2. **Use `async/await` syntax** instead of promise chains
3. **Handle errors** with try-catch blocks
4. **Don't use async functions as Promise executors**
```typescript
// Good
async function fetchUser(id: string): Promise<User> {
try {
const response = await fetch(`/api/users/${id}`);
return await response.json();
} catch (error) {
throw new Error(`Failed to fetch user: ${error.message}`);
}
}
// Avoid
function fetchUser(id: string): Promise<User> {
return fetch(`/api/users/${id}`)
.then(response => response.json())
.catch(error => { throw error; });
}
```
1. **Use function components** over class components
2. **Call hooks at the top level only**, never conditionally
3. **Specify all dependencies** in hook dependency arrays correctly
4. **Use the `key` prop** for elements in iterables (prefer unique IDs over array indices)
5. **Nest children** between opening and closing tags instead of passing as props
6. **Don't define components inside other components**
```typescript
// Good
function UserList({ users }: { users: User[] }) {
const [filter, setFilter] = useState('');
useEffect(() => {
// All dependencies listed
}, [filter]);
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
// Avoid
function UserList({ users }) {
if (loading) {
useEffect(() => { }); // Conditional hook call
}
return users.map((user, index) => (
<li key={index}>{user.name}</li> // Index as key
));
}
```
Use semantic HTML and ARIA attributes:
1. **Provide meaningful alt text** for images
2. **Use proper heading hierarchy** (h1 → h2 → h3)
3. **Add labels for form inputs**
4. **Include keyboard event handlers** alongside mouse events
5. **Use semantic elements** (`<button>`, `<nav>`, etc.) instead of divs with roles
```tsx
// Good
<button onClick={handleClick} onKeyDown={handleKeyDown}>
Submit
</button>
<img src={avatarUrl} alt={`${user.name}'s profile picture`} />
// Avoid
<div onClick={handleClick}>Submit</div>
<img src={avatarUrl} /> // Missing alt text
```
1. **Remove `console.log`, `debugger`, and `alert`** from production code
2. **Throw `Error` objects** with descriptive messages, not strings
3. **Use `try-catch` meaningfully** - don't catch just to rethrow
4. **Prefer early returns** over nested conditionals for error cases
```typescript
// Good
if (!user) {
throw new Error('User not found');
}
try {
await processUser(user);
} catch (error) {
logger.error('User processing failed', { error, userId: user.id });
throw error;
}
// Avoid
if (!user) {
throw 'User not found'; // Throwing string
}
try {
await processUser(user);
} catch (error) {
throw error; // Meaningless catch
}
```
1. **Keep functions focused** - under reasonable cognitive complexity limits
2. **Extract complex conditions** into well-named boolean variables
3. **Use early returns** to reduce nesting
4. **Prefer simple conditionals** over nested ternary operators
5. **Group related code** together and separate concerns
```typescript
// Good
const isEligibleForDiscount = user.isPremium && totalAmount > 100;
if (!isEligibleForDiscount) {
return calculateRegularPrice(totalAmount);
}
return calculateDiscountedPrice(totalAmount);
// Avoid
return user.isPremium && totalAmount > 100
? calculateDiscountedPrice(totalAmount)
: calculateRegularPrice(totalAmount);
```
1. **Add `rel="noopener"`** when using `target="_blank"` on links
2. **Avoid `dangerouslySetInnerHTML`** unless absolutely necessary
3. **Don't use `eval()`** or assign directly to `document.cookie`
4. **Validate and sanitize user input**
```tsx
// Good
<a href={externalUrl} target="_blank" rel="noopener noreferrer">
Visit external site
</a>
// Avoid
<a href={externalUrl} target="_blank">Visit</a>
```
1. **Avoid spread syntax in accumulators** within loops
2. **Use top-level regex literals** instead of creating them in loops
3. **Prefer specific imports** over namespace imports
4. **Avoid barrel files** (index files that re-export everything)
5. **Use proper image components** (e.g., Next.js `<Image>`) over `<img>` tags
```typescript
// Good
import { useState, useEffect } from 'react';
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
// Avoid
import * as React from 'react';
function validate(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); // Regex in function
}
```
1. **Use Next.js `<Image>` component** for images
2. **Use `next/head` or App Router metadata API** for head elements
3. **Use Server Components** for async data fetching instead of async Client Components
```tsx
// Good
import Image from 'next/image';
export default function Profile({ user }) {
return <Image src={user.avatar} alt={user.name} width={200} height={200} />;
}
// Avoid
export default function Profile({ user }) {
return <img src={user.avatar} alt={user.name} />;
}
```
1. **Write assertions inside `it()` or `test()` blocks**
2. **Avoid done callbacks** - use async/await instead
3. **Don't use `.only` or `.skip`** in committed code
4. **Keep test suites reasonably flat** - avoid excessive `describe` nesting
```typescript
// Good
test('should fetch user successfully', async () => {
const user = await fetchUser('123');
expect(user.name).toBe('John Doe');
});
// Avoid
test.only('should fetch user', (done) => {
fetchUser('123').then(user => {
expect(user.name).toBe('John Doe');
done();
});
});
```
Focus your manual review on:
1. **Business logic correctness** - Algorithms and data transformations
2. **Meaningful naming** - Descriptive function, variable, and type names
3. **Architecture decisions** - Component structure, data flow, API design
4. **Edge cases** - Boundary conditions and error states
5. **User experience** - Accessibility, performance, and usability
6. **Documentation** - Comments for complex logic (prefer self-documenting code)
Always run `npx ultracite fix` before committing to ensure code complies with all standards. Most formatting and common issues are automatically fixed by Biome.
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/ultracite-code-standards-big571/raw