Skip to content

Commit ff152a8

Browse files
committed
ultracite rules
1 parent 331b32b commit ff152a8

File tree

3 files changed

+721
-0
lines changed

3 files changed

+721
-0
lines changed

.cursor/rules/ultracite.mdc

Lines changed: 333 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,333 @@
1+
---
2+
description: Ultracite Rules - AI-Ready Formatter and Linter
3+
globs: "**/*.{ts,tsx,js,jsx}"
4+
alwaysApply: true
5+
---
6+
7+
# Project Context
8+
Ultracite enforces strict type safety, accessibility standards, and consistent code quality for JavaScript/TypeScript projects using Biome's lightning-fast formatter and linter.
9+
10+
## Key Principles
11+
- Zero configuration required
12+
- Subsecond performance
13+
- Maximum type safety
14+
- AI-friendly code generation
15+
16+
## Before Writing Code
17+
1. Analyze existing patterns in the codebase
18+
2. Consider edge cases and error scenarios
19+
3. Follow the rules below strictly
20+
4. Validate accessibility requirements
21+
22+
## Rules
23+
24+
### Accessibility (a11y)
25+
- Don't use `accessKey` attribute on any HTML element.
26+
- Don't set `aria-hidden="true"` on focusable elements.
27+
- Don't add ARIA roles, states, and properties to elements that don't support them.
28+
- Don't use distracting elements like `<marquee>` or `<blink>`.
29+
- Only use the `scope` prop on `<th>` elements.
30+
- Don't assign non-interactive ARIA roles to interactive HTML elements.
31+
- Make sure label elements have text content and are associated with an input.
32+
- Don't assign interactive ARIA roles to non-interactive HTML elements.
33+
- Don't assign `tabIndex` to non-interactive HTML elements.
34+
- Don't use positive integers for `tabIndex` property.
35+
- Don't include "image", "picture", or "photo" in img alt prop.
36+
- Don't use explicit role property that's the same as the implicit/default role.
37+
- Make static elements with click handlers use a valid role attribute.
38+
- Always include a `title` element for SVG elements.
39+
- Give all elements requiring alt text meaningful information for screen readers.
40+
- Make sure anchors have content that's accessible to screen readers.
41+
- Assign `tabIndex` to non-interactive HTML elements with `aria-activedescendant`.
42+
- Include all required ARIA attributes for elements with ARIA roles.
43+
- Make sure ARIA properties are valid for the element's supported roles.
44+
- Always include a `type` attribute for button elements.
45+
- Make elements with interactive roles and handlers focusable.
46+
- Give heading elements content that's accessible to screen readers (not hidden with `aria-hidden`).
47+
- Always include a `lang` attribute on the html element.
48+
- Always include a `title` attribute for iframe elements.
49+
- Accompany `onClick` with at least one of: `onKeyUp`, `onKeyDown`, or `onKeyPress`.
50+
- Accompany `onMouseOver`/`onMouseOut` with `onFocus`/`onBlur`.
51+
- Include caption tracks for audio and video elements.
52+
- Use semantic elements instead of role attributes in JSX.
53+
- Make sure all anchors are valid and navigable.
54+
- Ensure all ARIA properties (`aria-*`) are valid.
55+
- Use valid, non-abstract ARIA roles for elements with ARIA roles.
56+
- Use valid ARIA state and property values.
57+
- Use valid values for the `autocomplete` attribute on input elements.
58+
- Use correct ISO language/country codes for the `lang` attribute.
59+
60+
### Code Complexity and Quality
61+
- Don't use consecutive spaces in regular expression literals.
62+
- Don't use the `arguments` object.
63+
- Don't use primitive type aliases or misleading types.
64+
- Don't use the comma operator.
65+
- Don't use empty type parameters in type aliases and interfaces.
66+
- Don't write functions that exceed a given Cognitive Complexity score.
67+
- Don't nest describe() blocks too deeply in test files.
68+
- Don't use unnecessary boolean casts.
69+
- Don't use unnecessary callbacks with flatMap.
70+
- Use for...of statements instead of Array.forEach.
71+
- Don't create classes that only have static members (like a static namespace).
72+
- Don't use this and super in static contexts.
73+
- Don't use unnecessary catch clauses.
74+
- Don't use unnecessary constructors.
75+
- Don't use unnecessary continue statements.
76+
- Don't export empty modules that don't change anything.
77+
- Don't use unnecessary escape sequences in regular expression literals.
78+
- Don't use unnecessary fragments.
79+
- Don't use unnecessary labels.
80+
- Don't use unnecessary nested block statements.
81+
- Don't rename imports, exports, and destructured assignments to the same name.
82+
- Don't use unnecessary string or template literal concatenation.
83+
- Don't use String.raw in template literals when there are no escape sequences.
84+
- Don't use useless case statements in switch statements.
85+
- Don't use ternary operators when simpler alternatives exist.
86+
- Don't use useless `this` aliasing.
87+
- Don't use any or unknown as type constraints.
88+
- Don't initialize variables to undefined.
89+
- Don't use the void operators (they're not familiar).
90+
- Use arrow functions instead of function expressions.
91+
- Use Date.now() to get milliseconds since the Unix Epoch.
92+
- Use .flatMap() instead of map().flat() when possible.
93+
- Use literal property access instead of computed property access.
94+
- Don't use parseInt() or Number.parseInt() when binary, octal, or hexadecimal literals work.
95+
- Use concise optional chaining instead of chained logical expressions.
96+
- Use regular expression literals instead of the RegExp constructor when possible.
97+
- Don't use number literal object member names that aren't base 10 or use underscore separators.
98+
- Remove redundant terms from logical expressions.
99+
- Use while loops instead of for loops when you don't need initializer and update expressions.
100+
- Don't pass children as props.
101+
- Don't reassign const variables.
102+
- Don't use constant expressions in conditions.
103+
- Don't use `Math.min` and `Math.max` to clamp values when the result is constant.
104+
- Don't return a value from a constructor.
105+
- Don't use empty character classes in regular expression literals.
106+
- Don't use empty destructuring patterns.
107+
- Don't call global object properties as functions.
108+
- Don't declare functions and vars that are accessible outside their block.
109+
- Make sure builtins are correctly instantiated.
110+
- Don't use super() incorrectly inside classes. Also check that super() is called in classes that extend other constructors.
111+
- Don't use variables and function parameters before they're declared.
112+
- Don't use 8 and 9 escape sequences in string literals.
113+
- Don't use literal numbers that lose precision.
114+
115+
### React and JSX Best Practices
116+
- Don't use the return value of React.render.
117+
- Make sure all dependencies are correctly specified in React hooks.
118+
- Make sure all React hooks are called from the top level of component functions.
119+
- Don't forget key props in iterators and collection literals.
120+
- Don't destructure props inside JSX components in Solid projects.
121+
- Don't define React components inside other components.
122+
- Don't use event handlers on non-interactive elements.
123+
- Don't assign to React component props.
124+
- Don't use both `children` and `dangerouslySetInnerHTML` props on the same element.
125+
- Don't use dangerous JSX props.
126+
- Don't use Array index in keys.
127+
- Don't insert comments as text nodes.
128+
- Don't assign JSX properties multiple times.
129+
- Don't add extra closing tags for components without children.
130+
- Use `<>...</>` instead of `<Fragment>...</Fragment>`.
131+
- Watch out for possible "wrong" semicolons inside JSX elements.
132+
133+
### Correctness and Safety
134+
- Don't assign a value to itself.
135+
- Don't return a value from a setter.
136+
- Don't compare expressions that modify string case with non-compliant values.
137+
- Don't use lexical declarations in switch clauses.
138+
- Don't use variables that haven't been declared in the document.
139+
- Don't write unreachable code.
140+
- Make sure super() is called exactly once on every code path in a class constructor before this is accessed if the class has a superclass.
141+
- Don't use control flow statements in finally blocks.
142+
- Don't use optional chaining where undefined values aren't allowed.
143+
- Don't have unused function parameters.
144+
- Don't have unused imports.
145+
- Don't have unused labels.
146+
- Don't have unused private class members.
147+
- Don't have unused variables.
148+
- Make sure void (self-closing) elements don't have children.
149+
- Don't return a value from a function with the return type 'void'
150+
- Use isNaN() when checking for NaN.
151+
- Make sure "for" loop update clauses move the counter in the right direction.
152+
- Make sure typeof expressions are compared to valid values.
153+
- Make sure generator functions contain yield.
154+
- Don't use await inside loops.
155+
- Don't use bitwise operators.
156+
- Don't use expressions where the operation doesn't change the value.
157+
- Make sure Promise-like statements are handled appropriately.
158+
- Don't use __dirname and __filename in the global scope.
159+
- Prevent import cycles.
160+
- Don't use configured elements.
161+
- Don't hardcode sensitive data like API keys and tokens.
162+
- Don't let variable declarations shadow variables from outer scopes.
163+
- Don't use the TypeScript directive @ts-ignore.
164+
- Prevent duplicate polyfills from Polyfill.io.
165+
- Don't use useless backreferences in regular expressions that always match empty strings.
166+
- Don't use unnecessary escapes in string literals.
167+
- Don't use useless undefined.
168+
- Make sure getters and setters for the same property are next to each other in class and object definitions.
169+
- Make sure object literals are declared consistently (defaults to explicit definitions).
170+
- Use static Response methods instead of new Response() constructor when possible.
171+
- Make sure switch-case statements are exhaustive.
172+
- Make sure the `preconnect` attribute is used when using Google Fonts.
173+
- Use `Array#{indexOf,lastIndexOf}()` instead of `Array#{findIndex,findLastIndex}()` when looking for the index of an item.
174+
- Make sure iterable callbacks return consistent values.
175+
- Use `with { type: "json" }` for JSON module imports.
176+
- Use numeric separators in numeric literals.
177+
- Use object spread instead of `Object.assign()` when constructing new objects.
178+
- Always use the radix argument when using `parseInt()`.
179+
- Make sure JSDoc comment lines start with a single asterisk, except for the first one.
180+
- Include a description parameter for `Symbol()`.
181+
- Don't use spread (`...`) syntax on accumulators.
182+
- Don't use the `delete` operator.
183+
- Don't access namespace imports dynamically.
184+
- Don't use namespace imports.
185+
- Declare regex literals at the top level.
186+
- Don't use `target="_blank"` without `rel="noopener"`.
187+
188+
### TypeScript Best Practices
189+
- Don't use TypeScript enums.
190+
- Don't export imported variables.
191+
- Don't add type annotations to variables, parameters, and class properties that are initialized with literal expressions.
192+
- Don't use TypeScript namespaces.
193+
- Don't use non-null assertions with the `!` postfix operator.
194+
- Don't use parameter properties in class constructors.
195+
- Don't use user-defined types.
196+
- Use `as const` instead of literal types and type annotations.
197+
- Use either `T[]` or `Array<T>` consistently.
198+
- Initialize each enum member value explicitly.
199+
- Use `export type` for types.
200+
- Use `import type` for types.
201+
- Make sure all enum members are literal values.
202+
- Don't use TypeScript const enum.
203+
- Don't declare empty interfaces.
204+
- Don't let variables evolve into any type through reassignments.
205+
- Don't use the any type.
206+
- Don't misuse the non-null assertion operator (!) in TypeScript files.
207+
- Don't use implicit any type on variable declarations.
208+
- Don't merge interfaces and classes unsafely.
209+
- Don't use overload signatures that aren't next to each other.
210+
- Use the namespace keyword instead of the module keyword to declare TypeScript namespaces.
211+
212+
### Style and Consistency
213+
- Don't use global `eval()`.
214+
- Don't use callbacks in asynchronous tests and hooks.
215+
- Don't use negation in `if` statements that have `else` clauses.
216+
- Don't use nested ternary expressions.
217+
- Don't reassign function parameters.
218+
- This rule lets you specify global variable names you don't want to use in your application.
219+
- Don't use specified modules when loaded by import or require.
220+
- Don't use constants whose value is the upper-case version of their name.
221+
- Use `String.slice()` instead of `String.substr()` and `String.substring()`.
222+
- Don't use template literals if you don't need interpolation or special-character handling.
223+
- Don't use `else` blocks when the `if` block breaks early.
224+
- Don't use yoda expressions.
225+
- Don't use Array constructors.
226+
- Use `at()` instead of integer index access.
227+
- Follow curly brace conventions.
228+
- Use `else if` instead of nested `if` statements in `else` clauses.
229+
- Use single `if` statements instead of nested `if` clauses.
230+
- Use `new` for all builtins except `String`, `Number`, and `Boolean`.
231+
- Use consistent accessibility modifiers on class properties and methods.
232+
- Use `const` declarations for variables that are only assigned once.
233+
- Put default function parameters and optional function parameters last.
234+
- Include a `default` clause in switch statements.
235+
- Use the `**` operator instead of `Math.pow`.
236+
- Use `for-of` loops when you need the index to extract an item from the iterated array.
237+
- Use `node:assert/strict` over `node:assert`.
238+
- Use the `node:` protocol for Node.js builtin modules.
239+
- Use Number properties instead of global ones.
240+
- Use assignment operator shorthand where possible.
241+
- Use function types instead of object types with call signatures.
242+
- Use template literals over string concatenation.
243+
- Use `new` when throwing an error.
244+
- Don't throw non-Error values.
245+
- Use `String.trimStart()` and `String.trimEnd()` over `String.trimLeft()` and `String.trimRight()`.
246+
- Use standard constants instead of approximated literals.
247+
- Don't assign values in expressions.
248+
- Don't use async functions as Promise executors.
249+
- Don't reassign exceptions in catch clauses.
250+
- Don't reassign class members.
251+
- Don't compare against -0.
252+
- Don't use labeled statements that aren't loops.
253+
- Don't use void type outside of generic or return types.
254+
- Don't use console.
255+
- Don't use control characters and escape sequences that match control characters in regular expression literals.
256+
- Don't use debugger.
257+
- Don't assign directly to document.cookie.
258+
- Use `===` and `!==`.
259+
- Don't use duplicate case labels.
260+
- Don't use duplicate class members.
261+
- Don't use duplicate conditions in if-else-if chains.
262+
- Don't use two keys with the same name inside objects.
263+
- Don't use duplicate function parameter names.
264+
- Don't have duplicate hooks in describe blocks.
265+
- Don't use empty block statements and static blocks.
266+
- Don't let switch clauses fall through.
267+
- Don't reassign function declarations.
268+
- Don't allow assignments to native objects and read-only global variables.
269+
- Use Number.isFinite instead of global isFinite.
270+
- Use Number.isNaN instead of global isNaN.
271+
- Don't assign to imported bindings.
272+
- Don't use irregular whitespace characters.
273+
- Don't use labels that share a name with a variable.
274+
- Don't use characters made with multiple code points in character class syntax.
275+
- Make sure to use new and constructor properly.
276+
- Don't use shorthand assign when the variable appears on both sides.
277+
- Don't use octal escape sequences in string literals.
278+
- Don't use Object.prototype builtins directly.
279+
- Don't redeclare variables, functions, classes, and types in the same scope.
280+
- Don't have redundant "use strict".
281+
- Don't compare things where both sides are exactly the same.
282+
- Don't let identifiers shadow restricted names.
283+
- Don't use sparse arrays (arrays with holes).
284+
- Don't use template literal placeholder syntax in regular strings.
285+
- Don't use the then property.
286+
- Don't use unsafe negation.
287+
- Don't use var.
288+
- Don't use with statements in non-strict contexts.
289+
- Make sure async functions actually use await.
290+
- Make sure default clauses in switch statements come last.
291+
- Make sure to pass a message value when creating a built-in error.
292+
- Make sure get methods always return a value.
293+
- Use a recommended display strategy with Google Fonts.
294+
- Make sure for-in loops include an if statement.
295+
- Use Array.isArray() instead of instanceof Array.
296+
- Make sure to use the digits argument with Number#toFixed().
297+
- Make sure to use the "use strict" directive in script files.
298+
299+
### Next.js Specific Rules
300+
- Don't use `<img>` elements in Next.js projects.
301+
- Don't use `<head>` elements in Next.js projects.
302+
- Don't import next/document outside of pages/_document.jsx in Next.js projects.
303+
- Don't use the next/head module in pages/_document.js on Next.js projects.
304+
305+
### Testing Best Practices
306+
- Don't use export or module.exports in test files.
307+
- Don't use focused tests.
308+
- Make sure the assertion function, like expect, is placed inside an it() function call.
309+
- Don't use disabled tests.
310+
311+
## Common Tasks
312+
- `npx ultracite init` - Initialize Ultracite in your project
313+
- `npx ultracite fix` - Format and fix code automatically
314+
- `npx ultracite check` - Check for issues without fixing
315+
316+
## Example: Error Handling
317+
```typescript
318+
// ✅ Good: Comprehensive error handling
319+
try {
320+
const result = await fetchData();
321+
return { success: true, data: result };
322+
} catch (error) {
323+
console.error('API call failed:', error);
324+
return { success: false, error: error.message };
325+
}
326+
327+
// ❌ Bad: Swallowing errors
328+
try {
329+
return await fetchData();
330+
} catch (e) {
331+
console.log(e);
332+
}
333+
```

0 commit comments

Comments
 (0)