Write React Code
Use this skill whenever React code is written or changed. Apply these conventions to new React code and to lines
touched by the task. Preserve unrelated code and follow an explicit user instruction when it conflicts with this
skill.
General Rules
- Keep React, JSX, and SCSS under
src/.
- Keep every line at or under 120 characters, including Markdown changed as part of the task.
- Do not introduce unused variables or unrelated formatting churn.
- Use 2 spaces for indentation and never use tabs in JavaScript, JSX, or SCSS.
- Use single quotes for JavaScript strings and terminate JavaScript statements with semicolons.
- Inspect nearby files before adding a new pattern. Reuse established shared components, SCSS modules, and mixins
when they fit the requested behavior.
Components And Files
- Put each React component in its own file.
- Declare function components as named exported arrow functions. Do not default-export function components.
- Use parentheses around destructured props and no spaces inside their braces.
- Put one blank line between imports and the component declaration.
- Allow an implicit return only for very small components such as route wrappers.
- Give feature or page components a root element with a kebab-case
id.
- Give small reusable components a root element with a kebab-case class.
- If local styles are needed, create an adjacent, matching
Foo.scss and import it from Foo.js.
- Do not create empty SCSS placeholders or use inline styles when adjacent or shared SCSS is appropriate.
- A JavaScript file whose primary purpose is a class must declare
class Foo and end with export default Foo;.
import React from 'react';
import './Foo.scss';
export const Foo = ({message}) => {
return (
<div id="foo">
{message}
</div>
);
};
Imports
Order imports without blank lines between groups:
- React.
- Router.
- Third-party packages.
- Project modules.
- Adjacent styles.
- Do not put spaces inside named import braces.
- Import router primitives such as
Routes, Route, Navigate, and hooks from react-router.
- Import DOM-specific components such as
Link from react-router-dom.
import React, {useEffect, useState} from 'react';
import {Route, Routes, useParams} from 'react-router';
import {Link} from 'react-router-dom';
import {LoadingScreen} from '../global/components/LoadingScreen';
import './Customer.scss';
Component Body Order
Keep component bodies in this order:
- Router hooks.
- Context hooks.
- State hooks.
- Ref hooks.
- Derived constants used by hooks or rendering.
- Effects, with no-dependency effects before dependency-driven effects.
- Helpers and event handlers.
- Early returns.
- Main JSX.
- Keep hooks at the top and dependency arrays explicit.
- Separate effects and functions with blank lines.
- Define state-dependent helpers and handlers as
const arrow functions inside the component.
- Pass a named handler to JSX when no arguments need binding.
- Use an inline arrow only to bind arguments or perform a small direct state update.
- Do not extract a one-use expression solely to make it indirect. Extract reused or materially clearer logic.
JavaScript Layout
- Put a space before
{ in functions and control flow and after control-flow keywords.
- Put spaces around binary operators and around
= in default parameters.
- Use trailing commas in multiline objects and arrays.
- Keep short object literals inline with spaces inside their braces.
- Put multiline object properties and array items one per line.
- Use comments sparingly to explain intent, side effects, or non-obvious behavior.
const loadData = (marker = null) => {
if (marker) {
request.marker = marker;
}
};
const crumbs = [
{ text: 'Customers', path: '/customers' },
];
JSX Layout
- Parenthesize JSX only when it spans multiple lines.
- Keep a readable simple element on one line.
- For a complex element, put one prop per line and the closing
> on its own line.
- Self-close elements without children.
- Use anonymous fragments unless the fragment needs a
key; use React.Fragment when it does.
- Do not extract render variables used once unless that materially improves readability.
For larger conditional sections, put the JSX braces on their own lines and use ternaries that return null.
Nested ternaries are acceptable only while readable. In multiline ternaries, place ? after the condition and :
after the complete truthy branch.
{
hasAccess ?
<FeaturePanel /> :
null
}
SCSS
- Scope page and feature styles under the component's root
id.
- Scope reusable component styles under the component's root class.
- Use kebab-case selectors and avoid BEM unless the local file already establishes it.
- Use simple state classes such as
.active, .danger, .disabled, and .invalid where appropriate.
- Use Sass
@use, place all @use statements first, and leave one blank line after them. Do not use @import.
- Put a space before
{, close braces on their own line, and separate sibling blocks with one blank line.
- Nest enough to preserve component scope, but avoid unnecessary depth.
- Nest pseudo-classes, state modifiers, and component-specific media queries under the selector they affect.
- Loosely order properties from structure and positioning, through size and spacing, to visual and type effects.
- Prefer established SCSS variables and mixins over hard-coded application colors or duplicated patterns.
- Put third-party overrides in the established overrides file rather than a component file.
- Do not treat an application's palette as an organization-wide brand palette.
- Comment only unusual browser behavior, third-party overrides, or non-obvious groupings.
@use '../global/mixins/colors';
#customer {
display: flex;
width: 100%;
border: 1px solid colors.$border-color;
.actions {
display: flex;
gap: 0.5rem;
}
@media (max-width: 600px) {
.actions {
flex-direction: column;
}
}
}
Verification
- Run the narrowest relevant formatter, linter, and tests available to the changed code.
- Recheck import order, export shape, hook order, root selector matching, indentation, and the 120-character limit.
- Report checks that could not be run; do not claim unperformed verification.
1---2name: write-react-code3description: Use whenever a task writes or modifies React code, including JSX or TSX components, hooks, React tests, and React code snippets. Do not use for non-React JavaScript or standalone SCSS work.4---56# Write React Code78Use this skill whenever React code is written or changed. Apply these conventions to new React code and to lines9touched by the task. Preserve unrelated code and follow an explicit user instruction when it conflicts with this10skill.1112## General Rules1314- Keep React, JSX, and SCSS under `src/`.15- Keep every line at or under 120 characters, including Markdown changed as part of the task.16- Do not introduce unused variables or unrelated formatting churn.17- Use 2 spaces for indentation and never use tabs in JavaScript, JSX, or SCSS.18- Use single quotes for JavaScript strings and terminate JavaScript statements with semicolons.19- Inspect nearby files before adding a new pattern. Reuse established shared components, SCSS modules, and mixins20 when they fit the requested behavior.2122## Components And Files2324- Put each React component in its own file.25- Declare function components as named exported arrow functions. Do not default-export function components.26- Use parentheses around destructured props and no spaces inside their braces.27- Put one blank line between imports and the component declaration.28- Allow an implicit return only for very small components such as route wrappers.29- Give feature or page components a root element with a kebab-case `id`.30- Give small reusable components a root element with a kebab-case class.31- If local styles are needed, create an adjacent, matching `Foo.scss` and import it from `Foo.js`.32- Do not create empty SCSS placeholders or use inline styles when adjacent or shared SCSS is appropriate.33- A JavaScript file whose primary purpose is a class must declare `class Foo` and end with `export default Foo;`.3435```jsx36import React from 'react';37import './Foo.scss';3839export const Foo = ({message}) => {40 return (41 <div id="foo">42 {message}43 </div>44 );45};46```4748## Imports4950Order imports without blank lines between groups:51521. React.532. Router.543. Third-party packages.554. Project modules.565. Adjacent styles.5758- Do not put spaces inside named import braces.59- Import router primitives such as `Routes`, `Route`, `Navigate`, and hooks from `react-router`.60- Import DOM-specific components such as `Link` from `react-router-dom`.6162```js63import React, {useEffect, useState} from 'react';64import {Route, Routes, useParams} from 'react-router';65import {Link} from 'react-router-dom';66import {LoadingScreen} from '../global/components/LoadingScreen';67import './Customer.scss';68```6970## Component Body Order7172Keep component bodies in this order:73741. Router hooks.752. Context hooks.763. State hooks.774. Ref hooks.785. Derived constants used by hooks or rendering.796. Effects, with no-dependency effects before dependency-driven effects.807. Helpers and event handlers.818. Early returns.829. Main JSX.8384- Keep hooks at the top and dependency arrays explicit.85- Separate effects and functions with blank lines.86- Define state-dependent helpers and handlers as `const` arrow functions inside the component.87- Pass a named handler to JSX when no arguments need binding.88- Use an inline arrow only to bind arguments or perform a small direct state update.89- Do not extract a one-use expression solely to make it indirect. Extract reused or materially clearer logic.9091## JavaScript Layout9293- Put a space before `{` in functions and control flow and after control-flow keywords.94- Put spaces around binary operators and around `=` in default parameters.95- Use trailing commas in multiline objects and arrays.96- Keep short object literals inline with spaces inside their braces.97- Put multiline object properties and array items one per line.98- Use comments sparingly to explain intent, side effects, or non-obvious behavior.99100```js101const loadData = (marker = null) => {102 if (marker) {103 request.marker = marker;104 }105};106107const crumbs = [108 { text: 'Customers', path: '/customers' },109];110```111112## JSX Layout113114- Parenthesize JSX only when it spans multiple lines.115- Keep a readable simple element on one line.116- For a complex element, put one prop per line and the closing `>` on its own line.117- Self-close elements without children.118- Use anonymous fragments unless the fragment needs a `key`; use `React.Fragment` when it does.119- Do not extract render variables used once unless that materially improves readability.120121For larger conditional sections, put the JSX braces on their own lines and use ternaries that return `null`.122Nested ternaries are acceptable only while readable. In multiline ternaries, place `?` after the condition and `:`123after the complete truthy branch.124125```jsx126{127 hasAccess ?128 <FeaturePanel /> :129 null130}131```132133## SCSS134135- Scope page and feature styles under the component's root `id`.136- Scope reusable component styles under the component's root class.137- Use kebab-case selectors and avoid BEM unless the local file already establishes it.138- Use simple state classes such as `.active`, `.danger`, `.disabled`, and `.invalid` where appropriate.139- Use Sass `@use`, place all `@use` statements first, and leave one blank line after them. Do not use `@import`.140- Put a space before `{`, close braces on their own line, and separate sibling blocks with one blank line.141- Nest enough to preserve component scope, but avoid unnecessary depth.142- Nest pseudo-classes, state modifiers, and component-specific media queries under the selector they affect.143- Loosely order properties from structure and positioning, through size and spacing, to visual and type effects.144- Prefer established SCSS variables and mixins over hard-coded application colors or duplicated patterns.145- Put third-party overrides in the established overrides file rather than a component file.146- Do not treat an application's palette as an organization-wide brand palette.147- Comment only unusual browser behavior, third-party overrides, or non-obvious groupings.148149```scss150@use '../global/mixins/colors';151152#customer {153 display: flex;154 width: 100%;155 border: 1px solid colors.$border-color;156157 .actions {158 display: flex;159 gap: 0.5rem;160 }161162 @media (max-width: 600px) {163 .actions {164 flex-direction: column;165 }166 }167}168```169170## Verification171172- Run the narrowest relevant formatter, linter, and tests available to the changed code.173- Recheck import order, export shape, hook order, root selector matching, indentation, and the 120-character limit.174- Report checks that could not be run; do not claim unperformed verification.